📄 xti.c
字号:
if (tmp_addr == T_NULL) { free(tmp_ptr); t_errno = TSYSERR; errno = ENOBUFS; return(T_NULL); } } else { ( (struct t_bind *) tmp_ptr)->addr.maxlen = T_NULL; ( (struct t_bind *) tmp_ptr)->addr.len = T_NULL; ( (struct t_bind *) tmp_ptr)->addr.buf = T_NULL; } break; case T_OPTMGMT_STR: tmp_ptr = (char *)malloc(sizeof(struct t_optmgmt)); if (tmp_ptr == T_NULL) { t_errno = TSYSERR; errno = ENOBUFS; return(T_NULL); } if (fields & T_OPT) { /* OPTION */ tmp_opt = allocate_opt(struct_type, tmp_ptr, tmp_addr, tmp_udata, (int) table(fd).info.options); if (tmp_opt == T_NULL) { free(tmp_ptr); t_errno = TSYSERR; errno = ENOBUFS; return(T_NULL); } } else { ( (struct t_optmgmt *) tmp_ptr)->opt.maxlen = T_NULL; ( (struct t_optmgmt *) tmp_ptr)->opt.len = T_NULL; ( (struct t_optmgmt *) tmp_ptr)->opt.buf = T_NULL; } break; case T_CALL_STR: tmp_ptr = (char *)malloc(sizeof(struct t_call)); if (tmp_ptr == T_NULL) { t_errno = TSYSERR; errno = ENOBUFS; return(T_NULL); } if (fields & T_ADDR) { /* ADDRESS */ if (table(fd).info.addr == -1) { /* can't allocate infinity */ free(tmp_ptr); t_errno = TSYSERR; errno = EINVAL; return(T_NULL); } tmp_addr = allocate_addr(struct_type, tmp_ptr, tmp_opt, tmp_udata, (int) table(fd).info.addr); if (tmp_addr == T_NULL) { free(tmp_ptr); t_errno = TSYSERR; errno = ENOBUFS; return(T_NULL); } } else { ( (struct t_call *) tmp_ptr)->addr.maxlen = T_NULL; ( (struct t_call *) tmp_ptr)->addr.len = T_NULL; ( (struct t_call *) tmp_ptr)->addr.buf = T_NULL; } if (fields & T_OPT) { /* OPTION */ tmp_opt = allocate_opt(struct_type, tmp_ptr, tmp_addr, tmp_udata, (int) table(fd).info.options); if (tmp_opt == T_NULL) { free(tmp_ptr); t_errno = TSYSERR; errno = ENOBUFS; return(T_NULL); } } else { ( (struct t_call *) tmp_ptr)->opt.maxlen = T_NULL; ( (struct t_call *) tmp_ptr)->opt.len = T_NULL; ( (struct t_call *) tmp_ptr)->opt.buf = T_NULL; } if (fields & T_UDATA) { /* UDATA */ size = MAX(table(fd).info.connect, table(fd).info.discon); if (size == -2) { free(tmp_ptr); t_errno = TSYSERR; errno = EINVAL; return(T_NULL); } tmp_udata = allocate_udata(struct_type, tmp_ptr, tmp_opt, tmp_addr, size); if (tmp_udata == T_NULL) { free(tmp_ptr); t_errno = TSYSERR; errno = ENOBUFS; return(T_NULL); } } else { ( (struct t_call *) tmp_ptr)->udata.maxlen = T_NULL; ( (struct t_call *) tmp_ptr)->udata.len = T_NULL; ( (struct t_call *) tmp_ptr)->udata.buf = T_NULL; } break; case T_DIS_STR: tmp_ptr = (char *)malloc(sizeof(struct t_discon)); if (tmp_ptr == T_NULL) { t_errno = TSYSERR; errno = ENOBUFS; return(T_NULL); } if (fields & T_UDATA) { /* UDATA */ if (table(fd).info.discon == -2) { free(tmp_ptr); t_errno = TSYSERR; errno = EINVAL; return(T_NULL); } tmp_udata = allocate_udata(struct_type, tmp_ptr, tmp_opt, tmp_addr, (int) table(fd).info.discon); if (tmp_udata == T_NULL) { free(tmp_ptr); t_errno = TSYSERR; errno = ENOBUFS; return(T_NULL); } } else { ( (struct t_discon *) tmp_ptr)->udata.maxlen = T_NULL; ( (struct t_discon *) tmp_ptr)->udata.len = T_NULL; ( (struct t_discon *) tmp_ptr)->udata.buf = T_NULL; } break; case T_UNITDATA_STR: tmp_ptr = (char *)malloc(sizeof(struct t_unitdata)); if (tmp_ptr == T_NULL) { t_errno = TSYSERR; errno = ENOBUFS; return(T_NULL); } if (fields & T_ADDR) { /* ADDRESS */ if (table(fd).info.addr == -1) { /* can't allocate infinity */ free(tmp_ptr); t_errno = TSYSERR; errno = EINVAL; return(T_NULL); } tmp_addr = allocate_addr(struct_type, tmp_ptr, tmp_opt, tmp_udata, (int) table(fd).info.addr); if (tmp_addr == T_NULL) { free(tmp_ptr); t_errno = TSYSERR; errno = ENOBUFS; return(T_NULL); } } else { ( (struct t_unitdata *) tmp_ptr)->addr.maxlen = T_NULL; ( (struct t_unitdata *) tmp_ptr)->addr.len = T_NULL; ( (struct t_unitdata *) tmp_ptr)->addr.buf = T_NULL; } if (fields & T_OPT) { /* OPTION */ tmp_opt = allocate_opt(struct_type, tmp_ptr, tmp_addr, tmp_udata, (int) table(fd).info.options); if (tmp_opt == T_NULL) { free(tmp_ptr); t_errno = TSYSERR; errno = ENOBUFS; return(T_NULL); } } else { ( (struct t_unitdata *) tmp_ptr)->opt.maxlen = T_NULL; ( (struct t_unitdata *) tmp_ptr)->opt.len = T_NULL; ( (struct t_unitdata *) tmp_ptr)->opt.buf = T_NULL; } if (fields & T_UDATA) { /* UDATA */ if (table(fd).info.tsdu == -1) { /* can't allocate infinity */ free(tmp_ptr); t_errno = TSYSERR; errno = EINVAL; return(T_NULL); } tmp_udata = allocate_udata(struct_type, tmp_ptr, tmp_opt, tmp_addr, (int) table(fd).info.tsdu); if (tmp_udata == T_NULL) { free(tmp_ptr); t_errno = TSYSERR; errno = ENOBUFS; return(T_NULL); } } else { ( (struct t_unitdata *) tmp_ptr)->udata.maxlen = T_NULL; ( (struct t_unitdata *) tmp_ptr)->udata.len = T_NULL; ( (struct t_unitdata *) tmp_ptr)->udata.buf = T_NULL; } break; case T_UDERROR_STR: tmp_ptr = (char *)malloc(sizeof(struct t_uderr)); if (tmp_ptr == T_NULL) { t_errno = TSYSERR; errno = ENOBUFS; return(T_NULL); } if (fields & T_ADDR) { /* ADDRESS */ if (table(fd).info.addr == -1) { /* can't allocate infinity */ free(tmp_ptr); t_errno = TSYSERR; errno = EINVAL; return(T_NULL); } tmp_addr = allocate_addr(struct_type, tmp_ptr, tmp_opt, tmp_udata, (int) table(fd).info.addr); if (tmp_addr == T_NULL) { free(tmp_ptr); t_errno = TSYSERR; errno = ENOBUFS; return(T_NULL); } } else { ( (struct t_uderr *) tmp_ptr)->addr.maxlen = T_NULL; ( (struct t_uderr *) tmp_ptr)->addr.len = T_NULL; ( (struct t_uderr *) tmp_ptr)->addr.buf = T_NULL; } if (fields & T_OPT) { /* OPTION */ tmp_opt = allocate_opt(struct_type, tmp_ptr, tmp_addr, tmp_udata, (int) table(fd).info.options); if (tmp_opt == T_NULL) { free(tmp_ptr); return(T_NULL); } } else { ( (struct t_uderr *) tmp_ptr)->opt.maxlen = T_NULL; ( (struct t_uderr *) tmp_ptr)->opt.len = T_NULL; ( (struct t_uderr *) tmp_ptr)->opt.buf = T_NULL; } break; case T_INFO_STR: tmp_ptr = (char *)malloc(sizeof(struct t_info)); if (tmp_ptr == T_NULL) { t_errno = TSYSERR; errno = ENOBUFS; return(T_NULL); } break; default: t_errno = TNOSTRUCTYPE; return(T_NULL); break; }; return(tmp_ptr);}/* * T_BIND - bind an address to a transport endpoint */intt_bind(fd, req, ret)int fd;struct t_bind *req;struct t_bind *ret;{ int old_state; struct sockaddr_in *tmp_inet_addr; /* ptr to internet address for address * generation */ int status; int xti_evtenable; struct t_bind fake_req; char acceptmode; int acceptmodel; int optl; 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_BIND) == -1) { t_errno = TOUTSTATE; return(-1); } if (table(fd).info.servtype != T_COTS && table(fd).info.servtype != T_COTS_ORD && table(fd).info.servtype != T_CLTS) { t_errno = TNOTSUPPORT; return(-1); } /* do this here instead of t_open - because of t_bind()-t_unbind() */ xti_evtenable = 1; /* endpoint has events enabled */ status = setsockopt(fd, SOL_SOCKET, SO_XTIENEVENT, (char *) &xti_evtenable, sizeof(xti_evtenable)); if (status < 0) { map_err_to_XTI(errno, &t_errno); return(-1); }retest: if (req != T_NULL && req->addr.len != T_NULL && req->addr.buf != T_NULL) { if (table(fd).info.addr != -1 && table(fd).info.addr != -2) if (req->addr.len > table(fd).info.addr) { t_errno = TBADADDR; return(-1); } /* * * Update internal XTI data structure */ table(fd).qlen = ( (SOMAXCONN < req->qlen) ? SOMAXCONN : req->qlen); if ((bind (fd, (struct sockaddr *) req->addr.buf, (int) req->addr.len)) < 0) { if (errno == EADDRNOTAVAIL) { req = T_NULL; /* force automatic address generation */ goto retest; } if (errno == EINVAL) { /* re-map (ie) short address */ t_errno = TBADADDR; return(-1); } map_err_to_XTI(errno,&t_errno); return (-1); } } else { /* Automatic address generation */ struct t_bind tmp_bind, *tmp; tmp = &tmp_bind; req = tmp; if (table(fd).info.addr == -1) { /* can't allocate infinity */ t_errno = TNOADDR; return(-1); } req->addr.len = table(fd).info.addr; req->addr.buf = (char *)malloc(req->addr.len); req->addr.maxlen = 0; table(fd).qlen = 0; req->qlen = 0; switch (table(fd).family) {#ifdef XTIOSI case AF_OSI: bzero(req->addr.buf, req->addr.len); ((struct sockaddr_osi *) req->addr.buf)->osi_family = AF_OSI; if (table(fd).info.servtype == T_CLTS) ((struct sockaddr_osi *) req->addr.buf)->osi_proto = OSIPROTO_CLTS; else ((struct sockaddr_osi *) req->addr.buf)->osi_proto = OSIPROTO_COTS; req->addr.len = sizeof(struct sockaddr_osi); break;#endif case AF_INET: bzero(req->addr.buf, req->addr.len); tmp_inet_addr = (struct sockaddr_in *) req->addr.buf; tmp_inet_addr->sin_family = AF_INET; tmp_inet_addr->sin_port = 0; tmp_inet_addr->sin_addr.s_addr = INADDR_ANY; break;#ifdef XTINSP case AF_DECnet: free(req->addr.buf); t_errno = TNOADDR; return(-1); break;#endif }; if ((bind (fd, (struct sockaddr *) req->addr.buf, (int) req->addr.len)) < 0) { if (errno == EINVAL) { /* re-map (ie) short address */ t_errno = TBADADDR; return(-1); } map_err_to_XTI(errno,&t_errno); return (-1); } free(req->addr.buf); /* free up tmp space */ fake_req = *req; /* copy req in case ret != T_NULL */ } /* end of Automatic address generation */ if (ret != T_NULL) { int tmp_len; if (req == T_NULL) req = &fake_req; if (req->addr.len > ret->addr.maxlen) { buffer_overflow = 1; } /* * go to kernel to get sockname */ if (!buffer_overflow) { tmp_len = ret->addr.maxlen; status = getsockname(fd, ret->addr.buf, &tmp_len); if (status == -1) { map_err_to_XTI(errno,&t_errno); return(-1); } ret->addr.len = tmp_len; } /* if not overflow */ /* * Return actual qlen */ ret->qlen = table(fd).qlen; } /* if ret != NULL */ /* * code for listen - this is needed because we have to be * able to enqueue connections after this call. */ if (table(fd).info.servtype == T_CLTS) table(fd).qlen = 0; if (table(fd).qlen > 0) { /* we must do a listen here */ switch(table(fd).family) {#ifdef XTINSP case AF_DECnet: acceptmode = ACC_DEFER; optl = 1; status = setsockopt(fd, DNPROTO_NSP, DSO_ACCEPTMODE, (char *) &acceptmode, optl ); if (status == -1) { map_err_to_XTI(errno,&t_errno); return(-1); } break;#endif case AF_INET: acceptmodel = ACC_DEFER; optl = sizeof(acceptmodel); status = setsockopt(fd, IPPROTO_TCP, TCP_ACCEPTMODE, (char *) &acceptmodel, optl ); if (status == -1) { map_err_to_XTI(errno,&t_errno); return(-1); } break;#ifdef XTIOSI case AF_OSI: acceptmode = ACCEPTMODE_DEFERED; optl = 1; status = setsockopt(fd, OSIPROTO_COTS, TOPT_ACCEPTMODE, (char *) &acceptmode, optl ); if (status == -1) { map_err_to_XTI(errno,&t_errno); return(-1); } break;#endif default: break; }; status = listen(fd, table(fd).qlen); if (status == -1) { map_err_to_XTI(errno,&t_errno); return(-1); } } /* * Update XTI state tables * */ table(fd).event = XTI_BIND; /* T_BIND successful */ if (update_XTI_state(fd, -1, old_state) == -1) { t_errno = TOUTSTATE; return(-1); } if (buffer_overflow) { t_errno = TBUFOVFLW; return(-1); } return (0);}/* * T_CLOSE - close a transport endpoint */int t_close(fd)int fd;{ int status; struct linger ling_value; int old_state; 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 (table(fd).info.servtype != T_COTS && table(fd).info.servtype != T_COTS_ORD && table(fd).info.servtype != T_CLTS) { t_errno = TNOTSUPPORT; return(-1); } switch(table(fd).family) {#ifdef XTINSP case AF_DECnet: /* * Make sure we disable linger */ ling_value.l_onoff = 0; ling_value.l_linger = 1; status = setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *) &ling_value, sizeof(ling_value)); if (status == -1) { map_err_to_XTI(errno,&t_errno); return(-1); } break;#endif case AF_INET: ling_value.l_onoff = 1; ling_value.l_linger = 0; status = setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *) &ling_value, sizeof(ling_value)); if (status == -1) { map_err_to_XTI(errno,&t_errno); return(-1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -