Back to index

glibc  2.9
Classes | Functions | Variables
svc_unix.c File Reference
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <rpc/rpc.h>
#include <rpc/svc.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/poll.h>
#include <errno.h>
#include <stdlib.h>
#include <libintl.h>

Go to the source code of this file.

Classes

struct  unix_conn

Functions

static bool_t svcunix_recv (SVCXPRT *, struct rpc_msg *)
static enum xprt_stat svcunix_stat (SVCXPRT *)
static bool_t svcunix_getargs (SVCXPRT *, xdrproc_t, caddr_t)
static bool_t svcunix_reply (SVCXPRT *, struct rpc_msg *)
static bool_t svcunix_freeargs (SVCXPRT *, xdrproc_t, caddr_t)
static void svcunix_destroy (SVCXPRT *)
static bool_t rendezvous_request (SVCXPRT *, struct rpc_msg *)
static enum xprt_stat rendezvous_stat (SVCXPRT *)
static void svcunix_rendezvous_abort (void)
static int readunix (char *, char *, int)
static int writeunix (char *, char *, int)
static SVCXPRTmakefd_xprt (int, u_int, u_int)
SVCXPRTsvcunix_create (int sock, u_int sendsize, u_int recvsize, char *path)
SVCXPRTsvcunixfd_create (int fd, u_int sendsize, u_int recvsize)
static int __msgread (int sock, void *data, size_t cnt)
static int __msgwrite (int sock, void *data, size_t cnt)

Variables

static struct xp_ops

Class Documentation

struct unix_conn

Definition at line 110 of file svc_unix.c.


Function Documentation

static int __msgread ( int  sock,
void *  data,
size_t  cnt 
) [static]

Definition at line 305 of file svc_unix.c.

{
  struct iovec iov;
  struct msghdr msg;
  int len;

  iov.iov_base = data;
  iov.iov_len = cnt;

  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;
  msg.msg_name = NULL;
  msg.msg_namelen = 0;
#ifdef SCM_CREDENTIALS
  msg.msg_control = (caddr_t) &cm;
  msg.msg_controllen = sizeof (struct cmessage);
#endif
  msg.msg_flags = 0;

#ifdef SO_PASSCRED
  {
    int on = 1;
    if (__setsockopt (sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)))
      return -1;
  }
#endif

 restart:
  len = __recvmsg (sock, &msg, 0);
  if (len >= 0)
    {
      if (msg.msg_flags & MSG_CTRUNC || len == 0)
        return 0;
      else
        return len;
    }
  if (errno == EINTR)
    goto restart;
  return -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int __msgwrite ( int  sock,
void *  data,
size_t  cnt 
) [static]

Definition at line 347 of file svc_unix.c.

{
#ifndef SCM_CREDENTIALS
  /* We cannot implement this reliably.  */
  __set_errno (ENOSYS);
  return -1;
#else
  struct iovec iov;
  struct msghdr msg;
  struct cmsghdr *cmsg = &cm.cmsg;
  struct ucred cred;
  int len;

  /* XXX I'm not sure, if gete?id() is always correct, or if we should use
     get?id(). But since keyserv needs geteuid(), we have no other chance.
     It would be much better, if the kernel could pass both to the server. */
  cred.pid = __getpid ();
  cred.uid = __geteuid ();
  cred.gid = __getegid ();

  memcpy (CMSG_DATA(cmsg), &cred, sizeof (struct ucred));
  cmsg->cmsg_level = SOL_SOCKET;
  cmsg->cmsg_type = SCM_CREDENTIALS;
  cmsg->cmsg_len = sizeof(*cmsg) + sizeof(struct ucred);

  iov.iov_base = data;
  iov.iov_len = cnt;

  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;
  msg.msg_name = NULL;
  msg.msg_namelen = 0;
  msg.msg_control = cmsg;
  msg.msg_controllen = CMSG_ALIGN(cmsg->cmsg_len);
  msg.msg_flags = 0;

 restart:
  len = __sendmsg (sock, &msg, 0);
  if (len >= 0)
    return len;
  if (errno == EINTR)
    goto restart;
  return -1;

#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SVCXPRT *internal_function makefd_xprt ( int  fd,
u_int  sendsize,
u_int  recvsize 
) [static]

Definition at line 103 of file svc_unix.c.

                       {        /* kept in xprt->xp_p1 */
  u_int sendsize;
  u_int recvsize;
};

Here is the caller graph for this function:

static int readunix ( char *  xprtptr,
char *  buf,
int  len 
) [static]

