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

  1. Date: Wed, 3 Apr 85 00:10:58 pst
  2. From: decvax!sun!pumpkinseed!blyon (Bob Lyon)
  3. Subject: Sun RPC part 8 of 10
  4.  
  5. echo x - pmap_clnt.c
  6. sed 's/^X//' >pmap_clnt.c <<'!Funky!Stuff!'
  7. /*
  8.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  9.  * unrestricted use provided that this legend is included on all tape
  10.  * media and as a part of the software program in whole or part.  Users
  11.  * may copy or modify Sun RPC without charge, but are not authorized
  12.  * to license or distribute it to anyone else except as part of a product or
  13.  * program developed by the user.
  14.  * 
  15.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  16.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  17.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  18.  * 
  19.  * Sun RPC is provided with no support and without any obligation on the
  20.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  21.  * modification or enhancement.
  22.  * 
  23.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  24.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  25.  * OR ANY PART THEREOF.
  26.  * 
  27.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  28.  * or profits or other special, indirect and consequential damages, even if
  29.  * Sun has been advised of the possibility of such damages.
  30.  * 
  31.  * Sun Microsystems, Inc.
  32.  * 2550 Garcia Avenue
  33.  * Mountain View, California  94043
  34.  */
  35. #ifndef lint
  36. static char sccsid[] = "@(#)pmap_clnt.c 1.3 85/02/08 Copyr 1984 Sun Micro";
  37. #endif
  38.  
  39. /*
  40.  * pmap_clnt.c
  41.  * Client interface to pmap rpc service.
  42.  *
  43.  * Copyright (C) 1984, Sun Microsystems, Inc.
  44.  */
  45.  
  46. #include "types.h"
  47. #include <netinet/in.h>
  48. #include "xdr.h"
  49. #include "auth.h"
  50. #include "clnt.h"
  51. #include "rpc_msg.h"
  52. #include "pmap_prot.h" 
  53. #include "pmap_clnt.h"
  54. #include <sys/socket.h>
  55. #include <sys/time.h>
  56. #include <stdio.h>
  57. #include <net/if.h>
  58. #include <sys/ioctl.h>
  59. #include <arpa/inet.h>
  60. #define NAMELEN 255
  61.  
  62. static struct timeval timeout = { 5, 0 };
  63. static struct timeval tottimeout = { 60, 0 };
  64. static struct sockaddr_in myaddress;
  65.  
  66. void clnt_perror();
  67.  
  68.  
  69. /*
  70.  * Set a mapping between program,version and port.
  71.  * Calls the pmap service remotely to do the mapping.
  72.  */
  73. bool_t
  74. pmap_set(program, version, protocol, port)
  75.     u_long program;
  76.     u_long version;
  77.     u_long protocol;
  78.     u_short port;
  79. {
  80.     struct sockaddr_in myaddress;
  81.     int socket = -1;
  82.     register CLIENT *client;
  83.     struct pmap parms;
  84.     bool_t rslt;
  85.  
  86.     get_myaddress(&myaddress);
  87.     client = clntudp_create(&myaddress, PMAPPROG, PMAPVERS,
  88.         timeout, &socket);
  89.     if (client == (CLIENT *)NULL)
  90.         return (FALSE);
  91.     parms.pm_prog = program;
  92.     parms.pm_vers = version;
  93.     parms.pm_prot = protocol;
  94.     parms.pm_port = port;
  95.     if (CLNT_CALL(client, PMAPPROC_SET, xdr_pmap, &parms, xdr_bool, &rslt,
  96.         tottimeout) != RPC_SUCCESS) {
  97.         clnt_perror(client, "Cannot register service");
  98.         return (FALSE);
  99.     }
  100.     CLNT_DESTROY(client);
  101.     (void)close(socket);
  102.     return (rslt);
  103. }
  104.  
  105. /*
  106.  * Remove the mapping between program,version and port.
  107.  * Calls the pmap service remotely to do the un-mapping.
  108.  */
  109. bool_t
  110. pmap_unset(program, version)
  111.     u_long program;
  112.     u_long version;
  113. {
  114.     struct sockaddr_in myaddress;
  115.     int socket = -1;
  116.     register CLIENT *client;
  117.     struct pmap parms;
  118.     bool_t rslt;
  119.  
  120.     get_myaddress(&myaddress);
  121.     client = clntudp_create(&myaddress, PMAPPROG, PMAPVERS,
  122.         timeout, &socket);
  123.     if (client == (CLIENT *)NULL)
  124.         return (FALSE);
  125.     parms.pm_prog = program;
  126.     parms.pm_vers = version;
  127.     parms.pm_port = parms.pm_prot = 0;
  128.     CLNT_CALL(client, PMAPPROC_UNSET, xdr_pmap, &parms, xdr_bool, &rslt,
  129.         tottimeout);
  130.     CLNT_DESTROY(client);
  131.     (void)close(socket);
  132.     return (rslt);
  133. }
  134.  
  135. /* 
  136.  * don't use gethostbyname, which would invoke yellow pages
  137.  */
  138. get_myaddress(addr)
  139.     struct sockaddr_in *addr;
  140. {
  141.     int s;
  142.     char buf[BUFSIZ];
  143.     struct ifconf ifc;
  144.     struct ifreq ifreq, *ifr;
  145.     int len;
  146.  
  147.     if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  148.         perror("get_myaddress: socket");
  149.         exit(1);
  150.     }
  151.     ifc.ifc_len = sizeof (buf);
  152.     ifc.ifc_buf = buf;
  153.     if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
  154.         perror("get_myaddress: ioctl (get interface configuration)");
  155.         exit(1);
  156.     }
  157.     ifr = ifc.ifc_req;
  158.     for (len = ifc.ifc_len; len; len -= sizeof ifreq) {
  159.         ifreq = *ifr;
  160.         if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
  161.             perror("get_myaddress: ioctl");
  162.             exit(1);
  163.         }
  164.         if (ifreq.ifr_flags & IFF_UP) {
  165.             *addr = *((struct sockaddr_in *)&ifr->ifr_addr);
  166.             addr->sin_port = htons(PMAPPORT);
  167.             break;
  168.         }
  169.         ifr++;
  170.     }
  171.     close(s);
  172. }
  173. !Funky!Stuff!
  174. echo x - pmap_clnt.h
  175. sed 's/^X//' >pmap_clnt.h <<'!Funky!Stuff!'
  176. /*
  177.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  178.  * unrestricted use provided that this legend is included on all tape
  179.  * media and as a part of the software program in whole or part.  Users
  180.  * may copy or modify Sun RPC without charge, but are not authorized
  181.  * to license or distribute it to anyone else except as part of a product or
  182.  * program developed by the user.
  183.  * 
  184.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  185.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  186.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  187.  * 
  188.  * Sun RPC is provided with no support and without any obligation on the
  189.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  190.  * modification or enhancement.
  191.  * 
  192.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  193.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  194.  * OR ANY PART THEREOF.
  195.  * 
  196.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  197.  * or profits or other special, indirect and consequential damages, even if
  198.  * Sun has been advised of the possibility of such damages.
  199.  * 
  200.  * Sun Microsystems, Inc.
  201.  * 2550 Garcia Avenue
  202.  * Mountain View, California  94043
  203.  */
  204. /*    @(#)pmap_clnt.h 1.1 84/12/20 SMI    */
  205.  
  206. /*
  207.  * portmap_clnt.h
  208.  * Supplies C routines to get to portmap services.
  209.  *
  210.  * Copyright (C) 1984, Sun Microsystems, Inc.
  211.  */
  212.  
  213. /*
  214.  * Usage:
  215.  *    success = pmap_set(program, version, protocol, port);
  216.  *    success = pmap_unset(program, version);
  217.  *    port = pmap_getport(address, program, version, protocol);
  218.  *    head = pmap_getmaps(address);
  219.  *    clnt_stat = pmap_rmtcall(address, program, version, procedure,
  220.  *        xdrargs, argsp, xdrres, resp, tout, port_ptr)
  221.  *        (works for udp only.) 
  222.  *     clnt_stat = clnt_broadcast(program, version, procedure,
  223.  *        xdrargs, argsp,    xdrres, resp, eachresult)
  224.  *        (like pmap_rmtcall, except the call is broadcasted to all
  225.  *        locally connected nets.  For each valid response received,
  226.  *        the procedure eachresult is called.  Its form is:
  227.  *    done = eachresult(resp, raddr)
  228.  *        bool_t done;
  229.  *        caddr_t resp;
  230.  *        struct sockaddr_in raddr;
  231.  *        where resp points to the results of the call and raddr is the
  232.  *        address if the responder to the broadcast.
  233.  */
  234.  
  235. extern bool_t        pmap_set();
  236. extern bool_t        pmap_unset();
  237. extern u_short        pmap_getport();
  238. extern struct pmaplist    *pmap_getmaps();
  239. enum clnt_stat        pmap_rmtcall();
  240. enum clnt_stat        clnt_broadcast();
  241. !Funky!Stuff!
  242. echo x - pmap_getmaps.c
  243. sed 's/^X//' >pmap_getmaps.c <<'!Funky!Stuff!'
  244. /*
  245.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  246.  * unrestricted use provided that this legend is included on all tape
  247.  * media and as a part of the software program in whole or part.  Users
  248.  * may copy or modify Sun RPC without charge, but are not authorized
  249.  * to license or distribute it to anyone else except as part of a product or
  250.  * program developed by the user.
  251.  * 
  252.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  253.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  254.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  255.  * 
  256.  * Sun RPC is provided with no support and without any obligation on the
  257.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  258.  * modification or enhancement.
  259.  * 
  260.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  261.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  262.  * OR ANY PART THEREOF.
  263.  * 
  264.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  265.  * or profits or other special, indirect and consequential damages, even if
  266.  * Sun has been advised of the possibility of such damages.
  267.  * 
  268.  * Sun Microsystems, Inc.
  269.  * 2550 Garcia Avenue
  270.  * Mountain View, California  94043
  271.  */
  272. #ifndef lint
  273. static char sccsid[] = "@(#)pmap_getmaps.c 1.2 85/02/08 Copyr 1984 Sun Micro";
  274. #endif
  275.  
  276. /*
  277.  * pmap_getmap.c
  278.  * Client interface to pmap rpc service.
  279.  * contains pmap_getmaps, which is only tcp service involved
  280.  *
  281.  * Copyright (C) 1984, Sun Microsystems, Inc.
  282.  */
  283.  
  284. #include "types.h"
  285. #include <netinet/in.h>
  286. #include "xdr.h"
  287. #include "auth.h"
  288. #include "clnt.h"
  289. #include "rpc_msg.h"
  290. #include "pmap_prot.h" 
  291. #include "pmap_clnt.h"
  292. #include <sys/socket.h>
  293. #include <sys/time.h>
  294. #include <netdb.h>
  295. #include <stdio.h>
  296. #include <errno.h>
  297. #include <net/if.h>
  298. #include <sys/ioctl.h>
  299. #define NAMELEN 255
  300. #define MAX_BROADCAST_SIZE 1400
  301.  
  302. extern int errno;
  303. static struct timeval timeout = { 3, 0 };
  304. static struct timeval tottimeout = { 24, 0 };
  305. static struct sockaddr_in myaddress;
  306.  
  307. /*
  308.  * Get a copy of the current port maps.
  309.  * Calls the pmap service remotely to do get the maps.
  310.  */
  311. struct pmaplist *
  312. pmap_getmaps(address)
  313.      struct sockaddr_in *address;
  314. {
  315.     struct pmaplist *head = (struct pmaplist *)NULL;
  316.     int socket = -1;
  317.     struct timeval minutetimeout;
  318.     register CLIENT *client;
  319.  
  320.     minutetimeout.tv_sec = 60;
  321.     minutetimeout.tv_usec = 0;
  322.     address->sin_port = htons(PMAPPORT);
  323.     client = clnttcp_create(address, PMAPPROG,
  324.         PMAPVERS, &socket, 50, 500);
  325.     if (client != (CLIENT *)NULL) {
  326.         if (CLNT_CALL(client, PMAPPROC_DUMP, xdr_void, NULL, xdr_pmaplist,
  327.             &head, minutetimeout) != RPC_SUCCESS) {
  328.             clnt_perror(client, "pmap_getmaps rpc problem");
  329.         }
  330.         CLNT_DESTROY(client);
  331.     }
  332.     (void)close(socket);
  333.     address->sin_port = 0;
  334.     return (head);
  335. }
  336. !Funky!Stuff!
  337. echo x - pmap_getport.c
  338. sed 's/^X//' >pmap_getport.c <<'!Funky!Stuff!'
  339. /*
  340.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  341.  * unrestricted use provided that this legend is included on all tape
  342.  * media and as a part of the software program in whole or part.  Users
  343.  * may copy or modify Sun RPC without charge, but are not authorized
  344.  * to license or distribute it to anyone else except as part of a product or
  345.  * program developed by the user.
  346.  * 
  347.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  348.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  349.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  350.  * 
  351.  * Sun RPC is provided with no support and without any obligation on the
  352.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  353.  * modification or enhancement.
  354.  * 
  355.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  356.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  357.  * OR ANY PART THEREOF.
  358.  * 
  359.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  360.  * or profits or other special, indirect and consequential damages, even if
  361.  * Sun has been advised of the possibility of such damages.
  362.  * 
  363.  * Sun Microsystems, Inc.
  364.  * 2550 Garcia Avenue
  365.  * Mountain View, California  94043
  366.  */
  367. #ifndef lint
  368. static char sccsid[] = "@(#)pmap_getport.c 1.1 85/02/08 Copyr 1984 Sun Micro";
  369. #endif
  370.  
  371. /*
  372.  * pmap_getport.c
  373.  * Client interface to pmap rpc service.
  374.  *
  375.  * Copyright (C) 1984, Sun Microsystems, Inc.
  376.  */
  377.  
  378. #include "types.h"
  379. #include <netinet/in.h>
  380. #include "xdr.h"
  381. #include "auth.h"
  382. #include "clnt.h"
  383. #include "rpc_msg.h"
  384. #include "pmap_prot.h" 
  385. #include "pmap_clnt.h"
  386. #include <sys/socket.h>
  387. #include <sys/time.h>
  388. #include <stdio.h>
  389. #include <net/if.h>
  390. #include <sys/ioctl.h>
  391. #include <arpa/inet.h>
  392. #define NAMELEN 255
  393.  
  394. static struct timeval timeout = { 5, 0 };
  395. static struct timeval tottimeout = { 60, 0 };
  396.  
  397. /*
  398.  * Find the mapped port for program,version.
  399.  * Calls the pmap service remotely to do the lookup.
  400.  * Returns 0 if no map exists.
  401.  */
  402. u_short
  403. pmap_getport(address, program, version, protocol)
  404.     struct sockaddr_in *address;
  405.     u_long program;
  406.     u_long version;
  407.     u_long protocol;
  408. {
  409.     u_short port = 0;
  410.     int socket = -1;
  411.     register CLIENT *client;
  412.     struct pmap parms;
  413.  
  414.     address->sin_port = htons(PMAPPORT);
  415.     client = clntudp_create(address, PMAPPROG,
  416.         PMAPVERS, timeout, &socket);
  417.     if (client != (CLIENT *)NULL) {
  418.         parms.pm_prog = program;
  419.         parms.pm_vers = version;
  420.         parms.pm_prot = protocol;
  421.         parms.pm_port = 0;  /* not needed or used */
  422.         if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms,
  423.             xdr_u_short, &port, tottimeout) != RPC_SUCCESS){
  424.             rpc_createerr.cf_stat = RPC_PMAPFAILURE;
  425.             clnt_geterr(client, &rpc_createerr.cf_error);
  426.         } else if (port == 0) {
  427.             rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
  428.         }
  429.         CLNT_DESTROY(client);
  430.     }
  431.     (void)close(socket);
  432.     address->sin_port = 0;
  433.     return (port);
  434. }
  435. !Funky!Stuff!
  436. echo x - pmap_prot.c
  437. sed 's/^X//' >pmap_prot.c <<'!Funky!Stuff!'
  438. /*
  439.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  440.  * unrestricted use provided that this legend is included on all tape
  441.  * media and as a part of the software program in whole or part.  Users
  442.  * may copy or modify Sun RPC without charge, but are not authorized
  443.  * to license or distribute it to anyone else except as part of a product or
  444.  * program developed by the user.
  445.  * 
  446.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  447.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  448.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  449.  * 
  450.  * Sun RPC is provided with no support and without any obligation on the
  451.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  452.  * modification or enhancement.
  453.  * 
  454.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  455.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  456.  * OR ANY PART THEREOF.
  457.  * 
  458.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  459.  * or profits or other special, indirect and consequential damages, even if
  460.  * Sun has been advised of the possibility of such damages.
  461.  * 
  462.  * Sun Microsystems, Inc.
  463.  * 2550 Garcia Avenue
  464.  * Mountain View, California  94043
  465.  */
  466. #ifndef lint
  467. static char sccsid[] = "@(#)pmap_prot.c 1.2 85/02/08 Copyr 1984 Sun Micro";
  468. #endif
  469.  
  470. /*
  471.  * pmap_prot.c
  472.  * Protocol for the local binder service, or pmap.
  473.  *
  474.  * Copyright (C) 1984, Sun Microsystems, Inc.
  475.  */
  476.  
  477. #include "types.h"
  478. #include "xdr.h"
  479. #include "pmap_prot.h"
  480.  
  481. #define NULL ((struct pmaplist *)0)
  482.  
  483. bool_t
  484. xdr_pmap(xdrs, regs)
  485.     XDR *xdrs;
  486.     struct pmap *regs;
  487. {
  488.  
  489.     if (xdr_u_long(xdrs, ®s->pm_prog) && 
  490.         xdr_u_long(xdrs, ®s->pm_vers) && 
  491.         xdr_u_long(xdrs, ®s->pm_prot))
  492.         return (xdr_u_long(xdrs, ®s->pm_port));
  493.     return (FALSE);
  494. }
  495.  
  496. /* 
  497.  * What is going on with linked lists? (!)
  498.  * First recall the link list declaration from pmap_prot.h:
  499.  *
  500.  * struct pmaplist {
  501.  *    struct pmap pml_map;
  502.  *    struct pmaplist *pml_map;
  503.  * };
  504.  *
  505.  * Compare that declaration with a corresponding xdr declaration that 
  506.  * is (a) pointer-less, and (b) recursive:
  507.  *
  508.  * typedef union switch (bool_t) {
  509.  * 
  510.  *    case TRUE: struct {
  511.  *        struct pmap;
  512.  *         pmaplist_t foo;
  513.  *    };
  514.  *
  515.  *    case FALSE: struct {};
  516.  * } pmaplist_t;
  517.  *
  518.  * Notice that the xdr declaration has no nxt pointer while
  519.  * the C declaration has no bool_t variable.  The bool_t can be
  520.  * interpreted as ``more data follows me''; if FALSE then nothing
  521.  * follows this bool_t; if TRUE then the bool_t is followed by
  522.  * an actual struct pmap, and then (recursively) by the 
  523.  * xdr union, pamplist_t.  
  524.  *
  525.  * This could be implemented via the xdr_union primitive, though this
  526.  * would cause a one recursive call per element in the list.  Rather than do
  527.  * that we can ``unwind'' the recursion
  528.  * into a while loop and do the union arms in-place.
  529.  *
  530.  * The head of the list is what the C programmer wishes to past around
  531.  * the net, yet is the data that the pointer points to which is interesting;
  532.  * this sounds like a job for xdr_reference!
  533.  */
  534. bool_t
  535. xdr_pmaplist(xdrs, rp)
  536.     register XDR *xdrs;
  537.     register struct pmaplist **rp;
  538. {
  539.     /*
  540.      * more_elements is pre-computed in case the direction is
  541.      * XDR_ENCODE or XDR_FREE.  more_elements is overwritten by
  542.      * xdr_bool when the direction is XDR_DECODE.
  543.      */
  544.     bool_t more_elements;
  545.     register int freeing = (xdrs->x_op == XDR_FREE);
  546.     register struct pmaplist **next;
  547.  
  548.     while (TRUE) {
  549.         more_elements = (bool_t)(*rp != NULL);
  550.         if (! xdr_bool(xdrs, &more_elements))
  551.             return (FALSE);
  552.         if (! more_elements)
  553.             return (TRUE);  /* we are done */
  554.         /*
  555.          * the unfortunate side effect of non-recursion is that in
  556.          * the case of freeing we must remember the next object
  557.          * before we free the current object ...
  558.          */
  559.         if (freeing)
  560.             next = &((*rp)->pml_next); 
  561.         if (! xdr_reference(xdrs, (caddr_t *)rp,
  562.             (u_int)sizeof(struct pmaplist), xdr_pmap))
  563.             return (FALSE);
  564.         rp = (freeing) ? next : &((*rp)->pml_next);
  565.     }
  566. }
  567. !Funky!Stuff!
  568. echo x - pmap_prot.h
  569. sed 's/^X//' >pmap_prot.h <<'!Funky!Stuff!'
  570. /*
  571.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  572.  * unrestricted use provided that this legend is included on all tape
  573.  * media and as a part of the software program in whole or part.  Users
  574.  * may copy or modify Sun RPC without charge, but are not authorized
  575.  * to license or distribute it to anyone else except as part of a product or
  576.  * program developed by the user.
  577.  * 
  578.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  579.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  580.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  581.  * 
  582.  * Sun RPC is provided with no support and without any obligation on the
  583.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  584.  * modification or enhancement.
  585.  * 
  586.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  587.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  588.  * OR ANY PART THEREOF.
  589.  * 
  590.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  591.  * or profits or other special, indirect and consequential damages, even if
  592.  * Sun has been advised of the possibility of such damages.
  593.  * 
  594.  * Sun Microsystems, Inc.
  595.  * 2550 Garcia Avenue
  596.  * Mountain View, California  94043
  597.  */
  598. /*    @(#)pmap_prot.h 1.1 84/12/20 SMI    */
  599.  
  600. /*
  601.  * pmap_prot.h
  602.  * Protocol for the local binder service, or pmap.
  603.  *
  604.  * Copyright (C) 1984, Sun Microsystems, Inc.
  605.  *
  606.  * The following procedures are supported by the protocol:
  607.  *
  608.  * PMAPPROC_NULL() returns ()
  609.  *     takes nothing, returns nothing
  610.  *
  611.  * PMAPPROC_SET(struct pmap) returns (bool_t)
  612.  *     TRUE is success, FALSE is failure.  Registers the tuple
  613.  *    [prog, vers, prot, port].
  614.  *
  615.  * PMAPPROC_UNSET(struct pmap) returns (bool_t)
  616.  *    TRUE is success, FALSE is failure.  Un-registers pair
  617.  *    [prog, vers].  prot and port are ignored.
  618.  *
  619.  * PMAPPROC_GETPORT(struct pmap) returns (long unsigned).
  620.  *    0 is failure.  Otherwise returns the port number where the pair
  621.  *    [prog, vers] is registered.  It may lie!
  622.  *
  623.  * PMAPPROC_DUMP() RETURNS (struct pmaplist *)
  624.  *
  625.  * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>)
  626.  *     RETURNS (port, string<>);
  627.  * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs);
  628.  *     Calls the procedure on the local machine.  If it is not registered,
  629.  *    this procedure is quite; ie it does not return error information!!!
  630.  *    This procedure only is supported on rpc/udp and calls via
  631.  *    rpc/udp.  This routine only passes null authentication parameters.
  632.  *    This file has no interface to xdr routines for PMAPPROC_CALLIT.
  633.  *
  634.  * The service supports remote procedure calls on udp/ip or tcp/ip socket 111.
  635.  */
  636.  
  637. #define PMAPPORT        ((u_short)111)
  638. #define PMAPPROG        ((u_long)100000)
  639. #define PMAPVERS        ((u_long)2)
  640. #define PMAPVERS_PROTO        ((u_long)2)
  641. #define PMAPVERS_ORIG        ((u_long)1)
  642. #define PMAPPROC_NULL        ((u_long)0)
  643. #define PMAPPROC_SET        ((u_long)1)
  644. #define PMAPPROC_UNSET        ((u_long)2)
  645. #define PMAPPROC_GETPORT    ((u_long)3)
  646. #define PMAPPROC_DUMP        ((u_long)4)
  647. #define PMAPPROC_CALLIT        ((u_long)5)
  648.  
  649. struct pmap {
  650.     long unsigned pm_prog;
  651.     long unsigned pm_vers;
  652.     long unsigned pm_prot;
  653.     long unsigned pm_port;
  654. };
  655.  
  656. extern bool_t xdr_pmap();
  657.  
  658. struct pmaplist {
  659.     struct pmap    pml_map;
  660.     struct pmaplist *pml_next;
  661. };
  662.  
  663. extern bool_t xdr_pmaplist();
  664. !Funky!Stuff!
  665. echo x - pmap_rmt.c
  666. sed 's/^X//' >pmap_rmt.c <<'!Funky!Stuff!'
  667. /*
  668.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  669.  * unrestricted use provided that this legend is included on all tape
  670.  * media and as a part of the software program in whole or part.  Users
  671.  * may copy or modify Sun RPC without charge, but are not authorized
  672.  * to license or distribute it to anyone else except as part of a product or
  673.  * program developed by the user.
  674.  * 
  675.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  676.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  677.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  678.  * 
  679.  * Sun RPC is provided with no support and without any obligation on the
  680.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  681.  * modification or enhancement.
  682.  * 
  683.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  684.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  685.  * OR ANY PART THEREOF.
  686.  * 
  687.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  688.  * or profits or other special, indirect and consequential damages, even if
  689.  * Sun has been advised of the possibility of such damages.
  690.  * 
  691.  * Sun Microsystems, Inc.
  692.  * 2550 Garcia Avenue
  693.  * Mountain View, California  94043
  694.  */
  695. #ifndef lint
  696. static char sccsid[] = "@(#)pmap_rmt.c 1.4 85/03/17 Copyr 1984 Sun Micro";
  697. #endif
  698.  
  699. /*
  700.  * pmap_rmt.c
  701.  * Client interface to pmap rpc service.
  702.  * remote call and broadcast service
  703.  *
  704.  * Copyright (C) 1984, Sun Microsystems, Inc.
  705.  */
  706.  
  707. #include "types.h"
  708. #include <netinet/in.h>
  709. #include "xdr.h"
  710. #include "auth.h"
  711. #include "clnt.h"
  712. #include "rpc_msg.h"
  713. #include "pmap_prot.h" 
  714. #include "pmap_clnt.h"
  715. #include <sys/socket.h>
  716. #include <sys/time.h>
  717. #include <stdio.h>
  718. #include <errno.h>
  719. #include <net/if.h>
  720. #include <sys/ioctl.h>
  721. #include <arpa/inet.h>
  722. #define MAX_BROADCAST_SIZE 1400
  723.  
  724. extern int errno;
  725. static struct timeval timeout = { 3, 0 };
  726.  
  727. /*
  728.  * Structures and XDR routines for parameters to and replys from
  729.  * the pmapper remote-call-service.
  730.  */
  731.  
  732. struct rmtcallargs {
  733.     u_long prog, vers, proc, arglen;
  734.     caddr_t args_ptr;
  735.     xdrproc_t xdr_args;
  736. };
  737. static bool_t xdr_rmtcall_args();
  738.  
  739. struct rmtcallres {
  740.     u_long *port_ptr;
  741.     u_long resultslen;
  742.     caddr_t results_ptr;
  743.     xdrproc_t xdr_results;
  744. };
  745. static bool_t xdr_rmtcallres();
  746.  
  747. /*
  748.  * pmapper remote-call-service interface.
  749.  * This routine is used to call the pmapper remote call service
  750.  * which will look up a service program in the port maps, and then
  751.  * remotely call that routine with the given parameters.  This allows
  752.  * programs to do a lookup and call in one step.
  753. */
  754. enum clnt_stat
  755. pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_ptr)
  756.     struct sockaddr_in *addr;
  757.     u_long prog, vers, proc;
  758.     xdrproc_t xdrargs, xdrres;
  759.     caddr_t argsp, resp;
  760.     struct timeval tout;
  761.     u_long *port_ptr;
  762. {
  763.     int socket = -1;
  764.     register CLIENT *client;
  765.     struct rmtcallargs a;
  766.     struct rmtcallres r;
  767.     enum clnt_stat stat;
  768.  
  769.     addr->sin_port = htons(PMAPPORT);
  770.     client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &socket);
  771.     if (client != (CLIENT *)NULL) {
  772.         a.prog = prog;
  773.         a.vers = vers;
  774.         a.proc = proc;
  775.         a.args_ptr = argsp;
  776.         a.xdr_args = xdrargs;
  777.         r.port_ptr = port_ptr;
  778.         r.results_ptr = resp;
  779.         r.xdr_results = xdrres;
  780.         stat = CLNT_CALL(client, PMAPPROC_CALLIT, xdr_rmtcall_args, &a,
  781.             xdr_rmtcallres, &r, tout);
  782.         CLNT_DESTROY(client);
  783.     } else {
  784.         stat = RPC_FAILED;
  785.     }
  786.     (void)close(socket);
  787.     addr->sin_port = 0;
  788.     return (stat);
  789. }
  790.  
  791. /*
  792.  * XDR remote call arguments
  793.  * written for XDR_ENCODE direction only
  794.  */
  795. static bool_t
  796. xdr_rmtcall_args(xdrs, cap)
  797.     register XDR *xdrs;
  798.     register struct rmtcallargs *cap;
  799. {
  800.     u_int lenposition, argposition, position;
  801.  
  802.     if (xdr_u_long(xdrs, &(cap->prog)) &&
  803.         xdr_u_long(xdrs, &(cap->vers)) &&
  804.         xdr_u_long(xdrs, &(cap->proc))) {
  805.         lenposition = XDR_GETPOS(xdrs);
  806.         if (! xdr_u_long(xdrs, &(cap->arglen)))
  807.             return (FALSE);
  808.         argposition = XDR_GETPOS(xdrs);
  809.         if (! (*(cap->xdr_args))(xdrs, cap->args_ptr))
  810.             return (FALSE);
  811.         position = XDR_GETPOS(xdrs);
  812.         cap->arglen = (u_long)position - (u_long)argposition;
  813.         XDR_SETPOS(xdrs, lenposition);
  814.         if (! xdr_u_long(xdrs, &(cap->arglen)))
  815.             return (FALSE);
  816.         XDR_SETPOS(xdrs, position);
  817.         return (TRUE);
  818.     }
  819.     return (FALSE);
  820. }
  821.  
  822. /*
  823.  * XDR remote call results
  824.  * written for XDR_DECODE direction only
  825.  */
  826. static bool_t
  827. xdr_rmtcallres(xdrs, crp)
  828.     register XDR *xdrs;
  829.     register struct rmtcallres *crp;
  830. {
  831.  
  832.     if (xdr_reference(xdrs, &crp->port_ptr, sizeof (u_long), xdr_u_long) &&
  833.         xdr_u_long(xdrs, &crp->resultslen))
  834.         return ((*(crp->xdr_results))(xdrs, crp->results_ptr));
  835.     return (FALSE);
  836. }
  837.  
  838. /*
  839.  * The following is kludged-up support for simple rpc broadcasts.
  840.  * Someday a large, complicated system will replace these trivial 
  841.  * routines which only support udp/ip .
  842.  */
  843.  
  844. static int
  845. getbroadcastnets(addrs, sock, buf)
  846.     struct in_addr *addrs;
  847.     int sock;  /* any valid socket will do */
  848.     char *buf;  /* why allocxate more when we can use existing... */
  849. {
  850.     struct ifconf ifc;
  851.         struct ifreq ifreq, *ifr;
  852.     struct sockaddr_in *sin;
  853.         int n, i;
  854.  
  855.     ifc.ifc_len = MAX_BROADCAST_SIZE;
  856.         ifc.ifc_buf = buf;
  857.         if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
  858.                 perror("broadcast: ioctl (get interface configuration)");
  859.                 return (0);
  860.         }
  861.         ifr = ifc.ifc_req;
  862.         for (i = 0, n = ifc.ifc_len/sizeof (struct ifreq); n > 0; n--, ifr++) {
  863.                 ifreq = *ifr;
  864.                 if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
  865.                         perror("broadcast: ioctl (get interface flags)");
  866.                         continue;
  867.                 }
  868.                 if (ifreq.ifr_flags & IFF_BROADCAST) {
  869.                         sin = (struct sockaddr_in *)&ifr->ifr_addr;
  870.             addrs[i++] = inet_makeaddr(inet_netof
  871.                 (sin->sin_addr.s_addr), INADDR_ANY);
  872.                 }
  873.         }
  874.     return (i);
  875. }
  876.  
  877. typedef bool_t (*resultproc_t)();
  878.  
  879. enum clnt_stat 
  880. clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
  881.     u_long        prog;        /* program number */
  882.     u_long        vers;        /* version number */
  883.     u_long        proc;        /* procedure number */
  884.     xdrproc_t    xargs;        /* xdr routine for args */
  885.     caddr_t        argsp;        /* pointer to args */
  886.     xdrproc_t    xresults;    /* xdr routine for results */
  887.     caddr_t        resultsp;    /* pointer to results */
  888.     resultproc_t    eachresult;    /* call with each result obtained */
  889. {
  890.     enum clnt_stat stat;
  891.     AUTH *unix_auth = authunix_create_default();
  892.     XDR xdr_stream;
  893.     register XDR *xdrs = &xdr_stream;
  894.     int outlen, inlen, fromlen, readfds, nets;
  895.     register int sock, mask, i;
  896.     bool_t done = FALSE;
  897.     register u_long xid;
  898.     u_long port;
  899.     struct in_addr addrs[20];
  900.     struct sockaddr_in baddr, raddr; /* broadcast and response addresses */
  901.     struct rmtcallargs a;
  902.     struct rmtcallres r;
  903.     struct rpc_msg msg;
  904.     struct timeval t; 
  905.     char outbuf[MAX_BROADCAST_SIZE], inbuf[MAX_BROADCAST_SIZE];
  906.  
  907.     /*
  908.      * initialization: create a socket, a broadcast address, and
  909.      * preserialize the arguments into a send buffer.
  910.      */
  911.     if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
  912.         perror("Cannot create socket for broadcast rpc");
  913.         stat = RPC_CANTSEND;
  914.         goto done_broad;
  915.     }
  916.     mask = (1 << sock);
  917.     nets = getbroadcastnets(addrs, sock, inbuf);
  918.     bzero(&baddr, sizeof (baddr));
  919.     baddr.sin_family = AF_INET;
  920.     baddr.sin_port = htons(PMAPPORT);
  921.     baddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
  922.     (void)gettimeofday(&t, (struct timezone *)0);
  923.     msg.rm_xid = xid = getpid() ^ t.tv_sec ^ t.tv_usec;
  924.     t.tv_usec = 0;
  925.     msg.rm_direction = CALL;
  926.     msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
  927.     msg.rm_call.cb_prog = PMAPPROG;
  928.     msg.rm_call.cb_vers = PMAPVERS;
  929.     msg.rm_call.cb_proc = PMAPPROC_CALLIT;
  930.     msg.rm_call.cb_cred = unix_auth->ah_cred;
  931.     msg.rm_call.cb_verf = unix_auth->ah_verf;
  932.     a.prog = prog;
  933.     a.vers = vers;
  934.     a.proc = proc;
  935.     a.xdr_args = xargs;
  936.     a.args_ptr = argsp;
  937.     r.port_ptr = &port;
  938.     r.xdr_results = xresults;
  939.     r.results_ptr = resultsp;
  940.     xdrmem_create(xdrs, outbuf, MAX_BROADCAST_SIZE, XDR_ENCODE);
  941.     if ((! xdr_callmsg(xdrs, &msg)) || (! xdr_rmtcall_args(xdrs, &a))) {
  942.         stat = RPC_CANTENCODEARGS;
  943.         goto done_broad;
  944.     }
  945.     outlen = (int)xdr_getpos(xdrs);
  946.     xdr_destroy(xdrs);
  947.     /*
  948.      * Basic loop: broadcast a packet and wait a while for response(s).
  949.      * The response timeout grows larger per iteration.
  950.      */
  951.     for (t.tv_sec = 2; t.tv_sec <= 6; t.tv_sec += 2) {
  952.         for (i = 0; i < nets; i++) {
  953.             baddr.sin_addr = addrs[i];
  954.             if (sendto(sock, outbuf, outlen, 0,
  955.                 (struct socketaddr *)&baddr,
  956.                 sizeof (struct sockaddr)) != outlen) {
  957.                 perror("Cannot send broadcast packet");
  958.                 stat = RPC_CANTSEND;
  959.                 goto done_broad;
  960.             }
  961.         }
  962.     recv_again:
  963.         msg.acpted_rply.ar_verf = _null_auth;
  964.         msg.acpted_rply.ar_results.where = (caddr_t)&r;
  965.                 msg.acpted_rply.ar_results.proc = xdr_rmtcallres;
  966.         readfds = mask;
  967.         switch (select(32, &readfds, (int *)NULL, (int *)NULL, &t)) {
  968.  
  969.         case 0:  /* timed out */
  970.             stat = RPC_TIMEDOUT;
  971.             continue;
  972.  
  973.         case -1:  /* some kind of error */
  974.             if (errno == EINTR)
  975.                 goto recv_again;
  976.             perror("Broadcast select problem");
  977.             stat = RPC_CANTRECV;
  978.             goto done_broad;
  979.  
  980.         }  /* end of select results switch */
  981.         if ((readfds & mask) == 0)
  982.             goto recv_again;
  983.     try_again:
  984.         fromlen = sizeof(struct sockaddr);
  985.         inlen = recvfrom(sock, inbuf, MAX_BROADCAST_SIZE, 0,
  986.             (struct sockaddr *)&raddr, &fromlen);
  987.         if (inlen < 0) {
  988.             if (errno == EINTR)
  989.                 goto try_again;
  990.             perror("Cannot receive reply to broadcast");
  991.             stat = RPC_CANTRECV;
  992.             goto done_broad;
  993.         }
  994.         if (inlen < sizeof(u_long))
  995.             goto recv_again;
  996.         /*
  997.          * see if reply transaction id matches sent id.
  998.          * If so, decode the results.
  999.          */
  1000.         xdrmem_create(xdrs, inbuf, inlen, XDR_DECODE);
  1001.         if (xdr_replymsg(xdrs, &msg)) {
  1002.             if ((msg.rm_xid == xid) &&
  1003.                 (msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
  1004.                 (msg.acpted_rply.ar_stat == SUCCESS)) {
  1005.                 raddr.sin_port = htons((u_short)port);
  1006.                 done = (*eachresult)(resultsp, &raddr);
  1007.             }
  1008.             /* otherwise, we just ignore the errors ... */
  1009.         } else {
  1010.             /* some kind of deserialization problem ... */
  1011.             if (msg.rm_xid == xid)
  1012.                 fprintf(stderr, "Broadcast deserialization problem");
  1013.             /* otherwise, just random garbage */
  1014.         }
  1015.         xdrs->x_op = XDR_FREE;
  1016.         msg.acpted_rply.ar_results.proc = xdr_void;
  1017.         (void)xdr_replymsg(xdrs, &msg);
  1018.         (void)(*xresults)(xdrs, resultsp);
  1019.         xdr_destroy(xdrs);
  1020.         if (done) {
  1021.             stat = RPC_SUCCESS;
  1022.             goto done_broad;
  1023.         } else {
  1024.             goto recv_again;
  1025.         }
  1026.     }
  1027. done_broad:
  1028.     (void)close(sock);
  1029.     AUTH_DESTROY(unix_auth);
  1030.     return (stat);
  1031. }
  1032. !Funky!Stuff!
  1033.  
  1034. exit
  1035.