📄 xti.c
字号:
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 + -