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

📄 xti.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (((struct t_call *)ptr)->opt.buf)       free(((struct t_call *)ptr)->opt.buf);    if (((struct t_call *)ptr)->udata.buf)       free(((struct t_call *)ptr)->udata.buf);    free(ptr);    break;      case T_DIS_STR:    if (((struct t_discon *)ptr)->udata.buf)       free(((struct t_discon *)ptr)->udata.buf);    free(ptr);    break;    case T_UNITDATA_STR:    if (((struct t_unitdata *)ptr)->addr.buf)       free(((struct t_unitdata *)ptr)->addr.buf);    if (((struct t_unitdata *)ptr)->opt.buf)       free(((struct t_unitdata *)ptr)->opt.buf);    if (((struct t_unitdata *)ptr)->udata.buf)       free(((struct t_unitdata *)ptr)->udata.buf);    free(ptr);    break;  case T_UDERROR_STR:    if (((struct t_uderr *)ptr)->addr.buf)       free(((struct t_uderr *)ptr)->addr.buf);    if (((struct t_uderr *)ptr)->opt.buf)       free(((struct t_uderr *)ptr)->opt.buf);    free(ptr);    break;  case T_INFO_STR:    free(ptr);    break;  default:#ifdef XTIXPG4    t_errno = TNOSTRUCTYPE;#else    t_errno = TSYSERR;    errno = EINVAL;#endif    return(-1);    break;  };  return(T_NULL);}/* *	T_GETINFO - get protocol-specific service information (optional) */int t_getinfo (fd, info)int fd;struct t_info *info;{    int status;  if (!(check_xtifd(fd))) {    t_errno = TBADF;    return(-1);  }  if (d_table.dcb == T_NULL) { /* must make sure we have dynamic table built */    t_errno = TBADF;    return(-1);  }    if (info != T_NULL) {    int tmp_len;	    /* here we go, let's get it from the kernel */    tmp_len = sizeof(struct t_info);    status = getsockopt(fd, SOL_SOCKET, SO_XTITPDFLT,			(char *) info,			&tmp_len );    if (status == -1) {      map_err_to_XTI(errno,&t_errno);      return(-1);    }  }  return (0);}/* * 	T_GETSTATE - get the current state (optional) */int t_getstate(fd)int fd;{  int tmp_state;  int tmp_size;  int status;  if (!(check_xtifd(fd))) {    t_errno = TBADF;    return(-1);  }  if (d_table.dcb == T_NULL) { /* must make sure we have dynamic table built */    t_errno = TBADF;    return(-1);  }  if (table(fd).active_flag != 1) {    t_errno = TBADF;    return(-1);  }  if (table(fd).state < XTI_UNINIT ||      table(fd).state > XTI_INREL) {    t_errno = TSTATECHNG;    return(-1);  }  tmp_size = sizeof(tmp_state);  status = getsockopt(fd, SOL_SOCKET, SO_XTITPSTATE,		      (char *) &tmp_state,		      &tmp_size);    if (status < 0) {    map_err_to_XTI(errno,&t_errno);		    return (-1);  }  table(fd).state = tmp_state;  return(tmp_state);}/* * 	T_LISTEN - listen for a connect request */int t_listen (fd, call)int fd;struct t_call *call;{  int tmp_resfd; /* temp. fd to hold connection */  int status;  #ifdef XTINSP  struct accessdata_dn nsp_accessdata;  int optl;#endif  int old_state;  int tmp_size;  int tmp_len;  struct xti_evtinfo evtinfo;  int buffer_overflow = 0;  if (!(check_xtifd(fd))) {    t_errno = TBADF;    return(-1);  }  if (d_table.dcb == T_NULL) { /* must make sure we have dynamic table built */    t_errno = TBADF;    return(-1);  }  old_state = table(fd).state;    if (check_XTI_state(fd, XTI_LISTEN) == -1) {    t_errno = TOUTSTATE;    return(-1);  }  if (table(fd).info.servtype != T_COTS &&       table(fd).info.servtype != T_COTS_ORD) {    t_errno = TNOTSUPPORT;    return(-1);  }  /*   * check for any incoming T_DISCONNECT's   */  status = xti_peek(fd, &evtinfo);  if (status == -1) return(-1);  if (evtinfo.evtarray[ffs(T_DISCONNECT)]) {    t_errno = TLOOK;    return(-1);  }  if (table(fd).qlen == 0) {    t_errno = TBADQLEN;    return(-1);  }    if (call == T_NULL) {    t_errno = TNOADDR;    return(-1);  }  if (call->addr.maxlen == 0 || call->addr.buf == T_NULL) {    t_errno = TNOADDR;    return (-1);  }  call->opt.len = 0;  call->udata.len = 0;  tmp_len = call->addr.maxlen;  if ((tmp_resfd = accept (fd, (struct sockaddr *) call->addr.buf,			   (int *) &tmp_len)) < 0) {    map_err_to_XTI(errno,&t_errno);    return (-1);  }   else {        call->addr.len = tmp_len; /* fill in len for user */    if (call->addr.maxlen < table(fd).info.addr) {      buffer_overflow = 1;    }        /*     * get SEQUENCE number from kernel     */        call->sequence = 0;    tmp_size = sizeof(tmp_size);    status = getsockopt(tmp_resfd, SOL_SOCKET, SO_XTISEQNUM,			(char *) &call->sequence,			&tmp_size);        if (status < 0) {      map_err_to_XTI(errno, &t_errno);      return(-1);    }        table(fd).sequence = call->sequence; /* assoc. seq. with this fd */      }   /*   * Option data   */  if (call->opt.maxlen > 0) {        if (table(fd).info.options == T_NOTSUPPORTED) {      t_errno = TNOTSUPPORT;      return(-1);    }       if (call->opt.maxlen < table(fd).info.options) {      buffer_overflow = 1;    }    if (!buffer_overflow) {       switch(table(fd).family) {      case AF_INET:              if (table(fd).xti_proto == IPPROTO_TCP) {		  /* here we go, let's get it from the kernel */		  tmp_len = call->opt.maxlen;	  status = getsockopt(tmp_resfd, IPPROTO_TCP, TCP_CONOPT,			      call->opt.buf,			      &tmp_len );		  call->opt.len = tmp_len;		  if (status == -1) {	    map_err_to_XTI(errno,&t_errno);	    return(-1);	  }        }        break;#ifdef XTIOSI      case AF_OSI:         {          char *usrdat;          int usrdatlen = table(fd).info.connect;	  tmp_len = call->opt.maxlen;	  status = getsockopt(tmp_resfd, OSIPROTO_COTS, TOPT_XTICONOPTS,			      call->opt.buf,			      &tmp_len );		  call->opt.len = tmp_len;		  if (status == -1) {	    map_err_to_XTI(errno,&t_errno);	    return(-1);	  }        }        break;#endif#ifdef XTINSP      case AF_DECnet:              optl = sizeof(struct accessdata_dn);        status = getsockopt(tmp_resfd, DNPROTO_NSP, DSO_CONACCESS, 			    (char *) &nsp_accessdata, 			    &optl );              if (status == -1) {	  map_err_to_XTI(errno,&t_errno);	  return(-1);        }              call->opt.len = optl;        bcopy(&nsp_accessdata,call->opt.buf,call->opt.len);        break;#endif      }; /* end switch */    } /* end if !buffer_overflow */  } /* end option data */    /*   * user data   */  if (call->udata.maxlen > 0) {        if (table(fd).info.connect == T_NOTSUPPORTED) {      t_errno = TNOTSUPPORT;      return(-1);    }        if (call->udata.maxlen < table(fd).info.connect) {      buffer_overflow = 1;    }    if (!buffer_overflow) {      switch(table(fd).family) {#ifdef XTIOSI      case AF_OSI:        {          char *usrdat;          int usrdatlen = table(fd).info.connect;          usrdat = (char *)malloc(usrdatlen);          if (usrdat == NULL) {            t_errno = TSYSERR;            errno = ENOBUFS;            return(-1);          }          bzero(usrdat, usrdatlen);          status = getsockopt(tmp_resfd, OSIPROTO_COTS, TOPT_OPTCONDATA,                              usrdat, &usrdatlen);          if (status == -1) {            free(usrdat);            map_err_to_XTI(errno,&t_errno);            return(-1);          }          bcopy(usrdat, call->udata.buf, usrdatlen);          call->udata.len = usrdatlen;        }        break;#endif XTIOSI#ifdef XTINSP      case AF_DECnet:              optl = call->udata.maxlen;        status = getsockopt(tmp_resfd, DNPROTO_NSP, DSO_CONDATA, 			    call->udata.buf, 			    &optl );              if (status == -1) {  	  map_err_to_XTI(errno,&t_errno);	  return(-1);        }              call->udata.len = optl;        break;#endif      default:        break;            };  /* end switch */    }  /* end if not buffer_overflow */  }  /* end user data */    /*   *	Update XTI state tables   */      table(fd).event = XTI_LISTEN;    /* T_LISTEN successful */    if (update_XTI_state(fd, tmp_resfd, old_state) == -1) {    t_errno = TOUTSTATE;    return(-1);  }  if (buffer_overflow) {    t_errno = TBUFOVFLW;    return(-1);  }  return (0);}/* *	T_LOOK - look at the current event on a transport endpoint */intt_look(fd)int fd;{  int status;  int xti_evt;  int tmp_size;  int tmp_len;  struct xti_evtinfo evtinfo;  if (!(check_xtifd(fd))) {    t_errno = TBADF;    return(-1);  }  status = xti_peek(fd, &evtinfo);  if (status < 0) {    map_err_to_XTI(errno, &t_errno);    return(-1);  }  /* Special: t_look now has event precedence   *   * (Connect events) highest   * T_LISTEN   * T_CONNECT   * (Data events)   * T_EXDATA   * T_DATA   * (Disconnect events)   * T_DISCONNECT   * T_ORDREL   * (Flow control events)   * T_GOEXDATA   * T_GODATA   * (error events)   * T_UDERR   */  if (evtinfo.evtarray[ffs(T_LISTEN)]) return(T_LISTEN);  if (evtinfo.evtarray[ffs(T_CONNECT)]) return(T_CONNECT);  if (evtinfo.evtarray[ffs(T_EXDATA)]) return(T_EXDATA);#ifndef XTI_UNEVENT  tmp_size = 0;  tmp_len = sizeof(int);  status = getsockopt(fd, SOL_SOCKET, SO_XTIREADEX,		      (char *) &tmp_size,		      &tmp_len );  if (status < 0) {    map_err_to_XTI(errno, &t_errno);    return(-1);  }  if (tmp_size > 0) return(T_EXDATA);#endif XTI_UNEVENT  if (evtinfo.evtarray[ffs(T_DATA)]) return(T_DATA);#ifndef XTI_UNEVENT  tmp_size = 0;  status = ioctl(fd, FIONREAD,(char *) &tmp_size );  if (status < 0) {    map_err_to_XTI(errno, &t_errno);    return(-1);  }  if (tmp_size > 0) return(T_DATA);#endif XTI_UNEVENT  if (evtinfo.evtarray[ffs(T_DISCONNECT)]) return(T_DISCONNECT);  if (evtinfo.evtarray[ffs(T_ORDREL)]) return(T_ORDREL);  if (evtinfo.evtarray[ffs(T_GOEXDATA)] ||      evtinfo.evtarray[ffs(T_GODATA)]) {        if (evtinfo.evtarray[ffs(T_GOEXDATA)])      xti_evt = T_GOEXDATA;    else      xti_evt = T_GODATA;        tmp_size = sizeof(xti_evt);    status = setsockopt(fd, SOL_SOCKET, SO_XTICLREVENT,			(char *) &xti_evt,			tmp_size);    if (status < 0) {      map_err_to_XTI(errno, &t_errno);      return(-1);    }    return(xti_evt);  }  if (evtinfo.evtarray[ffs(T_UDERR)]) return(T_UDERR);  /* No events */  return(0);}/* *	T_OPEN - establish a transport endpoint */int t_open (name, oflag, info)char *name;int oflag;struct t_info *info;{  extern struct xti_lookup *getname();  register struct xti_lookup *c;  int fd = -1;  int status;  int tmp_len;  struct t_info tmp_info;  int xti_epvalid;  int old_state;  /* debug code */  if (d_table.dcb == T_NULL) { /* must initalize dynamic descriptor table */    d_table.dcb = (struct d_entry (*)[])                    malloc( (unsigned) 			   ((sizeof(struct d_entry) * getdtablesize())) );  }  if ( d_table.dcb == T_NULL) {    map_err_to_XTI(ENOMEM, &t_errno);    return(-1);  }  if ((int) (c = getname(name)) != -1) {    if ((fd = socket (c->x_af, c->x_type, c->x_protocol)) == -1) {      map_err_to_XTI(errno,&t_errno);      return(-1);    }    else {       if (oflag != O_RDWR && oflag != (O_RDWR|O_NONBLOCK) ) {	t_errno = TBADFLAG;	return(-1);      }      xti_epvalid = 1;   /* endpoint is valid for XTI operations */      status = setsockopt(fd, SOL_SOCKET, SO_XTIFDVALID,			  (char *) &xti_epvalid,			  sizeof(xti_epvalid));            if (status < 0) {	map_err_to_XTI(errno, &t_errno);	return(-1);      }      if (oflag & O_NONBLOCK) {	int f_flags;	f_flags = fcntl(fd, F_GETFL, 0);	/* May change when POSIX things change */#define XTIPOSIX#ifdef XTIPOSIX	f_flags |= FNBLOCK;#else	f_flags |= FNDELAY;#endif	fcntl(fd, F_SETFL, f_flags);      }          /* here we go, let's get it from the kernel */            tmp_len = sizeof(struct t_info);      status = getsockopt(fd, SOL_SOCKET, SO_XTITPDFLT, 			  (char *) &tmp_info,			  &tmp_len );      if (status == -1) {	map_err_to_XTI(errno,&t_errno);	return(-1);      }      if (info != T_NULL) {	*info = tmp_info;      }    }    /*     * save info structure into descriptor table

⌨️ 快捷键说明

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