home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume1 / rpc / part01 next >
Encoding:
Internet Message Format  |  1986-11-30  |  34.7 KB

  1. Date: Tue, 2 Apr 85 23:34:28 pst
  2. From: decvax!sun!pumpkinseed!blyon (Bob Lyon)
  3. Subject: Sun RPC part 1 of 10
  4.  
  5. mkdir profiled
  6. echo x - Makefile
  7. sed 's/^X//' >Makefile <<'!Funky!Stuff!'
  8. #
  9. #     Makefile    1.3    85/02/08
  10. #
  11. DESTDIR=
  12.  
  13. SRC=    auth_none.c auth_unix.c authunix_prot.c \
  14.     clnt_perror.c clnt_raw.c clnt_simple.c clnt_tcp.c clnt_udp.c \
  15.     pmap_clnt.c pmap_getmaps.c pmap_getport.c pmap_prot.c pmap_rmt.c \
  16.     rpc_prot.c \
  17.     svc.c svc_auth.c svc_auth_unix.c svc_raw.c svc_simple.c \
  18.     svc_tcp.c svc_udp.c xdr.c xdr_array.c xdr_float.c xdr_mem.c xdr_rec.c \
  19.     xdr_reference.c xdr_stdio.c
  20.  
  21. OBJ=    auth_none.o auth_unix.o authunix_prot.o clnt_perror.o clnt_raw.o\
  22.     clnt_simple.o clnt_tcp.o clnt_udp.o \
  23.     pmap_clnt.o pmap_getmaps.o pmap_getport.o pmap_prot.o pmap_rmt.o \
  24.     rpc_prot.o \
  25.     svc.o svc_auth.o svc_auth_unix.o svc_raw.o svc_simple.o \
  26.     svc_tcp.o svc_udp.o xdr.o xdr_array.o xdr_float.o xdr_mem.o xdr_rec.o \
  27.     xdr_reference.o xdr_stdio.o
  28. INC=    auth.h auth_unix.h clnt.h pmap_clnt.h\
  29.     pmap_prot.h rpc.h rpc_msg.h svc.h svc_auth.h types.h xdr.h
  30.  
  31. CFLAGS= -O
  32.  
  33. X.c.o:
  34.     ${CC} -p -c ${CFLAGS} $*.c
  35.     -ld -X -r $*.o
  36.     mv a.out profiled/$*.o
  37.     ${CC} ${CFLAGS} -c $*.c
  38.     -ld -x -r $*.o
  39.     mv a.out $*.o
  40.  
  41. all: rpclib portmap rpcinfo
  42.  
  43. portmap: portmap.o
  44.     cc $(CFLAGS) portmap.o rpclib -o portmap
  45.  
  46. rpcinfo: rpcinfo.o
  47.     cc $(CFLAGS) rpcinfo.o rpclib -o rpcinfo
  48.  
  49. rpclib rpclib_p: ${OBJ}
  50.     @echo "building profiled rpclib"
  51.     @cd profiled; ar cru ../rpclib_p ${OBJ}
  52.     @echo "building normal rpclib"
  53.     @ar cru rpclib ${OBJ}
  54.     ranlib rpclib
  55.  
  56. install:
  57.     -mkdir ${DESTDIR}/usr/include/rpc && \
  58.         chown bin ${DESTDIR}/usr/include/rpc && \
  59.         chmod 755 ${DESTDIR}/usr/include/rpc
  60.     -for i in *.h; do \
  61.         (install -c -m 644 $$i ${DESTDIR}/usr/include/rpc) done
  62.  
  63. tags: $(SRC) $(KSRC) $(INC)
  64.     ctags -tw $(SRC) $(KSRC) $(INC)
  65.  
  66. ref: tags
  67.     sed 's,    /.*,,' tags | \
  68.     awk ' { printf("%-26s%-16s%s\n", $$1, $$2, $$3) }' > ref
  69.  
  70. lint:
  71.     lint -bnuvx $(SRC)
  72.  
  73. print:
  74.     pr $(INC) $(SRC) $(KSRC) | lpr -Pvp
  75.  
  76. clean:
  77.     rm -f $(OBJ) librpc.a linted made profiled/*.o
  78.  
  79. depend:
  80.     @-grep '^#include' $(SRC) | grep -v '<' | grep -v '../' | \
  81.     sed 's/:[^"]*"\([^"]*\)".*/: \1/' | sed 's/\.[cs]:/.o:/' | \
  82.     awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \
  83.         else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \
  84.                else rec = rec " " $$2 } } \
  85.           END { print rec } ' >> makedep
  86.     @echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep
  87.     @echo '$$r makedep' >>eddep
  88.     @echo 'w' >>eddep
  89.     @cp Makefile makefile.bak
  90.     @ed - Makefile < eddep
  91.     @rm eddep makedep makefile.bak
  92.  
  93.  
  94.  
  95. # DO NOT DELETE THIS LINE
  96.  
  97. auth_none.o: types.h xdr.h auth.h
  98. auth_unix.o: types.h xdr.h auth.h auth_unix.h
  99. authunix_prot.o: types.h xdr.h auth.h auth_unix.h
  100. clnt_perror.o: types.h xdr.h auth.h clnt.h rpc_msg.h
  101. clnt_raw.o: types.h xdr.h auth.h clnt.h rpc_msg.h
  102. clnt_tcp.o: types.h xdr.h auth.h clnt.h rpc_msg.h pmap_clnt.h
  103. clnt_udp.o: types.h xdr.h auth.h clnt.h rpc_msg.h pmap_clnt.h
  104. pmap_clnt.o: types.h xdr.h auth.h clnt.h rpc_msg.h pmap_prot.h pmap_clnt.h
  105. pmap_getmaps.o: types.h xdr.h auth.h clnt.h rpc_msg.h pmap_prot.h pmap_clnt.h
  106. pmap_getport.o: types.h xdr.h auth.h clnt.h rpc_msg.h pmap_prot.h pmap_clnt.h
  107. pmap_prot.o: types.h xdr.h pmap_prot.h
  108. pmap_rmt.o: types.h xdr.h auth.h clnt.h rpc_msg.h pmap_prot.h pmap_clnt.h
  109. rpc_prot.o: types.h xdr.h auth.h clnt.h rpc_msg.h
  110. svc.o: types.h xdr.h auth.h clnt.h rpc_msg.h svc.h svc_auth.h
  111. svc_auth.o: types.h xdr.h auth.h clnt.h rpc_msg.h svc.h svc_auth.h
  112. svc_auth_unix.o: types.h xdr.h auth.h clnt.h rpc_msg.h svc.h auth_unix.h
  113. svc_auth_unix.o: svc_auth.h
  114. svc_raw.o: types.h xdr.h auth.h clnt.h rpc_msg.h svc.h
  115. svc_tcp.o: types.h xdr.h auth.h clnt.h rpc_msg.h svc.h
  116. svc_udp.o: types.h xdr.h auth.h clnt.h rpc_msg.h svc.h
  117. xdr.o: types.h xdr.h
  118. xdr_array.o: types.h xdr.h
  119. xdr_float.o: types.h xdr.h
  120. xdr_mem.o: types.h xdr.h
  121. xdr_rec.o: types.h xdr.h
  122. xdr_reference.o: types.h xdr.h
  123. xdr_stdio.o: types.h xdr.h
  124. !Funky!Stuff!
  125. echo x - README
  126. sed 's/^X//' >README <<'!Funky!Stuff!'
  127. Things that you should be aware of:
  128.  
  129. 1.  At Sun, RPC is part of the C library.  This makefile will make a library
  130. called rpclib.
  131.  
  132. 2.  I have added two other files - portmap.c and rcpinfo.c; they usually
  133. do not live in this directory.  Also, both files
  134. assume that the rpc dot h files have been installed in /usr/include.
  135.  
  136. portmap.c is the source to /etc/portmap, the rpc deamon which must be started
  137. by root before any other rpc based servers or clients.
  138.  
  139. rpcinfo.c dumps the information that the portmap keeps; at Sun, it lives
  140. in /usr/etc/rpcinfo.
  141.  
  142. 3. The rpc library was built with a post-1.1 Sun release of the compiler.
  143. Old compilers complain about valid C.  You can make old compilers happy
  144. by changing some voids to ints.  However, the fix to the 4.2 VAX compiler is as
  145. follows:
  146.  
  147. trees.c:
  148.  
  149. removed spurious type mismatch errors in expressions involving
  150. pointers to void functions, e.g., void foo(){...} void (*f)() = foo;
  151.  
  152. 1250c1264,1266
  153. <         else if( mt12 == 0 ) break;
  154. ---
  155. >         /* if right is TVOID and looks like a CALL, is not ok */
  156. >         else if (mt2 == 0 && (p->in.right->in.op == CALL || p->in.right->in.op == UNARY CALL))
  157. >             break;
  158.  
  159. 4. The documentation is in ditroff form in subdirectory doc.  It depends
  160. on a Sun macro package (/usr/lib/tmac/tmac.sun) which I have included.
  161.  
  162. Bob Lyon 
  163. Sun Microsystems, Inc
  164. sun!blyon
  165. Thu Mar 28 1985
  166.  
  167. !Funky!Stuff!
  168. echo x - portmap.c
  169. sed 's/^X//' >portmap.c <<'!Funky!Stuff!'
  170. #ifndef lint
  171. static    char sccsid[] = "@(#)portmap.c 1.2 85/03/13 Copyr 1984 Sun Micro";
  172. #endif
  173.  
  174. /*
  175.  * Copyright (c) 1984 by Sun Microsystems, Inc.
  176.  */
  177.  
  178. /*
  179.  * portmap.c, Implements the program,version to port number mapping for
  180.  * rpc.
  181.  */
  182.  
  183. /*
  184.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  185.  * unrestricted use provided that this legend is included on all tape
  186.  * media and as a part of the software program in whole or part.  Users
  187.  * may copy or modify Sun RPC without charge, but are not authorized
  188.  * to license or distribute it to anyone else except as part of a product or
  189.  * program developed by the user.
  190.  * 
  191.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  192.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  193.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  194.  * 
  195.  * Sun RPC is provided with no support and without any obligation on the
  196.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  197.  * modification or enhancement.
  198.  * 
  199.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  200.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  201.  * OR ANY PART THEREOF.
  202.  * 
  203.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  204.  * or profits or other special, indirect and consequential damages, even if
  205.  * Sun has been advised of the possibility of such damages.
  206.  * 
  207.  * Sun Microsystems, Inc.
  208.  * 2550 Garcia Avenue
  209.  * Mountain View, California  94043
  210.  */
  211.  
  212. #include <rpc/rpc.h>
  213. #include <rpc/pmap_prot.h>
  214. #include <stdio.h>
  215. #include <netdb.h>
  216. #include <sys/socket.h>
  217. #include <sys/time.h>
  218. #include <sys/ioctl.h>
  219.  
  220. char *malloc();
  221. int reg_service();
  222. static int debugging = 0;
  223.  
  224. main()
  225. {
  226.     SVCXPRT *xprt;
  227.     int sock, pid, t;
  228.     struct sockaddr_in addr;
  229.     int len = sizeof(struct sockaddr_in);
  230.  
  231. #ifndef DEBUG
  232.     pid = fork();
  233.     if (pid < 0) {
  234.         perror("portmap: fork");
  235.         exit(1);
  236.     }
  237.     if (pid != 0)
  238.         exit(0);
  239.     for (t = 0; t < 20; t++)
  240.         close(t);
  241.      open("/", 0);
  242.      dup2(0, 1);
  243.      dup2(0, 2);
  244.      t = open("/dev/tty", 2);
  245.      if (t >= 0) {
  246.          ioctl(t, TIOCNOTTY, (char *)0);
  247.          close(t);
  248.      }
  249. #endif
  250.     if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
  251.         perror("portmap cannot create socket");
  252.         exit(1);
  253.     }
  254.  
  255.     addr.sin_addr.S_un.S_addr = 0;
  256.     addr.sin_family = AF_INET;
  257.     addr.sin_port = htons(PMAPPORT);
  258.     if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
  259.         perror("portmap cannot bind");
  260.         exit(1);
  261.     }
  262.  
  263.     if ((xprt = svcudp_create(sock)) == (SVCXPRT *)NULL) {
  264.         fprintf(stderr, "couldn't do udp_create\n");
  265.         exit(1);
  266.     }
  267.  
  268.     if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
  269.         perror("portmap cannot create socket");
  270.         exit(1);
  271.     }
  272.     if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
  273.         perror("portmap cannot bind");
  274.         exit(1);
  275.     }
  276.     if ((xprt = svctcp_create(sock, 0, 0)) == (SVCXPRT *)NULL) {
  277.         fprintf(stderr, "couldn't do tcp_create\n");
  278.         exit(1);
  279.     }
  280.  
  281.         (void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, FALSE);
  282.     svc_run();
  283.     fprintf(stderr, "run_svc returned unexpectedly\n");
  284.     abort();
  285. }
  286.  
  287. struct pmaplist *pmaplist;
  288.  
  289. static struct pmaplist *
  290. find_service(prog, vers, prot)
  291.     u_long prog;
  292.     u_long vers;
  293. {
  294.     register struct pmaplist *hit = NULL;
  295.     register struct pmaplist *pml;
  296.  
  297.     for (pml = pmaplist; pml != NULL; pml = pml->pml_next) {
  298.         if ((pml->pml_map.pm_prog != prog) ||
  299.             (pml->pml_map.pm_prot != prot))
  300.             continue;
  301.         hit = pml;
  302.         if (pml->pml_map.pm_vers == vers)
  303.             break;
  304.     }
  305.     return (hit);
  306. }
  307.  
  308. /* 
  309.  * 1 OK, 0 not
  310.  */
  311. reg_service(rqstp, xprt)
  312.     struct svc_req *rqstp;
  313.     SVCXPRT *xprt;
  314. {
  315.     struct pmap reg;
  316.     struct pmaplist *pml, *prevpml, *fnd;
  317.     int ans, port;
  318.     caddr_t t;
  319.     
  320. #ifdef DEBUG
  321.     fprintf(stderr, "server: about do a switch\n");
  322. #endif
  323.     switch (rqstp->rq_proc) {
  324.  
  325.     case PMAPPROC_NULL:
  326.         /*
  327.          * Null proc call
  328.          */
  329.         if ((!svc_sendreply(xprt, xdr_void, NULL)) && debugging) {
  330.             abort();
  331.         }
  332.         break;
  333.  
  334.     case PMAPPROC_SET:
  335.         /*
  336.          * Set a program,version to port mapping
  337.          */
  338.         if (!svc_getargs(xprt, xdr_pmap, ®))
  339.             svcerr_decode(xprt);
  340.         else {
  341.             /*
  342.              * check to see if already used
  343.              * find_service returns a hit even if
  344.              * the versions don't match, so check for it
  345.              */
  346.             fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
  347.             if (fnd && fnd->pml_map.pm_vers == reg.pm_vers) {
  348.                 if (fnd->pml_map.pm_port == reg.pm_port) {
  349.                     ans = 1;
  350.                     goto done;
  351.                 }
  352.                 else {
  353.                     ans = 0;
  354.                     goto done;
  355.                 }
  356.             } else {
  357.                 /* 
  358.                  * add to list
  359.                  */
  360.                 pml = (struct pmaplist *)
  361.                     malloc((u_int)sizeof(struct pmaplist));
  362.                 pml->pml_map = reg;
  363.                 pml->pml_next = pmaplist;
  364.                 pmaplist = pml;
  365.                 ans = 1;
  366.             }
  367.         done:
  368.             if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) &&
  369.                 debugging) {
  370.                 fprintf(stderr, "svc_sendreply\n");
  371.                 abort();
  372.             }
  373.         }
  374.         break;
  375.  
  376.     case PMAPPROC_UNSET:
  377.         /*
  378.          * Remove a program,version to port mapping.
  379.          */
  380.         if (!svc_getargs(xprt, xdr_pmap, ®))
  381.             svcerr_decode(xprt);
  382.         else {
  383.             ans = 0;
  384.             for (prevpml = NULL, pml = pmaplist; pml != NULL; ) {
  385.                 if ((pml->pml_map.pm_prog != reg.pm_prog) ||
  386.                     (pml->pml_map.pm_vers != reg.pm_vers)) {
  387.                     /* both pml & prevpml move forwards */
  388.                     prevpml = pml;
  389.                     pml = pml->pml_next;
  390.                     continue;
  391.                 }
  392.                 /* found it; pml moves forward, prevpml stays */
  393.                 ans = 1;
  394.                 t = (caddr_t)pml;
  395.                 pml = pml->pml_next;
  396.                 if (prevpml == NULL)
  397.                     pmaplist = pml;
  398.                 else
  399.                     prevpml->pml_next = pml;
  400.                 free(t);
  401.             }
  402.             if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) &&
  403.                 debugging) {
  404.                 fprintf(stderr, "svc_sendreply\n");
  405.                 abort();
  406.             }
  407.         }
  408.         break;
  409.  
  410.     case PMAPPROC_GETPORT:
  411.         /*
  412.          * Lookup the mapping for a program,version and return its port
  413.          */
  414.         if (!svc_getargs(xprt, xdr_pmap, ®))
  415.             svcerr_decode(xprt);
  416.         else {
  417.             fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
  418.             if (fnd)
  419.                 port = fnd->pml_map.pm_port;
  420.             else
  421.                 port = 0;
  422.             if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&port)) &&
  423.                 debugging) {
  424.                 fprintf(stderr, "svc_sendreply\n");
  425.                 abort();
  426.             }
  427.         }
  428.         break;
  429.  
  430.     case PMAPPROC_DUMP:
  431.         /*
  432.          * Return the current set of mapped program,version
  433.          */
  434.         if (!svc_getargs(xprt, xdr_void, NULL))
  435.             svcerr_decode(xprt);
  436.         else {
  437.             if ((!svc_sendreply(xprt, xdr_pmaplist,
  438.                 (caddr_t)&pmaplist)) && debugging) {
  439.                 fprintf(stderr, "svc_sendreply\n");
  440.                 abort();
  441.             }
  442.         }
  443.         break;
  444.  
  445.     case PMAPPROC_CALLIT:
  446.         /*
  447.          * Calls a procedure on the local machine.  If the requested
  448.          * procedure is not registered this procedure does not return
  449.          * error information!!
  450.          * This procedure is only supported on rpc/udp and calls via 
  451.          * rpc/udp.  It passes null authentication parameters.
  452.          */
  453.         callit(rqstp, xprt);
  454.         break;
  455.  
  456.     default:
  457.         svcerr_noproc(xprt);
  458.         break;
  459.     }
  460. }
  461.  
  462.  
  463. /*
  464.  * Stuff for the rmtcall service
  465.  */
  466. #define ARGSIZE 9000
  467.  
  468. typedef struct encap_parms {
  469.     u_long arglen;
  470.     char *args;
  471. };
  472.  
  473. static bool_t
  474. xdr_encap_parms(xdrs, epp)
  475.     XDR *xdrs;
  476.     struct encap_parms *epp;
  477. {
  478.  
  479.     return (xdr_bytes(xdrs, &(epp->args), &(epp->arglen), ARGSIZE));
  480. }
  481.  
  482. typedef struct rmtcallargs {
  483.     u_long    rmt_prog;
  484.     u_long    rmt_vers;
  485.     u_long    rmt_port;
  486.     u_long    rmt_proc;
  487.     struct encap_parms rmt_args;
  488. };
  489.  
  490. static bool_t
  491. xdr_rmtcall_args(xdrs, cap)
  492.     register XDR *xdrs;
  493.     register struct rmtcallargs *cap;
  494. {
  495.  
  496.     /* does not get a port number */
  497.     if (xdr_u_long(xdrs, &(cap->rmt_prog)) &&
  498.         xdr_u_long(xdrs, &(cap->rmt_vers)) &&
  499.         xdr_u_long(xdrs, &(cap->rmt_proc))) {
  500.         return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
  501.     }
  502.     return (FALSE);
  503. }
  504.  
  505. static bool_t
  506. xdr_rmtcall_result(xdrs, cap)
  507.     register XDR *xdrs;
  508.     register struct rmtcallargs *cap;
  509. {
  510.     if (xdr_u_long(xdrs, &(cap->rmt_port)))
  511.         return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
  512.     return (FALSE);
  513. }
  514.  
  515. /*
  516.  * only worries about the struct encap_parms part of struct rmtcallargs.
  517.  * The arglen must already be set!!
  518.  */
  519. static bool_t
  520. xdr_opaque_parms(xdrs, cap)
  521.     XDR *xdrs;
  522.     struct rmtcallargs *cap;
  523. {
  524.  
  525.     return (xdr_opaque(xdrs, cap->rmt_args.args, cap->rmt_args.arglen));
  526. }
  527.  
  528. /*
  529.  * This routine finds and sets the length of incoming opaque paraters
  530.  * and then calls xdr_opaque_parms.
  531.  */
  532. static bool_t
  533. xdr_len_opaque_parms(xdrs, cap)
  534.     register XDR *xdrs;
  535.     struct rmtcallargs *cap;
  536. {
  537.     register u_int beginpos, lowpos, highpos, currpos, pos;
  538.  
  539.     beginpos = lowpos = pos = xdr_getpos(xdrs);
  540.     highpos = lowpos + ARGSIZE;
  541.     while ((int)(highpos - lowpos) >= 0) {
  542.         currpos = (lowpos + highpos) / 2;
  543.         if (xdr_setpos(xdrs, currpos)) {
  544.             pos = currpos;
  545.             lowpos = currpos + 1;
  546.         } else {
  547.             highpos = currpos - 1;
  548.         }
  549.     }
  550.     xdr_setpos(xdrs, beginpos);
  551.     cap->rmt_args.arglen = pos - beginpos;
  552.     return (xdr_opaque_parms(xdrs, cap));
  553. }
  554.  
  555. /*
  556.  * Call a remote procedure service
  557.  * This procedure is very quiet when things go wrong.
  558.  * The proc is written to support broadcast rpc.  In the broadcast case,
  559.  * a machine should shut-up instead of complain, less the requestor be
  560.  * overrun with complaints at the expense of not hearing a valid reply ...
  561.  */
  562. static
  563. callit(rqstp, xprt)
  564.     struct svc_req *rqstp;
  565.     SVCXPRT *xprt;
  566. {
  567.     char buf[2000];
  568.     struct rmtcallargs a;
  569.     struct pmaplist *pml;
  570.     u_short port;
  571.     struct sockaddr_in me;
  572.     int socket = -1;
  573.     CLIENT *client;
  574.     struct authunix_parms *au = (struct authunix_parms *)rqstp->rq_clntcred;
  575.     struct timeval timeout;
  576.  
  577.     timeout.tv_sec = 5;
  578.     timeout.tv_usec = 0;
  579.     a.rmt_args.args = buf;
  580.     if (!svc_getargs(xprt, xdr_rmtcall_args, &a))
  581.         return;
  582.     if ((pml = find_service(a.rmt_prog, a.rmt_vers, IPPROTO_UDP)) == NULL)
  583.         return;
  584.     port = pml->pml_map.pm_port;
  585.     get_myaddress(&me);
  586.     me.sin_port = htons(port);
  587.     client = clntudp_create(&me, a.rmt_prog, a.rmt_vers, timeout, &socket);
  588.     if (client != (CLIENT *)NULL) {
  589.         if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) {
  590.             client->cl_auth = authunix_create(au->aup_machname,
  591.                au->aup_uid, au->aup_gid, au->aup_len, au->aup_gids);
  592.         }
  593.         a.rmt_port = (u_long)port;
  594.         if (clnt_call(client, a.rmt_proc, xdr_opaque_parms, &a,
  595.             xdr_len_opaque_parms, &a, timeout) == RPC_SUCCESS) {
  596.             svc_sendreply(xprt, xdr_rmtcall_result, &a);
  597.         }
  598.         AUTH_DESTROY(client->cl_auth);
  599.         clnt_destroy(client);
  600.     }
  601.     (void)close(socket);
  602. }
  603. !Funky!Stuff!
  604. echo x - rpc.h
  605. sed 's/^X//' >rpc.h <<'!Funky!Stuff!'
  606. /*
  607.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  608.  * unrestricted use provided that this legend is included on all tape
  609.  * media and as a part of the software program in whole or part.  Users
  610.  * may copy or modify Sun RPC without charge, but are not authorized
  611.  * to license or distribute it to anyone else except as part of a product or
  612.  * program developed by the user.
  613.  * 
  614.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  615.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  616.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  617.  * 
  618.  * Sun RPC is provided with no support and without any obligation on the
  619.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  620.  * modification or enhancement.
  621.  * 
  622.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  623.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  624.  * OR ANY PART THEREOF.
  625.  * 
  626.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  627.  * or profits or other special, indirect and consequential damages, even if
  628.  * Sun has been advised of the possibility of such damages.
  629.  * 
  630.  * Sun Microsystems, Inc.
  631.  * 2550 Garcia Avenue
  632.  * Mountain View, California  94043
  633.  */
  634. /*    @(#)rpc.h 1.2 85/02/08 SMI    */
  635.  
  636. /*
  637.  * rpc.h, Just includes the billions of rpc header files necessary to 
  638.  * do remote procedure calling.
  639.  *
  640.  * Copyright (C) 1984, Sun Microsystems, Inc.
  641.  */
  642.  
  643. #include <rpc/types.h>        /* some typedefs */
  644. #include <netinet/in.h>
  645.  
  646. /* external data representation interfaces */
  647. #include <rpc/xdr.h>        /* generic (de)serializer */
  648.  
  649. /* Client side only authentication */
  650. #include <rpc/auth.h>        /* generic authenticator (client side) */
  651.  
  652. /* Client side (mostly) remote procedure call */
  653. #include <rpc/clnt.h>        /* generic rpc stuff */
  654.  
  655. /* semi-private protocol headers */
  656. #include <rpc/rpc_msg.h>    /* protocol for rpc messages */
  657. #include <rpc/auth_unix.h>    /* protocol for unix style cred */
  658.  
  659. /* Server side only remote procedure callee */
  660. #include <rpc/svc.h>        /* service manager and multiplexer */
  661. #include <rpc/svc_auth.h>    /* service side authenticator */
  662. !Funky!Stuff!
  663. echo x - rpc_msg.h
  664. sed 's/^X//' >rpc_msg.h <<'!Funky!Stuff!'
  665. /*
  666.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  667.  * unrestricted use provided that this legend is included on all tape
  668.  * media and as a part of the software program in whole or part.  Users
  669.  * may copy or modify Sun RPC without charge, but are not authorized
  670.  * to license or distribute it to anyone else except as part of a product or
  671.  * program developed by the user.
  672.  * 
  673.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  674.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  675.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  676.  * 
  677.  * Sun RPC is provided with no support and without any obligation on the
  678.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  679.  * modification or enhancement.
  680.  * 
  681.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  682.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  683.  * OR ANY PART THEREOF.
  684.  * 
  685.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  686.  * or profits or other special, indirect and consequential damages, even if
  687.  * Sun has been advised of the possibility of such damages.
  688.  * 
  689.  * Sun Microsystems, Inc.
  690.  * 2550 Garcia Avenue
  691.  * Mountain View, California  94043
  692.  */
  693. /*      @(#)rpc_msg.h 1.3 85/03/14 SMI      */
  694.  
  695. /*
  696.  * rpc_msg.h
  697.  * rpc message definition
  698.  *
  699.  * Copyright (C) 1984, Sun Microsystems, Inc.
  700.  */
  701.  
  702. #define RPC_MSG_VERSION        ((u_long) 2)
  703. #define RPC_SERVICE_PORT    ((u_short) 2048)
  704.  
  705. /*
  706.  * Bottom up definition of an rpc message.
  707.  * NOTE: call and reply use the same overall stuct but
  708.  * different parts of unions within it.
  709.  */
  710.  
  711. enum msg_type {
  712.     CALL=0,
  713.     REPLY=1
  714. };
  715.  
  716. enum reply_stat {
  717.     MSG_ACCEPTED=0,
  718.     MSG_DENIED=1
  719. };
  720.  
  721. enum accept_stat {
  722.     SUCCESS=0,
  723.     PROG_UNAVAIL=1,
  724.     PROG_MISMATCH=2,
  725.     PROC_UNAVAIL=3,
  726.     GARBAGE_ARGS=4,
  727.     SYSTEM_ERR=5
  728. };
  729.  
  730. enum reject_stat {
  731.     RPC_MISMATCH=0,
  732.     AUTH_ERROR=1
  733. };
  734.  
  735. /*
  736.  * Reply part of an rpc exchange
  737.  */
  738.  
  739. /*
  740.  * Reply to an rpc request that was accepted by the server.
  741.  * Note: there could be an error even though the request was
  742.  * accepted.
  743.  */
  744. struct accepted_reply {
  745.     struct opaque_auth    ar_verf;
  746.     enum accept_stat    ar_stat;
  747.     union {
  748.         struct {
  749.             u_long    low;
  750.             u_long    high;
  751.         } AR_versions;
  752.         struct {
  753.             caddr_t    where;
  754.             xdrproc_t proc;
  755.         } AR_results;
  756.         /* and many other null cases */
  757.     } ru;
  758. #define    ar_results    ru.AR_results
  759. #define    ar_vers        ru.AR_versions
  760. };
  761.  
  762. /*
  763.  * Reply to an rpc request that was rejected by the server.
  764.  */
  765. struct rejected_reply {
  766.     enum reject_stat rj_stat;
  767.     union {
  768.         struct {
  769.             u_long low;
  770.             u_long high;
  771.         } RJ_versions;
  772.         enum auth_stat RJ_why;  /* why authentication did not work */
  773.     } ru;
  774. #define    rj_vers    ru.RJ_versions
  775. #define    rj_why    ru.RJ_why
  776. };
  777.  
  778. /*
  779.  * Body of a reply to an rpc request.
  780.  */
  781. struct reply_body {
  782.     enum reply_stat rp_stat;
  783.     union {
  784.         struct accepted_reply RP_ar;
  785.         struct rejected_reply RP_dr;
  786.     } ru;
  787. #define    rp_acpt    ru.RP_ar
  788. #define    rp_rjct    ru.RP_dr
  789. };
  790.  
  791. /*
  792.  * Body of an rpc request call.
  793.  */
  794. struct call_body {
  795.     u_long cb_rpcvers;    /* must be equal to two */
  796.     u_long cb_prog;
  797.     u_long cb_vers;
  798.     u_long cb_proc;
  799.     struct opaque_auth cb_cred;
  800.     struct opaque_auth cb_verf; /* protocol specific - provided by client */
  801. };
  802.  
  803. /*
  804.  * The rpc message
  805.  */
  806. struct rpc_msg {
  807.     u_long            rm_xid;
  808.     enum msg_type        rm_direction;
  809.     union {
  810.         struct call_body RM_cmb;
  811.         struct reply_body RM_rmb;
  812.     } ru;
  813. #define    rm_call        ru.RM_cmb
  814. #define    rm_reply    ru.RM_rmb
  815. };
  816. #define    acpted_rply    ru.RM_rmb.ru.RP_ar
  817. #define    rjcted_rply    ru.RM_rmb.ru.RP_dr
  818.  
  819.  
  820. /*
  821.  * XDR routine to handle a rpc message.
  822.  * xdr_callmsg(xdrs, cmsg)
  823.  *     XDR *xdrs;
  824.  *     struct rpc_msg *cmsg;
  825.  */
  826. extern bool_t    xdr_callmsg();
  827.  
  828. /*
  829.  * XDR routine to pre-serialize the static part of a rpc message.
  830.  * xdr_callhdr(xdrs, cmsg)
  831.  *     XDR *xdrs;
  832.  *     struct rpc_msg *cmsg;
  833.  */
  834. extern bool_t    xdr_callhdr();
  835.  
  836. /*
  837.  * XDR routine to handle a rpc reply.
  838.  * xdr_replymsg(xdrs, rmsg)
  839.  *     XDR *xdrs;
  840.  *     struct rpc_msg *rmsg;
  841.  */
  842. extern bool_t    xdr_replymsg();
  843.  
  844. /*
  845.  * Fills in the error part of a reply message.
  846.  * _seterr_reply(msg, error)
  847.  *     struct rpc_msg *msg;
  848.  *     struct rpc_err *error;
  849.  */
  850. extern void    _seterr_reply();
  851. !Funky!Stuff!
  852. echo x - rpc_prot.c
  853. sed 's/^X//' >rpc_prot.c <<'!Funky!Stuff!'
  854. /*
  855.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  856.  * unrestricted use provided that this legend is included on all tape
  857.  * media and as a part of the software program in whole or part.  Users
  858.  * may copy or modify Sun RPC without charge, but are not authorized
  859.  * to license or distribute it to anyone else except as part of a product or
  860.  * program developed by the user.
  861.  * 
  862.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  863.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  864.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  865.  * 
  866.  * Sun RPC is provided with no support and without any obligation on the
  867.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  868.  * modification or enhancement.
  869.  * 
  870.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  871.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  872.  * OR ANY PART THEREOF.
  873.  * 
  874.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  875.  * or profits or other special, indirect and consequential damages, even if
  876.  * Sun has been advised of the possibility of such damages.
  877.  * 
  878.  * Sun Microsystems, Inc.
  879.  * 2550 Garcia Avenue
  880.  * Mountain View, California  94043
  881.  */
  882. #ifndef lint
  883. static char sccsid[] = "@(#)rpc_prot.c 1.5 85/03/20 Copyr 1984 Sun Micro";
  884. #endif
  885.  
  886. /*
  887.  * rpc_prot.c
  888.  *
  889.  * Copyright (C) 1984, Sun Microsystems, Inc.
  890.  *
  891.  * This set of routines implements the rpc message definition,
  892.  * its serializer and some common rpc utility routines.
  893.  * The routines are meant for various implementations of rpc -
  894.  * they are NOT for the rpc client or rpc service implementations!
  895.  * Because authentication stuff is easy and is part of rpc, the opaque
  896.  * routines are also in this program.
  897.  */
  898.  
  899. #include "types.h"
  900. #include "xdr.h"
  901. #include "auth.h"
  902. #include "clnt.h"
  903. #include "rpc_msg.h"
  904.  
  905. /* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
  906.  
  907. struct opaque_auth _null_auth;
  908.  
  909. /*
  910.  * XDR an opaque authentication struct
  911.  * (see auth.h)
  912.  */
  913. bool_t
  914. xdr_opaque_auth(xdrs, ap)
  915.     register XDR *xdrs;
  916.     register struct opaque_auth *ap;
  917. {
  918.  
  919.     if (xdr_enum(xdrs, &(ap->oa_flavor)))
  920.         return (xdr_bytes(xdrs, &ap->oa_base,
  921.             &ap->oa_length, MAX_AUTH_BYTES));
  922.     return (FALSE);
  923. }
  924.  
  925. /*
  926.  * XDR a DES key.
  927.  */
  928. bool_t
  929. xdr_deskey(xdrs, blkp)
  930.     register XDR *xdrs;
  931.     register union des_block *blkp;
  932. {
  933.  
  934.     if (! xdr_u_long(xdrs, &(blkp->key.high)))
  935.         return (FALSE);
  936.     return (xdr_u_long(xdrs, &(blkp->key.low)));
  937. }
  938.  
  939. /* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
  940.  
  941. /*
  942.  * XDR the MSG_ACCEPTED part of a reply message union
  943.  */
  944. bool_t 
  945. xdr_accepted_reply(xdrs, ar)
  946.     register XDR *xdrs;   
  947.     register struct accepted_reply *ar;
  948. {
  949.  
  950.     /* personalized union, rather than calling xdr_union */
  951.     if (! xdr_opaque_auth(xdrs, &(ar->ar_verf)))
  952.         return (FALSE);
  953.     if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat)))
  954.         return (FALSE);
  955.     switch (ar->ar_stat) {
  956.  
  957.     case SUCCESS:
  958.         return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where));
  959.     
  960.     case PROG_MISMATCH:
  961.         if (! xdr_u_long(xdrs, &(ar->ar_vers.low)))
  962.             return (FALSE);
  963.         return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
  964.     }
  965.     return (TRUE);  /* TRUE => open ended set of problems */
  966. }
  967.  
  968. /*
  969.  * XDR the MSG_DENIED part of a reply message union
  970.  */
  971. bool_t 
  972. xdr_rejected_reply(xdrs, rr)
  973.     register XDR *xdrs;
  974.     register struct rejected_reply *rr;
  975. {
  976.  
  977.     /* personalized union, rather than calling xdr_union */
  978.     if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat)))
  979.         return (FALSE);
  980.     switch (rr->rj_stat) {
  981.  
  982.     case RPC_MISMATCH:
  983.         if (! xdr_u_long(xdrs, &(rr->rj_vers.low)))
  984.             return (FALSE);
  985.         return (xdr_u_long(xdrs, &(rr->rj_vers.high)));
  986.  
  987.     case AUTH_ERROR:
  988.         return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why)));
  989.     }
  990.     return (FALSE);
  991. }
  992.  
  993. static struct xdr_discrim reply_dscrm[3] = {
  994.     { (int)MSG_ACCEPTED, xdr_accepted_reply },
  995.     { (int)MSG_DENIED, xdr_rejected_reply },
  996.     { __dontcare__, NULL_xdrproc_t } };
  997.  
  998. /*
  999.  * XDR a reply message
  1000.  */
  1001. bool_t
  1002. xdr_replymsg(xdrs, rmsg)
  1003.     register XDR *xdrs;
  1004.     register struct rpc_msg *rmsg;
  1005. {
  1006.  
  1007.     if (
  1008.         xdr_u_long(xdrs, &(rmsg->rm_xid)) && 
  1009.         xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) &&
  1010.         (rmsg->rm_direction == REPLY) )
  1011.         return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
  1012.             (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t));
  1013.     return (FALSE);
  1014. }
  1015.  
  1016. /*
  1017.  * XDR a call message
  1018.  */
  1019. bool_t
  1020. xdr_callmsg(xdrs, cmsg)
  1021.     register XDR *xdrs;
  1022.     register struct rpc_msg *cmsg;
  1023. {
  1024.  
  1025.     if (
  1026.         xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
  1027.         xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
  1028.         (cmsg->rm_direction == CALL) &&
  1029.         xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
  1030.         (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) &&
  1031.         xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) &&
  1032.         xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)) &&
  1033.         xdr_u_long(xdrs, &(cmsg->rm_call.cb_proc)) &&
  1034.         xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) )
  1035.         return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf)));
  1036.     return (FALSE);
  1037. }
  1038.  
  1039. /*
  1040.  * Serializes the "static part" of a call message header.
  1041.  * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
  1042.  * The rm_xid is not really static, but the user can easily munge on the fly.
  1043.  */
  1044. bool_t
  1045. xdr_callhdr(xdrs, cmsg)
  1046.     register XDR *xdrs;
  1047.     register struct rpc_msg *cmsg;
  1048. {
  1049.  
  1050.     cmsg->rm_direction = CALL;
  1051.     cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
  1052.     if (
  1053.         (xdrs->x_op == XDR_ENCODE) &&
  1054.         xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
  1055.         xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
  1056.         xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
  1057.         xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) )
  1058.         return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)));
  1059.     return (FALSE);
  1060. }
  1061.  
  1062. /* ************************** Client utility routine ************* */
  1063.  
  1064. static void
  1065. accepted(acpt_stat, error)
  1066.     register enum accept_stat acpt_stat;
  1067.     register struct rpc_err *error;
  1068. {
  1069.  
  1070.     switch (acpt_stat) {
  1071.  
  1072.     case PROG_UNAVAIL:
  1073.         error->re_status = RPC_PROGUNAVAIL;
  1074.         return;
  1075.  
  1076.     case PROG_MISMATCH:
  1077.         error->re_status = RPC_PROGVERSMISMATCH;
  1078.         return;
  1079.  
  1080.     case PROC_UNAVAIL:
  1081.         error->re_status = RPC_PROCUNAVAIL;
  1082.         return;
  1083.  
  1084.     case GARBAGE_ARGS:
  1085.         error->re_status = RPC_CANTDECODEARGS;
  1086.         return;
  1087.  
  1088.     case SYSTEM_ERR:
  1089.         error->re_status = RPC_SYSTEMERROR;
  1090.         return;
  1091.  
  1092.     case SUCCESS:
  1093.         error->re_status = RPC_SUCCESS;
  1094.         return;
  1095.     }
  1096.     /* something's wrong, but we don't know what ... */
  1097.     error->re_status = RPC_FAILED;
  1098.     error->re_lb.s1 = (long)MSG_ACCEPTED;
  1099.     error->re_lb.s2 = (long)acpt_stat;
  1100. }
  1101.  
  1102. static void 
  1103. rejected(rjct_stat, error)
  1104.     register enum reject_stat rjct_stat;
  1105.     register struct rpc_err *error;
  1106. {
  1107.  
  1108.     switch (rjct_stat) {
  1109.  
  1110.     case RPC_VERSMISMATCH:
  1111.         error->re_status = RPC_VERSMISMATCH;
  1112.         return;
  1113.  
  1114.     case AUTH_ERROR:
  1115.         error->re_status = RPC_AUTHERROR;
  1116.         return;
  1117.     }
  1118.     /* something's wrong, but we don't know what ... */
  1119.     error->re_status = RPC_FAILED;
  1120.     error->re_lb.s1 = (long)MSG_DENIED;
  1121.     error->re_lb.s2 = (long)rjct_stat;
  1122. }
  1123.  
  1124. /*
  1125.  * given a reply message, fills in the error
  1126.  */
  1127. void
  1128. _seterr_reply(msg, error)
  1129.     register struct rpc_msg *msg;
  1130.     register struct rpc_err *error;
  1131. {
  1132.  
  1133.     /* optimized for normal, SUCCESSful case */
  1134.     switch (msg->rm_reply.rp_stat) {
  1135.  
  1136.     case MSG_ACCEPTED:
  1137.         if (msg->acpted_rply.ar_stat == SUCCESS) {
  1138.             error->re_status = RPC_SUCCESS;
  1139.             return;
  1140.         };
  1141.         accepted(msg->acpted_rply.ar_stat, error);
  1142.         break;
  1143.  
  1144.     case MSG_DENIED:
  1145.         rejected(msg->rjcted_rply.rj_stat, error);
  1146.         break;
  1147.  
  1148.     default:
  1149.         error->re_status = RPC_FAILED;
  1150.         error->re_lb.s1 = (long)(msg->rm_reply.rp_stat);
  1151.         break;
  1152.     }
  1153.     switch (error->re_status) {
  1154.  
  1155.     case RPC_VERSMISMATCH:
  1156.         error->re_vers.low = msg->rjcted_rply.rj_vers.low;
  1157.         error->re_vers.high = msg->rjcted_rply.rj_vers.high;
  1158.         break;
  1159.  
  1160.     case RPC_AUTHERROR:
  1161.         error->re_why = msg->rjcted_rply.rj_why;
  1162.         break;
  1163.  
  1164.     case RPC_PROGVERSMISMATCH:
  1165.         error->re_vers.low = msg->acpted_rply.ar_vers.low;
  1166.         error->re_vers.high = msg->acpted_rply.ar_vers.high;
  1167.         break;
  1168.     }
  1169. }
  1170. !Funky!Stuff!
  1171. echo x - rpcinfo.c
  1172. sed 's/^X//' >rpcinfo.c <<'!Funky!Stuff!'
  1173. /*      rpcinfo.c     1.2     85/01/15     */
  1174.  
  1175. /*
  1176.  * Copyright (C) 1984, Sun Microsystems, Inc.
  1177.  */
  1178.  
  1179. /*
  1180.  * rpcinfo: ping a particular rpc program
  1181.  *     or dump the portmapper
  1182.  */
  1183.  
  1184. #include <rpc/rpc.h>
  1185. #include <stdio.h>
  1186. #include <sys/socket.h>
  1187. #include <sys/time.h>
  1188. #include <netdb.h>
  1189. #include <rpc/pmap_prot.h>
  1190. #include <rpc/pmap_clnt.h>
  1191.  
  1192. #define MAXHOSTLEN 256
  1193.  
  1194. main(argc, argv)
  1195.     char **argv;
  1196. {
  1197.     int ans;
  1198.     
  1199.     if (argc < 2) {
  1200.         usage();
  1201.         exit(1);
  1202.     }
  1203.     if (argv[1][0] == '-') {
  1204.         switch(argv[1][1]) {
  1205.             case 't':
  1206.                 tcpping(argc-1, argv+1);
  1207.                 break;
  1208.             case 'p':
  1209.                 pmapdump(argc-1, argv+1);
  1210.                 break;
  1211.             case 'u':
  1212.                 udpping(argc-1, argv+1);
  1213.                 break;
  1214.             default:
  1215.                 usage();
  1216.                 exit(1);
  1217.                 break;
  1218.         }
  1219.     }
  1220.     else
  1221.         usage();
  1222. }
  1223.         
  1224. udpping(argc, argv)
  1225.     char **argv;
  1226. {
  1227.     int ans;
  1228.     
  1229.     if (argc != 4) {
  1230.         usage();
  1231.         exit(1);
  1232.     }
  1233.     ans = callrpc(argv[1], atoi(argv[2]), atoi(argv[3]), NULLPROC,
  1234.         xdr_void, 0, xdr_void, 0);
  1235.     if (ans != 0) {
  1236.         clnt_perrno(ans);
  1237.         fprintf(stderr, "\n");
  1238.         printf("proc %d vers %d is not available\n", atoi(argv[2]),
  1239.             atoi(argv[3]));
  1240.     }
  1241.     else
  1242.         printf("proc %d vers %d ready and waiting\n", atoi(argv[2]),
  1243.             atoi(argv[3]));
  1244. }
  1245.  
  1246. tcpping(argc, argv)
  1247.     int argc;
  1248.     char **argv;
  1249. {
  1250.     struct timeval to;
  1251.     struct sockaddr_in addr;
  1252.     enum clnt_stat rpc_stat;
  1253.     CLIENT *client;
  1254.     int sock = -1;
  1255.     struct hostent *hp;
  1256.  
  1257.     if (argc != 4) {
  1258.         usage();
  1259.         exit(1);
  1260.     }
  1261.     if ((hp = gethostbyname(argv[1])) == NULL) {
  1262.         fprintf(stderr, "can't find %s\n", argv[1]);
  1263.         exit(1);
  1264.     }
  1265.     addr.sin_family = AF_INET;
  1266.     addr.sin_port = 0;
  1267.     addr.sin_addr.s_addr = *(int *)hp->h_addr;
  1268.     if ((client = clnttcp_create(&addr, atoi(argv[2]),
  1269.         atoi(argv[3]), &sock, 0, 0)) == NULL) {
  1270.             clnt_pcreateerror("");
  1271.             printf("proc %d vers %d is not available\n",
  1272.                 atoi(argv[2]), atoi(argv[3]));
  1273.             exit(1);
  1274.         }
  1275.     to.tv_usec = 0;
  1276.     to.tv_sec = 10;
  1277.     rpc_stat = clnt_call(client, 0, xdr_void, NULL, xdr_void, NULL, to);
  1278.     if (rpc_stat != RPC_SUCCESS) {
  1279.         clnt_perrno(rpc_stat);
  1280.         fprintf(stderr, "\n");
  1281.         printf("proc %d vers %d is not available\n", atoi(argv[2]),
  1282.             atoi(argv[3]));
  1283.     }
  1284.     else
  1285.         printf("proc %d vers %d ready and waiting\n", atoi(argv[2]),
  1286.             atoi(argv[3]));
  1287. }
  1288.  
  1289. pmapdump(argc, argv)
  1290.     int argc;
  1291.     char **argv;
  1292. {
  1293.     struct sockaddr_in server_addr;
  1294.     struct hostent *hp;
  1295.     struct pmaplist *head;
  1296.     char hoststr[MAXHOSTLEN];
  1297.     int socket = -1;
  1298.     struct timeval minutetimeout;
  1299.     char *hostnm;
  1300.     register CLIENT *client;
  1301.     enum clnt_stat rpc_stat;
  1302.     
  1303.     if (argc > 2) {
  1304.         usage();
  1305.         exit(1);
  1306.     }
  1307.     if (argc == 2) {
  1308.         hostnm = argv[1];
  1309.     } else {
  1310.         gethostname(hoststr, sizeof(hoststr));
  1311.         hostnm = hoststr;
  1312.     }
  1313.     if ((hp = gethostbyname(hostnm)) == NULL) {
  1314.         fprintf(stderr, "cannot get addr for '%s'\n", hostnm);
  1315.         exit(0);
  1316.     }
  1317.     bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr, hp->h_length);
  1318.     server_addr.sin_family = AF_INET;
  1319.     minutetimeout.tv_sec = 60;
  1320.     minutetimeout.tv_usec = 0;
  1321.     server_addr.sin_port = htons(PMAPPORT);
  1322.     if ((client = clnttcp_create(&server_addr, PMAPPROG,
  1323.         PMAPVERS, &socket, 50, 500)) == NULL) {
  1324.         clnt_pcreateerror("rpcinfo: can't contact portmapper");
  1325.         exit(1);
  1326.     }
  1327.     if (clnt_call(client, PMAPPROC_DUMP, xdr_void, NULL,
  1328.         xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) {
  1329.         fprintf(stderr, "rpcinfo: can't contact portmapper");
  1330.         clnt_perrno(rpc_stat);
  1331.         fprintf(stderr, "\n");
  1332.         exit(1);
  1333.     }
  1334.     if (head == NULL) {
  1335.         printf("No remote programs registered.\n");
  1336.     } else {
  1337.         printf("[program, version, protocol, port]:\n\n");
  1338.         for (; head != (struct pmaplist *)NULL; head = head->pml_next) {
  1339.             printf("[%ld, %ld, %ld, %ld]\n",
  1340.                 head->pml_map.pm_prog,
  1341.                 head->pml_map.pm_vers,
  1342.                 head->pml_map.pm_prot,
  1343.                 head->pml_map.pm_port);
  1344.         }
  1345.     }
  1346. }
  1347.  
  1348. usage()
  1349. {
  1350.     fprintf(stderr, "Usage: rpcinfo -u host prognum versnum\n");
  1351.     fprintf(stderr, "       rpcinfo -t host prognum versnum\n");
  1352.     fprintf(stderr, "       rpcinfo -p [host]\n");
  1353. }
  1354. !Funky!Stuff!
  1355. echo x - types.h
  1356. sed 's/^X//' >types.h <<'!Funky!Stuff!'
  1357. /*
  1358.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1359.  * unrestricted use provided that this legend is included on all tape
  1360.  * media and as a part of the software program in whole or part.  Users
  1361.  * may copy or modify Sun RPC without charge, but are not authorized
  1362.  * to license or distribute it to anyone else except as part of a product or
  1363.  * program developed by the user.
  1364.  * 
  1365.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1366.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1367.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1368.  * 
  1369.  * Sun RPC is provided with no support and without any obligation on the
  1370.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  1371.  * modification or enhancement.
  1372.  * 
  1373.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1374.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  1375.  * OR ANY PART THEREOF.
  1376.  * 
  1377.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  1378.  * or profits or other special, indirect and consequential damages, even if
  1379.  * Sun has been advised of the possibility of such damages.
  1380.  * 
  1381.  * Sun Microsystems, Inc.
  1382.  * 2550 Garcia Avenue
  1383.  * Mountain View, California  94043
  1384.  */
  1385. /*      @(#)types.h 1.2 85/02/08 SMI      */
  1386.  
  1387. /*
  1388.  * Rpc additions to <sys/types.h>
  1389.  */
  1390.  
  1391. #define    bool_t    int
  1392. #define    enum_t    int
  1393. #define    FALSE    (0==1)
  1394. #define    TRUE    (1==1)
  1395. #define __dontcare__    -1
  1396.  
  1397. #define mem_alloc(bsize)    malloc(bsize)
  1398. #define mem_free(ptr, bsize)    free(ptr)
  1399. #ifndef major        /* ouch! */
  1400. #include <sys/types.h>
  1401. #endif
  1402. !Funky!Stuff!
  1403.  
  1404. exit
  1405.