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

📄 clnt_udp.c

📁 Axis 221 camera embedded programing interface
💻 C
📖 第 1 页 / 共 2 页
字号:
  XDR_SETPOS (xdrs, cu->cu_xdrpos);  /*   * the transaction is the first thing in the out buffer   */  (*(uint32_t *) (cu->cu_outbuf))++;  if ((!XDR_PUTLONG (xdrs, (long *) &proc)) ||      (!AUTH_MARSHALL (cl->cl_auth, xdrs)) ||      (!(*xargs) (xdrs, argsp)))    return (cu->cu_error.re_status = RPC_CANTENCODEARGS);  outlen = (int) XDR_GETPOS (xdrs);send_again:  if (sendto (cu->cu_sock, cu->cu_outbuf, outlen, 0,	      (struct sockaddr *) &(cu->cu_raddr), cu->cu_rlen)      != outlen)    {      cu->cu_error.re_errno = errno;      return (cu->cu_error.re_status = RPC_CANTSEND);    }  /*   * Hack to provide rpc-based message passing   */  if (timeout.tv_sec == 0 && timeout.tv_usec == 0)    {      return (cu->cu_error.re_status = RPC_TIMEDOUT);    } get_reply:  /*   * sub-optimal code appears here because we have   * some clock time to spare while the packets are in flight.   * (We assume that this is actually only executed once.)   */  reply_msg.acpted_rply.ar_verf = _null_auth;  reply_msg.acpted_rply.ar_results.where = resultsp;  reply_msg.acpted_rply.ar_results.proc = xresults;  fd.fd = cu->cu_sock;  fd.events = POLLIN;  anyup = 0;  for (;;)    {      switch (poll (&fd, 1, milliseconds))	{	case 0:	  if (anyup == 0)	    {	      anyup = is_network_up (cu->cu_sock);	      if (!anyup)		return (cu->cu_error.re_status = RPC_CANTRECV);	    }	  time_waited.tv_sec += cu->cu_wait.tv_sec;	  time_waited.tv_usec += cu->cu_wait.tv_usec;	  while (time_waited.tv_usec >= 1000000)	    {	      time_waited.tv_sec++;	      time_waited.tv_usec -= 1000000;	    }	  if ((time_waited.tv_sec < timeout.tv_sec) ||	      ((time_waited.tv_sec == timeout.tv_sec) &&	       (time_waited.tv_usec < timeout.tv_usec)))	    goto send_again;	  return (cu->cu_error.re_status = RPC_TIMEDOUT);	  /*	   * buggy in other cases because time_waited is not being	   * updated.	   */	case -1:	  if (errno == EINTR)	    continue;	  cu->cu_error.re_errno = errno;	  return (cu->cu_error.re_status = RPC_CANTRECV);	}#ifdef IP_RECVERR      if (fd.revents & POLLERR)	{	  struct msghdr msg;	  struct cmsghdr *cmsg;	  struct sock_extended_err *e;	  struct sockaddr_in err_addr;	  struct iovec iov;	  char *cbuf = (char *) alloca (outlen + 256);	  int ret;	  iov.iov_base = cbuf + 256;	  iov.iov_len = outlen;	  msg.msg_name = (void *) &err_addr;	  msg.msg_namelen = sizeof (err_addr);	  msg.msg_iov = &iov;	  msg.msg_iovlen = 1;	  msg.msg_flags = 0;	  msg.msg_control = cbuf;	  msg.msg_controllen = 256;	  ret = recvmsg (cu->cu_sock, &msg, MSG_ERRQUEUE);	  if (ret >= 0	      && memcmp (cbuf + 256, cu->cu_outbuf, ret) == 0	      && (msg.msg_flags & MSG_ERRQUEUE)	      && ((msg.msg_namelen == 0		   && ret >= 12)		  || (msg.msg_namelen == sizeof (err_addr)		      && err_addr.sin_family == AF_INET		      && memcmp (&err_addr.sin_addr, &cu->cu_raddr.sin_addr,				 sizeof (err_addr.sin_addr)) == 0		      && err_addr.sin_port == cu->cu_raddr.sin_port)))	    for (cmsg = CMSG_FIRSTHDR (&msg); cmsg;		 cmsg = CMSG_NXTHDR (&msg, cmsg))	      if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR)		{		  e = (struct sock_extended_err *) CMSG_DATA(cmsg);		  cu->cu_error.re_errno = e->ee_errno;		  return (cu->cu_error.re_status = RPC_CANTRECV);		}	}#endif      do	{	  fromlen = sizeof (struct sockaddr);	  inlen = recvfrom (cu->cu_sock, cu->cu_inbuf,			    (int) cu->cu_recvsz, 0,			    (struct sockaddr *) &from, &fromlen);	}      while (inlen < 0 && errno == EINTR);      if (inlen < 0)	{	  if (errno == EWOULDBLOCK)	    continue;	  cu->cu_error.re_errno = errno;	  return (cu->cu_error.re_status = RPC_CANTRECV);	}      if (inlen < 4)	continue;      /* see if reply transaction id matches sent id.        Don't do this if we only wait for a replay */      if (xargs != NULL	  && (*((u_int32_t *) (cu->cu_inbuf))	      != *((u_int32_t *) (cu->cu_outbuf))))	continue;      /* we now assume we have the proper reply */      break;    }  /*   * now decode and validate the response   */  xdrmem_create (&reply_xdrs, cu->cu_inbuf, (u_int) inlen, XDR_DECODE);  ok = xdr_replymsg (&reply_xdrs, &reply_msg);  /* XDR_DESTROY(&reply_xdrs);  save a few cycles on noop destroy */  if (ok)    {      _seterr_reply (&reply_msg, &(cu->cu_error));      if (cu->cu_error.re_status == RPC_SUCCESS)	{	  if (!AUTH_VALIDATE (cl->cl_auth,			      &reply_msg.acpted_rply.ar_verf))	    {	      cu->cu_error.re_status = RPC_AUTHERROR;	      cu->cu_error.re_why = AUTH_INVALIDRESP;	    }	  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 (nrefreshes > 0 && AUTH_REFRESH (cl->cl_auth))	    {	      nrefreshes--;	      goto call_again;	    }	}			/* end of unsuccessful completion */    }				/* end of valid reply message */  else    {      cu->cu_error.re_status = RPC_CANTDECODERES;    }  return cu->cu_error.re_status;}static voidclntudp_geterr (CLIENT *cl, struct rpc_err *errp){  struct cu_data *cu = (struct cu_data *) cl->cl_private;  *errp = cu->cu_error;}static bool_tclntudp_freeres (CLIENT *cl, xdrproc_t xdr_res, caddr_t res_ptr){  struct cu_data *cu = (struct cu_data *) cl->cl_private;  XDR *xdrs = &(cu->cu_outxdrs);  xdrs->x_op = XDR_FREE;  return (*xdr_res) (xdrs, res_ptr);}static voidclntudp_abort (void){}static bool_tclntudp_control (CLIENT *cl, int request, char *info){  struct cu_data *cu = (struct cu_data *) cl->cl_private;  switch (request)    {    case CLSET_FD_CLOSE:      cu->cu_closeit = TRUE;      break;    case CLSET_FD_NCLOSE:      cu->cu_closeit = FALSE;      break;    case CLSET_TIMEOUT:      cu->cu_total = *(struct timeval *) info;      break;    case CLGET_TIMEOUT:      *(struct timeval *) info = cu->cu_total;      break;    case CLSET_RETRY_TIMEOUT:      cu->cu_wait = *(struct timeval *) info;      break;    case CLGET_RETRY_TIMEOUT:      *(struct timeval *) info = cu->cu_wait;      break;    case CLGET_SERVER_ADDR:      *(struct sockaddr_in *) info = cu->cu_raddr;      break;    case CLGET_FD:      *(int *)info = cu->cu_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 *)cu->cu_outbuf);      break;    case CLSET_XID:      /* This will set the xid of the NEXT call */      *(u_long *)cu->cu_outbuf =  htonl(*(u_long *)info - 1);      /* decrement by 1 as clntudp_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 *)(cu->cu_outbuf +					  4 * BYTES_PER_XDR_UNIT));      break;    case CLSET_VERS:      *(u_long *)(cu->cu_outbuf + 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 *)(cu->cu_outbuf +					  3 * BYTES_PER_XDR_UNIT));      break;    case CLSET_PROG:      *(u_long *)(cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT)	= htonl(*(u_long *)info);      break;    /* The following are only possible with TI-RPC */    case CLGET_SVC_ADDR:    case CLSET_SVC_ADDR:    case CLSET_PUSH_TIMOD:    case CLSET_POP_TIMOD:    default:      return FALSE;    }  return TRUE;}static voidclntudp_destroy (CLIENT *cl){  struct cu_data *cu = (struct cu_data *) cl->cl_private;  if (cu->cu_closeit)    {      (void) close (cu->cu_sock);    }  XDR_DESTROY (&(cu->cu_outxdrs));  mem_free ((caddr_t) cu, (sizeof (*cu) + cu->cu_sendsz + cu->cu_recvsz));  mem_free ((caddr_t) cl, sizeof (CLIENT));}

⌨️ 快捷键说明

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