Definition at line 400 of file svc_unix.c.

{
  SVCXPRT *xprt = (SVCXPRT *) xprtptr;
  int sock = xprt->xp_sock;
  int milliseconds = 35 * 1000;
  struct pollfd pollfd;

  do
    {
      pollfd.fd = sock;
      pollfd.events = POLLIN;
      switch (__poll (&pollfd, 1, milliseconds))
       {
       case -1:
         if (errno == EINTR)
           continue;
         /*FALLTHROUGH*/
       case 0:
         goto fatal_err;
       default:
         if ((pollfd.revents & POLLERR) || (pollfd.revents & POLLHUP)
             || (pollfd.revents & POLLNVAL))
           goto fatal_err;
         break;
       }
    }
  while ((pollfd.revents & POLLIN) == 0);

  if ((len = __msgread (sock, buf, len)) > 0)
    return len;

 fatal_err:
  ((struct unix_conn *) (xprt->xp_p1))->strm_stat = XPRT_DIED;
  return -1;
}

Here is the call graph for this function:

static bool_t rendezvous_request ( SVCXPRT xprt,
struct rpc_msg errmsg 
) [static]

Definition at line 235 of file svc_unix.c.

{
  int sock;
  struct unix_rendezvous *r;
  struct sockaddr_un addr;
  struct sockaddr_in in_addr;
  socklen_t len;

  r = (struct unix_rendezvous *) xprt->xp_p1;
again:
  len = sizeof (struct sockaddr_un);
  if ((sock = accept (xprt->xp_sock, (struct sockaddr *) &addr, &len)) < 0)
    {
      if (errno == EINTR)
       goto again;
      return FALSE;
    }
  /*
   * make a new transporter (re-uses xprt)
   */
  memset (&in_addr, '\0', sizeof (in_addr));
  in_addr.sin_family = AF_UNIX;
  xprt = makefd_xprt (sock, r->sendsize, r->recvsize);
  memcpy (&xprt->xp_raddr, &in_addr, sizeof (in_addr));
  xprt->xp_addrlen = len;
  return FALSE;             /* there is never an rpc msg to be processed */
}

Here is the call graph for this function:

static enum xprt_stat rendezvous_stat ( SVCXPRT xprt) [static]

Definition at line 264 of file svc_unix.c.

{
  return XPRT_IDLE;
}
SVCXPRT* svcunix_create ( int  sock,
u_int  sendsize,
u_int  recvsize,
char *  path 
)

Definition at line 138 of file svc_unix.c.

