⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clnt_unix.c

📁 一个嵌入式C库
💻 C
📖 第 1 页 / 共 2 页
字号:
	}      /* free verifier ... */      if (reply_msg.acpted_rply.ar_verf.oa_base != NULL)	{	  xdrs->x_op = XDR_FREE;	  (void) xdr_opaque_auth (xdrs, &(reply_msg.acpted_rply.ar_verf));	}    }				/* end successful completion */  else    {      /* maybe our credentials need to be refreshed ... */      if (refreshes-- && AUTH_REFRESH (h->cl_auth))	goto call_again;    }				/* end of unsuccessful completion */  return ct->ct_error.re_status;}static voidclntunix_geterr (CLIENT *h, struct rpc_err *errp){  struct ct_data *ct = (struct ct_data *) h->cl_private;  *errp = ct->ct_error;}static bool_tclntunix_freeres (cl, xdr_res, res_ptr)     CLIENT *cl;     xdrproc_t xdr_res;     caddr_t res_ptr;{  struct ct_data *ct = (struct ct_data *) cl->cl_private;  XDR *xdrs = &(ct->ct_xdrs);  xdrs->x_op = XDR_FREE;  return (*xdr_res) (xdrs, res_ptr);}static voidclntunix_abort (){}static bool_tclntunix_control (CLIENT *cl, int request, char *info){  struct ct_data *ct = (struct ct_data *) cl->cl_private;  switch (request)    {    case CLSET_FD_CLOSE:      ct->ct_closeit = TRUE;      break;    case CLSET_FD_NCLOSE:      ct->ct_closeit = FALSE;      break;    case CLSET_TIMEOUT:      ct->ct_wait = *(struct timeval *) info;      break;    case CLGET_TIMEOUT:      *(struct timeval *) info = ct->ct_wait;      break;    case CLGET_SERVER_ADDR:      *(struct sockaddr_un *) info = ct->ct_addr;      break;    case CLGET_FD:      *(int *)info = ct->ct_sock;      break;    case CLGET_XID:      /*       * use the knowledge that xid is the       * first element in the call structure *.       * This will get the xid of the PREVIOUS call       */      *(u_long *) info = ntohl (*(u_long *)ct->ct_mcall);      break;    case CLSET_XID:      /* This will set the xid of the NEXT call */      *(u_long *) ct->ct_mcall =  htonl (*(u_long *)info - 1);      /* decrement by 1 as clntunix_call() increments once */    case CLGET_VERS:      /*       * This RELIES on the information that, in the call body,       * the version number field is the fifth field from the       * begining of the RPC header. MUST be changed if the       * call_struct is changed       */      *(u_long *) info = ntohl (*(u_long *) (ct->ct_mcall					     + 4 * BYTES_PER_XDR_UNIT));      break;    case CLSET_VERS:      *(u_long *) (ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT)	= htonl (*(u_long *) info);      break;    case CLGET_PROG:      /*       * This RELIES on the information that, in the call body,       * the program number field is the  field from the       * begining of the RPC header. MUST be changed if the       * call_struct is changed       */      *(u_long *) info = ntohl (*(u_long *) (ct->ct_mcall					     + 3 * BYTES_PER_XDR_UNIT));      break;    case CLSET_PROG:      *(u_long *) (ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT)	= htonl(*(u_long *) info);      break;    /* The following are only possible with TI-RPC */    case CLGET_RETRY_TIMEOUT:    case CLSET_RETRY_TIMEOUT:    case CLGET_SVC_ADDR:    case CLSET_SVC_ADDR:    case CLSET_PUSH_TIMOD:    case CLSET_POP_TIMOD:    default:      return FALSE;    }  return TRUE;}static voidclntunix_destroy (CLIENT *h){  struct ct_data *ct =  (struct ct_data *) h->cl_private;  if (ct->ct_closeit)    {      (void) close (ct->ct_sock);    }  XDR_DESTROY (&(ct->ct_xdrs));  mem_free ((caddr_t) ct, sizeof (struct ct_data));  mem_free ((caddr_t) h, sizeof (CLIENT));}static int__msgread (int sock, void *data, size_t cnt){  struct iovec iov;  struct msghdr msg;#ifdef SCM_CREDENTIALS  static char cm[CMSG_SPACE(sizeof (struct ucred))];#endif  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 = CMSG_SPACE(sizeof (struct ucred));#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;}static int__msgwrite (int sock, void *data, size_t cnt){#ifndef SCM_CREDENTIALS  /* We cannot implement this reliably.  */  __set_errno (ENOSYS);  return -1;#else  struct iovec iov;  struct msghdr msg;  struct cmsghdr *cmsg = alloca (CMSG_SPACE(sizeof (struct ucred)));  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}/* * Interface between xdr serializer and unix connection. * Behaves like the system calls, read & write, but keeps some error state * around for the rpc level. */static intreadunix (char *ctptr, char *buf, int len){  struct ct_data *ct = (struct ct_data *) ctptr;  struct pollfd fd;  int milliseconds = ((ct->ct_wait.tv_sec * 1000)		      + (ct->ct_wait.tv_usec / 1000));  if (len == 0)    return 0;  fd.fd = ct->ct_sock;  fd.events = POLLIN;  while (TRUE)    {      switch (poll (&fd, 1, milliseconds))        {        case 0:          ct->ct_error.re_status = RPC_TIMEDOUT;          return -1;        case -1:          if (errno == EINTR)            continue;          ct->ct_error.re_status = RPC_CANTRECV;          ct->ct_error.re_errno = errno;          return -1;        }      break;    }  switch (len = __msgread (ct->ct_sock, buf, len))    {    case 0:      /* premature eof */      ct->ct_error.re_errno = ECONNRESET;      ct->ct_error.re_status = RPC_CANTRECV;      len = -1;			/* it's really an error */      break;    case -1:      ct->ct_error.re_errno = errno;      ct->ct_error.re_status = RPC_CANTRECV;      break;    }  return len;}static intwriteunix (char *ctptr, char *buf, int len){  int i, cnt;  struct ct_data *ct = (struct ct_data *) ctptr;  for (cnt = len; cnt > 0; cnt -= i, buf += i)    {      if ((i = __msgwrite (ct->ct_sock, buf, cnt)) == -1)	{	  ct->ct_error.re_errno = errno;	  ct->ct_error.re_status = RPC_CANTSEND;	  return -1;	}    }  return len;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -