]> git.saurik.com Git - apple/libinfo.git/blobdiff - netinfo.subproj/multi_call.c
Libinfo-278.tar.gz
[apple/libinfo.git] / netinfo.subproj / multi_call.c
diff --git a/netinfo.subproj/multi_call.c b/netinfo.subproj/multi_call.c
deleted file mode 100644 (file)
index 2d12086..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * multi_call: send out multiple call messages, wait for first reply
- * Copyright (C) 1991 by NeXT, Inc.
- */
-#include <rpc/rpc.h>
-#include <rpc/pmap_prot.h>
-#include <sys/socket.h>
-#include <syslog.h>
-#include <sys/param.h>
-#include <arpa/inet.h>
-#include <string.h>
-#include <unistd.h>
-
-#ifdef NETINFOD
-#      include "socket_lock.h"
-#      include "clib.h"
-#      define multi_call _multi_call
-#else
-#      define socket_lock()
-#      define socket_unlock()
-#      include "clib.h"
-#endif
-
-
-#define NRETRIES 5
-#define USECS_PER_SEC 1000000
-
-
-/*
- * Wrapper for gethostname() syscall
- */
-static char *
-get_hostname(void)
-{
-       int len;
-       static char hostname[MAXHOSTNAMELEN + 1];
-
-       len = gethostname(hostname, sizeof(hostname));
-       if (len < 0) {
-               hostname[0] = 0;
-       } else {
-               hostname[len] = 0;
-       }
-       return (hostname);
-}
-
-
-/*
- * Encode a call message
- */
-static int
-encodemsg(
-         char *buf,
-         int buflen,
-         struct rpc_msg *call,
-         unsigned prognum,
-         unsigned versnum,
-         unsigned procnum,
-         xdrproc_t xdr_args,
-         void *arg
-         )
-{
-       XDR xdr;
-       unsigned size;
-       unsigned pos;
-
-       xdrmem_create(&xdr, buf, buflen, XDR_ENCODE);
-       if (!xdr_callmsg(&xdr, call) ||
-           !xdr_u_int(&xdr, &prognum) ||
-           !xdr_u_int(&xdr, &versnum) ||
-           !xdr_u_int(&xdr, &procnum)) {
-               return (0);
-       }
-       pos = xdr_getpos(&xdr);
-       xdr_setpos(&xdr, pos + BYTES_PER_XDR_UNIT);
-       if (!(*xdr_args)(&xdr, arg)) {
-               return (0);
-       }
-       size = xdr_getpos(&xdr) - pos;
-       xdr_setpos(&xdr, pos);
-       if (!xdr_u_int(&xdr, &size)) {
-               return (0);
-       }
-       return (pos + BYTES_PER_XDR_UNIT + size);
-}
-
-/*
- * Decode a reply message
- */
-static int
-decodemsg(
-         XDR *xdr,
-         xdrproc_t xdr_res,
-         void *res
-         )
-{
-       unsigned port;
-       unsigned len;
-       long *buf;
-       XDR bufxdr;
-
-       if (!xdr_u_int(xdr, &port) ||
-           !xdr_u_int(xdr, &len) ||
-           !(buf = (long *)xdr_inline(xdr, len))) {
-               return (0);
-       }
-       xdrmem_create(&bufxdr, (char *)buf, len * BYTES_PER_XDR_UNIT, 
-                     XDR_DECODE);
-       if (!(*xdr_res)(&bufxdr, res)) {
-               return (0);
-       }
-       return (1);
-       
-}
-
-/*
- * Do the real work
- */
-enum clnt_stat 
-multi_call(
-          unsigned naddrs,             
-          struct in_addr *addrs, 
-          u_long prognum,
-          u_long versnum,
-          u_long procnum,
-          xdrproc_t xdr_args,
-          void *argsvec,
-          unsigned argsize,
-          xdrproc_t xdr_res,
-          void *res,
-          int (*eachresult)(void *, struct sockaddr_in *, int),
-          int timeout
-          )
-{
-       struct authunix_parms aup;
-       char credbuf[MAX_AUTH_BYTES];
-       struct opaque_auth cred;
-       struct opaque_auth verf;
-       int gids[NGROUPS];
-       int s;
-       struct timeval tv;
-       struct timeval subtimeout;
-       unsigned long long utimeout;
-       int callno;
-       int serverno;
-       struct rpc_msg call;
-       struct rpc_msg reply;
-       struct sockaddr_in sin;
-       struct sockaddr_in from;
-       int fromsize;
-       char buf[UDPMSGSIZE];
-       int buflen;
-       unsigned trans_id;
-       int dtablesize = getdtablesize();
-       XDR xdr;
-       int sendlen;
-       fd_set fds;
-
-       /*
-        * Fill in Unix auth stuff
-        */
-       aup.aup_time = time(0);
-       aup.aup_machname = get_hostname();
-       aup.aup_uid = getuid();
-       aup.aup_gid = getgid();
-       aup.aup_gids = gids;
-       aup.aup_len = getgroups(NGROUPS, aup.aup_gids);
-
-       /*
-        * Encode unix auth
-        */
-       xdrmem_create(&xdr, credbuf, sizeof(credbuf), XDR_ENCODE);
-       if (!xdr_authunix_parms(&xdr, &aup)) {
-               return (RPC_CANTENCODEARGS);
-       }
-       cred.oa_flavor = AUTH_UNIX;
-       cred.oa_base = credbuf;
-       cred.oa_length = xdr_getpos(&xdr);
-
-       verf.oa_flavor = AUTH_NULL;
-       verf.oa_length = 0;
-
-       /*
-        * Set up call header information
-        */
-       trans_id = time(0) ^ getpid();
-       call.rm_xid = trans_id;
-       call.rm_direction = CALL;
-       call.rm_call.cb_rpcvers = 2;
-       call.rm_call.cb_prog = PMAPPROG;
-       call.rm_call.cb_vers = PMAPVERS;
-       call.rm_call.cb_proc = PMAPPROC_CALLIT;
-       call.rm_call.cb_cred = cred;
-       call.rm_call.cb_verf = verf;
-
-
-       /*
-        * Open socket
-        */
-       socket_lock();
-       s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-       socket_unlock();
-       if (s < 0) {
-               syslog(LOG_ERR, "multi_call: socket: %m");
-               return (RPC_FAILED);
-       }
-
-       /*
-        * Init timeouts
-        */
-       utimeout = ((unsigned long long) timeout) * USECS_PER_SEC;
-       subtimeout.tv_sec = (utimeout >> NRETRIES) / USECS_PER_SEC;
-       subtimeout.tv_usec = (utimeout >> NRETRIES) % USECS_PER_SEC;
-       tv = subtimeout;
-
-       /*
-        * Init address info
-        */
-       sin.sin_family = AF_INET;
-       sin.sin_port = htons(PMAPPORT);
-       bzero(sin.sin_zero, sizeof(sin.sin_zero));
-       
-       for (callno = 0; callno <= NRETRIES; callno++) {
-               /*
-                * Send a call message to each host with the appropriate args
-                */
-               for (serverno = 0; serverno < naddrs; serverno++) {
-                       call.rm_xid = trans_id + serverno;
-                       buflen = encodemsg(buf, sizeof(buf), &call, 
-                                          prognum, versnum, procnum, 
-                                          xdr_args, (argsvec + 
-                                                     (serverno * argsize)));
-                       if (buflen == 0) {
-                               /*
-                                * Encode failed
-                                */
-                               continue;
-                       }
-                       sin.sin_addr = addrs[serverno];
-                       sendlen = sendto(s, buf, buflen, 0, 
-                                        (struct sockaddr *)&sin, sizeof(sin));
-                       if (sendlen != buflen) {
-                               syslog(LOG_ERR, 
-                                      "Cannot send multicall packet to %s: %m",
-                                      inet_ntoa(addrs[serverno]));
-                       }
-               }
-
-               /*
-                * Double the timeout from previous timeout, if necessary
-                */
-               if (callno > 1) {
-                       tv.tv_sec *= 2;
-                       tv.tv_usec *= 2;
-                       if (tv.tv_usec >= USECS_PER_SEC) {
-                               tv.tv_usec -= USECS_PER_SEC;
-                               tv.tv_sec++;
-                       }
-               }
-
-
-#ifdef NETINFOD
-               /*
-                * Check for cancel by user
-                */
-               if (alert_aborted()) {
-                       socket_lock();
-                       close(s);
-                       socket_unlock();
-                       return (RPC_FAILED);
-               }
-#endif 
-               /*
-                * Wait for reply
-                */
-               FD_ZERO(&fds);
-               FD_SET(s, &fds);
-               switch (select(dtablesize, &fds, NULL, NULL, &tv)) {
-               case -1:
-                       syslog(LOG_ERR, "select failure: %m");
-                       continue;
-               case 0:
-                       continue;
-               default:
-                       break;
-               }
-
-               /*
-                * Receive packet
-                */
-               fromsize = sizeof(from);
-               buflen = recvfrom(s, buf, sizeof(buf), 0,
-                                 (struct sockaddr *)&from, &fromsize);
-               if (buflen < 0) {
-                       continue;
-               }
-
-               /*
-                * Decode packet and if no errors, call eachresult
-                */
-               xdrmem_create(&xdr, buf, buflen, XDR_DECODE);
-               reply.rm_reply.rp_acpt.ar_results.proc = xdr_void;
-               reply.rm_reply.rp_acpt.ar_results.where = NULL;
-               if (xdr_replymsg(&xdr, &reply) &&
-                   (reply.rm_xid >= trans_id) &&
-                   (reply.rm_xid < trans_id + naddrs) &&
-                   (reply.rm_reply.rp_stat == MSG_ACCEPTED) &&
-                   (reply.acpted_rply.ar_stat == SUCCESS) &&
-                   decodemsg(&xdr, xdr_res, res)) {
-                       if ((*eachresult)(res, &from, 
-                                         reply.rm_xid - trans_id)) {
-                               xdr_free(xdr_res, res);
-                               socket_lock();
-                               close(s);
-                               socket_unlock();
-                               return (RPC_SUCCESS);
-                       }
-               }
-               xdr_free(xdr_res, res);
-       }
-       socket_lock();
-       close(s);
-       socket_unlock();
-       return (RPC_TIMEDOUT);
-}
-
-
-
-