{
  bool_t madesock = FALSE;
  SVCXPRT *xprt;
  struct unix_rendezvous *r;
  struct sockaddr_un addr;
  socklen_t len = sizeof (struct sockaddr_in);

  if (sock == RPC_ANYSOCK)
    {
      if ((sock = __socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
       {
         perror (_("svc_unix.c - AF_UNIX socket creation problem"));
         return (SVCXPRT *) NULL;
       }
      madesock = TRUE;
    }
  memset (&addr, '\0', sizeof (addr));
  addr.sun_family = AF_UNIX;
  len = strlen (path) + 1;
  memcpy (addr.sun_path, path, len);
  len += sizeof (addr.sun_family);

  __bind (sock, (struct sockaddr *) &addr, len);

  if (__getsockname (sock, (struct sockaddr *) &addr, &len) != 0
      || __listen (sock, SOMAXCONN) != 0)
    {
      perror (_("svc_unix.c - cannot getsockname or listen"));
      if (madesock)
       __close (sock);
      return (SVCXPRT *) NULL;
    }

  r = (struct unix_rendezvous *) mem_alloc (sizeof (*r));
  xprt = (SVCXPRT *) mem_alloc (sizeof (SVCXPRT));
  if (r == NULL || xprt == NULL)
    {
      __fxprintf (NULL, "%s: %s", __func__, _("out of memory\n"));
      mem_free (r, sizeof (*r));
      mem_free (xprt, sizeof (SVCXPRT));
      return NULL;
    }
  r->sendsize = sendsize;
  r->recvsize = recvsize;
  xprt->xp_p2 = NULL;
  xprt->xp_p1 = (caddr_t) r;
  xprt->xp_verf = _null_auth;
  xprt->xp_ops = &svcunix_rendezvous_op;
  xprt->xp_port = -1;
  xprt->xp_sock = sock;
  xprt_register (xprt);
  return xprt;
}

Here is the call graph for this function:

static void svcunix_destroy ( SVCXPRT xprt) [static]

Definition at line 270 of file svc_unix.c.

{
  struct unix_conn *cd = (struct unix_conn *) xprt->xp_p1;

  xprt_unregister (xprt);
  __close (xprt->xp_sock);
  if (xprt->xp_port != 0)
    {
      /* a rendezvouser socket */
      xprt->xp_port = 0;
    }
  else
    {
      /* an actual connection socket */
      XDR_DESTROY (&(cd->xdrs));
    }
  mem_free ((caddr_t) cd, sizeof (struct unix_conn));
  mem_free ((caddr_t) xprt, sizeof (SVCXPRT));
}

Here is the call graph for this function:

static bool_t svcunix_freeargs ( SVCXPRT xprt,
xdrproc_t  xdr_args,
caddr_t  args_ptr 
) [static]

Definition at line 501 of file svc_unix.c.

{
  XDR *xdrs = &(((struct unix_conn *) (xprt->xp_p1))->xdrs);

  xdrs->x_op = XDR_FREE;
  return (*xdr_args) (xdrs, args_ptr);
}
static bool_t svcunix_getargs ( SVCXPRT xprt,
xdrproc_t  xdr_args,
caddr_t  args_ptr 
) [static]

Definition at line 494 of file svc_unix.c.

{
  return (*xdr_args) (&(((struct unix_conn *) (xprt->xp_p1))->xdrs),
                    args_ptr);
}
static bool_t svcunix_recv ( SVCXPRT xprt,
struct rpc_msg msg 
) [static]

Definition at line 471 of file svc_unix.c.

{
  struct unix_conn *cd = (struct unix_conn *) (xprt->xp_p1);
  XDR *xdrs = &(cd->xdrs);

  xdrs->x_op = XDR_DECODE;
  INTUSE(xdrrec_skiprecord) (xdrs);
  if (INTUSE(xdr_callmsg) (xdrs, msg))
    {
      cd->x_id = msg->rm_xid;
      /* set up verifiers */
#ifdef SCM_CREDENTIALS
      msg->rm_call.cb_verf.oa_flavor = AUTH_UNIX;
      msg->rm_call.cb_verf.oa_base = (caddr_t) &cm;
      msg->rm_call.cb_verf.oa_length = sizeof (cm);
#endif
      return TRUE;
    }
  cd->strm_stat = XPRT_DIED;       /* XXXX */
  return FALSE;
}

Here is the call graph for this function:

static void svcunix_rendezvous_abort ( void  ) [static]

Definition at line 81 of file svc_unix.c.

{
  abort ();
};

Here is the call graph for this function:

static bool_t svcunix_reply ( SVCXPRT xprt,
struct rpc_msg msg 
) [static]

Definition at line 510 of file svc_unix.c.

{
  struct unix_conn *cd = (struct unix_conn *) (xprt->xp_p1);
  XDR *xdrs = &(cd->xdrs);
  bool_t stat;

  xdrs->x_op = XDR_ENCODE;
  msg->rm_xid = cd->x_id;
  stat = INTUSE(xdr_replymsg) (xdrs, msg);
  (void) INTUSE(xdrrec_endofrecord) (xdrs, TRUE);
  return stat;
}

Here is the call graph for this function:

static enum xprt_stat svcunix_stat ( SVCXPRT xprt) [static]

Definition at line 458 of file svc_unix.c.

{
  struct unix_conn *cd =
  (struct unix_conn *) (xprt->xp_p1);

  if (cd->strm_stat == XPRT_DIED)
    return XPRT_DIED;
  if (!INTUSE(xdrrec_eof) (&(cd->xdrs)))
    return XPRT_MOREREQS;
  return XPRT_IDLE;
}

Here is the call graph for this function:

SVCXPRT* svcunixfd_create ( int  fd,
u_int  sendsize,
u_int  recvsize 
)

Definition at line 198 of file svc_unix.c.

{
  return makefd_xprt (fd, sendsize, recvsize);
}

Here is the call graph for this function:

static int writeunix ( char *  xprtptr,
char *  buf,
int  len 
) [static]

Definition at line 441 of file svc_unix.c.

{
  SVCXPRT *xprt = (SVCXPRT *) xprtptr;
  int i, cnt;

  for (cnt = len; cnt > 0; cnt -= i, buf += i)
    {
      if ((i = __msgwrite (xprt->xp_sock, buf, cnt)) < 0)
       {
         ((struct unix_conn *) (xprt->xp_p1))->strm_stat = XPRT_DIED;
         return -1;
       }
    }
  return len;
}

Here is the call graph for this function:


Variable Documentation

static struct xp_ops [static]