- if ((res = read(fd, buf, toget - got)) < 0)
- {
- if (errno == EAGAIN)
- t_errno = TNODATA;
- else
- {
- TRC(fprintf(stderr, "Error on read.\n"));
- t_errno = TSYSERR;
- }
- return -1;
- }
- if (!res) /* peer closed network connection */
- {
- t_errno = TLOOK;
- cnt->event = T_DISCONNECT; /* is this correct ? ## */
- cnt->hlen = cnt->pending = 0;
- cnt->state = T_IDLE; /* this can't be correct ## */
- return 0;
- }
- buf += res;
+ if ((res = read(fd, buf, toget - got)) < 0)
+ {
+ if (errno == EAGAIN)
+ t_errno = TNODATA;
+ else
+ {
+ TRC(fprintf(stderr, "Error on read.\n"));
+ t_errno = TSYSERR;
+ }
+ return -1;
+ }
+ if (!res) /* peer closed network connection */
+ {
+ t_errno = TLOOK;
+ cnt->event = T_DISCONNECT; /* is this correct ? ## */
+ cnt->hlen = cnt->pending = 0;
+ cnt->state = T_IDLE; /* this can't be correct ## */
+ return 0;
+ }
+ buf += res;
- switch ((unsigned char)*p)
- {
- case TPDU_PARM_TSIZE:
- cnt->tsize = 1 << *(p + 2);
- break;
- case TPDU_PARM_CLDID:
- if (call)
- {
- if (*(p + 1) > TSEL_MAXLEN)
- {
- TRC(fprintf(stderr, "Called TSEL too long.\n"));
- t_errno = TSYSERR; /* Wrong.. ## */
- return -1;
- }
- *addrp = *(p + 1); /* length */
- memcpy(addrp + 1, p + 2, *(p + 1)); /* remote TSEL */
- addrp += *(p + 1); /* move past TSEL */
- }
- break;
- case TPDU_PARM_CLGID: break; /* ignoring this for now */
- default:
- TRC(fprintf(stderr, "Inoring CR parameter: %d\n",
- (unsigned char)*p));
- /* we silently ignore anything else */
- }
- p++;
- cnt->hlen -= (unsigned char) *p + 2;
- p += (unsigned char) *p + 1;
+ switch ((unsigned char)*p)
+ {
+ case TPDU_PARM_TSIZE:
+ cnt->tsize = 1 << *(p + 2);
+ break;
+ case TPDU_PARM_CLDID:
+ if (call)
+ {
+ if (*(p + 1) > TSEL_MAXLEN)
+ {
+ TRC(fprintf(stderr, "Called TSEL too long.\n"));
+ t_errno = TSYSERR; /* Wrong.. ## */
+ return -1;
+ }
+ *addrp = *(p + 1); /* length */
+ memcpy(addrp + 1, p + 2, *(p + 1)); /* remote TSEL */
+ addrp += *(p + 1); /* move past TSEL */
+ }
+ break;
+ case TPDU_PARM_CLGID: break; /* ignoring this for now */
+ default:
+ TRC(fprintf(stderr, "Inoring CR parameter: %d\n",
+ (unsigned char)*p));
+ /* we silently ignore anything else */
+ }
+ p++;
+ cnt->hlen -= (unsigned char) *p + 2;
+ p += (unsigned char) *p + 1;
- if (getpeername(fd, (struct sockaddr*) &peer, &len) < 0)
- {
- TRC(perror("getpeername()"));
- t_errno = TSYSERR;
- return -1;
- }
- *(addrp++) = sizeof(struct sockaddr_in);
- memcpy(addrp, &peer, sizeof(struct sockaddr_in));
- addrp += sizeof(struct sockaddr_in);
- call->addr.len = addrp - call->addr.buf + 1;
+ if (getpeername(fd, (struct sockaddr*) &peer, &len) < 0)
+ {
+ TRC(perror("getpeername()"));
+ t_errno = TSYSERR;
+ return -1;
+ }
+ *(addrp++) = sizeof(struct sockaddr_in);
+ memcpy(addrp, &peer, sizeof(struct sockaddr_in));
+ addrp += sizeof(struct sockaddr_in);
+ call->addr.len = addrp - call->addr.buf + 1;
- if (cnt->togo > 0) /* we have a partial TPDU on the wire */
- {
- TRC(fprintf(stderr, " writing continuation block (%d)\n",
- cnt->togo));
- if ((res = write(fd, buf, cnt->togo)) < 0)
- {
- if (errno == EAGAIN)
- {
- t_errno = TFLOW;
- return -1;
- }
- cnt->togo -= res;
- return res;
- }
- writ += res;
- cnt->togo = 0;
- TRC(fprintf(stderr, " wrote %d, total %d\n", res, writ));
- }
- else /* prepare and send (possibly partial) header */
- {
- towrite = nbytes - writ;
- if (towrite + 3 + 4 > cnt->tsize)
- towrite = cnt->tsize - (3 + 4); /* space for DATA header */
- rfc.version = RFC_VERSION;
- rfc.reserved = 0;
- rfc.len = htons(towrite + 4 + 3); /* RFC1006 length */
- rfc.hlen = 2;
- rfc.code = TPDU_CODE_DATA;
- if (flags & T_MORE || towrite + writ < nbytes)
- eot = 0;
- else
- eot = 1;
- rfc.suffix[0] = eot << 7; /* DATA EOT marker */
- if (cnt->togo < 0)
- head_offset = 7 + cnt->togo;
- else
- head_offset = 0;
- vec[0].iov_base = (caddr_t) (char*)&rfc + head_offset;
- vec[0].iov_len = 7 - head_offset;
- vec[1].iov_base = (caddr_t) buf + writ;
- vec[1].iov_len = towrite;
- TRC(fprintf(stderr, " sending beg of block (%d+%d)\n",
- 7 - head_offset, towrite));
- if ((res = writev(fd, vec, 2)) < 0)
- {
- TRC(fprintf(stderr, " write returned -1\n"));
- /* thwarted by flow control */
- if (errno == EAGAIN)
- {
- if (writ)
- return writ;
- else
- {
- t_errno = TFLOW;
- return -1;
- }
- }
- else
- t_errno = TSYSERR;
- return -1;
- }
- /* somewhat thwarted */
- else if (res < towrite + 7 - head_offset)
- {
- /*
- * Write came up short. We assume that this is a flow-
- * control thing, and return immediately. Maybe it'd
- * be better to take another loop, and generate an
- * actual EAGAIN from write?
- */
- TRC(fprintf(stderr, " write returned %d\n", res));
- if (res < 7 - head_offset) /* we didn't send a full header */
- {
- cnt->togo = -(7 - head_offset - res);
- t_errno = TFLOW;
- return -1;
- }
- else if ((res -= 7 - head_offset) < towrite) /* not all data */
- {
- cnt->togo = towrite - res;
- return nbytes - (writ + res);
- }
- }
- else /* whew... nonblocking I/O is hard work */
- {
- cnt->togo = 0;
- writ += res - (7 - head_offset);
- }
- }
+ if (cnt->togo > 0) /* we have a partial TPDU on the wire */
+ {
+ TRC(fprintf(stderr, " writing continuation block (%d)\n",
+ cnt->togo));
+ if ((res = write(fd, buf, cnt->togo)) < 0)
+ {
+ if (errno == EAGAIN)
+ {
+ t_errno = TFLOW;
+ return -1;
+ }
+ cnt->togo -= res;
+ return res;
+ }
+ writ += res;
+ cnt->togo = 0;
+ TRC(fprintf(stderr, " wrote %d, total %d\n", res, writ));
+ }
+ else /* prepare and send (possibly partial) header */
+ {
+ towrite = nbytes - writ;
+ if (towrite + 3 + 4 > cnt->tsize)
+ towrite = cnt->tsize - (3 + 4); /* space for DATA header */
+ rfc.version = RFC_VERSION;
+ rfc.reserved = 0;
+ rfc.len = htons(towrite + 4 + 3); /* RFC1006 length */
+ rfc.hlen = 2;
+ rfc.code = TPDU_CODE_DATA;
+ if (flags & T_MORE || towrite + writ < nbytes)
+ eot = 0;
+ else
+ eot = 1;
+ rfc.suffix[0] = eot << 7; /* DATA EOT marker */
+ if (cnt->togo < 0)
+ head_offset = 7 + cnt->togo;
+ else
+ head_offset = 0;
+ vec[0].iov_base = (caddr_t) (char*)&rfc + head_offset;
+ vec[0].iov_len = 7 - head_offset;
+ vec[1].iov_base = (caddr_t) buf + writ;
+ vec[1].iov_len = towrite;
+ TRC(fprintf(stderr, " sending beg of block (%d+%d)\n",
+ 7 - head_offset, towrite));
+ if ((res = writev(fd, vec, 2)) < 0)
+ {
+ TRC(fprintf(stderr, " write returned -1\n"));
+ /* thwarted by flow control */
+ if (errno == EAGAIN)
+ {
+ if (writ)
+ return writ;
+ else
+ {
+ t_errno = TFLOW;
+ return -1;
+ }
+ }
+ else
+ t_errno = TSYSERR;
+ return -1;
+ }
+ /* somewhat thwarted */
+ else if (res < towrite + 7 - head_offset)
+ {
+ /*
+ * Write came up short. We assume that this is a flow-
+ * control thing, and return immediately. Maybe it'd
+ * be better to take another loop, and generate an
+ * actual EAGAIN from write?
+ */
+ TRC(fprintf(stderr, " write returned %d\n", res));
+ if (res < 7 - head_offset) /* we didn't send a full header */
+ {
+ cnt->togo = -(7 - head_offset - res);
+ t_errno = TFLOW;
+ return -1;
+ }
+ else if ((res -= 7 - head_offset) < towrite) /* not all data */
+ {
+ cnt->togo = towrite - res;
+ return nbytes - (writ + res);
+ }
+ }
+ else /* whew... nonblocking I/O is hard work */
+ {
+ cnt->togo = 0;
+ writ += res - (7 - head_offset);
+ }
+ }
- if (!cnt->event)
- if (t_look_wait(fd, 0) <= 0)
- return -1;
- if (cnt->event != T_DATA)
- {
- t_errno = TLOOK;
- return -1;
- }
- if (cnt->hlen) /* beginning of block */
- {
- TRC(fprintf(stderr, " Beginning of TPDU\n"));
- if (cnt->hlen > 2)
- {
- TRC(fprintf(stderr, "We can't handle parameters to DATA\n"));
- t_errno = TSYSERR;
- return -1;
- }
- toget = cnt->pending;
- if (toget > nbytes - got)
- toget = nbytes - got;
- TRC(fprintf(stderr, " toget=%d\n", toget));
- vec[0].iov_base = (caddr_t) &dhead;
- vec[0].iov_len = 1;
- vec[1].iov_base = (caddr_t) buf + got;
- vec[1].iov_len = toget;
- if ((res = readv(fd, vec, 2)) < 0)
- {
- TRC(perror("readv()"));
- if (errno == EAGAIN)
- {
- if (got) /* we got some data in previous cycle */
- break;
- t_errno = TNODATA; /* no data */
- return -1;
- }
- t_errno = TSYSERR;
- return -1;
- }
- TRC(fprintf(stderr, " readv() returned %d\n", res));
- if (res == 0)
- {
- t_errno = TLOOK;
- cnt->event = T_DISCONNECT;
- return -1;
- }
- got += res - 1;
- cnt->eot_flag = (dhead.nr & DATA_EOT) >> 7;
- cnt->hlen = 0;
- cnt->pending -= got;
- TRC(fprintf(stderr, " Got total of %d octets, %d pending\n",
- got, cnt->pending));
- }
- else /* continuation */
- {
- TRC(fprintf(stderr, " Reading middle of TPDU\n"));
- toget = cnt->pending;
- if (toget > nbytes - got)
- toget = nbytes - got;
- TRC(fprintf(stderr, " toget=%d\n", toget));
- if ((res = read(fd, buf + got, toget)) < 0)
- {
- TRC(perror("read()"));
- if (errno == EAGAIN)
- {
- if (got) /* we got some data in previous cycle */
- break;
- t_errno = TNODATA; /* no data */
- return -1;
- }
- t_errno = TSYSERR;
- return -1;
- }
- TRC(fprintf(stderr, " read() returned %d\n", res));
- if (res == 0)
- {
- t_errno = TLOOK;
- cnt->event = T_DISCONNECT;
- return -1;
- }
- got += res;
- cnt->pending -= res;
- TRC(fprintf(stderr, " Got total of %d octets, %d pending\n",
- got, cnt->pending));
- }
- TRC(fprintf(stderr, " bottom of loop: pending=%d, got=%d\n",
- cnt->pending, got));
+ if (!cnt->event)
+ if (t_look_wait(fd, 0) <= 0)
+ return -1;
+ if (cnt->event != T_DATA)
+ {
+ t_errno = TLOOK;
+ return -1;
+ }
+ if (cnt->hlen) /* beginning of block */
+ {
+ TRC(fprintf(stderr, " Beginning of TPDU\n"));
+ if (cnt->hlen > 2)
+ {
+ TRC(fprintf(stderr, "We can't handle parameters to DATA\n"));
+ t_errno = TSYSERR;
+ return -1;
+ }
+ toget = cnt->pending;
+ if (toget > nbytes - got)
+ toget = nbytes - got;
+ TRC(fprintf(stderr, " toget=%d\n", toget));
+ vec[0].iov_base = (caddr_t) &dhead;
+ vec[0].iov_len = 1;
+ vec[1].iov_base = (caddr_t) buf + got;
+ vec[1].iov_len = toget;
+ if ((res = readv(fd, vec, 2)) < 0)
+ {
+ TRC(perror("readv()"));
+ if (errno == EAGAIN)
+ {
+ if (got) /* we got some data in previous cycle */
+ break;
+ t_errno = TNODATA; /* no data */
+ return -1;
+ }
+ t_errno = TSYSERR;
+ return -1;
+ }
+ TRC(fprintf(stderr, " readv() returned %d\n", res));
+ if (res == 0)
+ {
+ t_errno = TLOOK;
+ cnt->event = T_DISCONNECT;
+ return -1;
+ }
+ got += res - 1;
+ cnt->eot_flag = (dhead.nr & DATA_EOT) >> 7;
+ cnt->hlen = 0;
+ cnt->pending -= got;
+ TRC(fprintf(stderr, " Got total of %d octets, %d pending\n",
+ got, cnt->pending));
+ }
+ else /* continuation */
+ {
+ TRC(fprintf(stderr, " Reading middle of TPDU\n"));
+ toget = cnt->pending;
+ if (toget > nbytes - got)
+ toget = nbytes - got;
+ TRC(fprintf(stderr, " toget=%d\n", toget));
+ if ((res = read(fd, buf + got, toget)) < 0)
+ {
+ TRC(perror("read()"));
+ if (errno == EAGAIN)
+ {
+ if (got) /* we got some data in previous cycle */
+ break;
+ t_errno = TNODATA; /* no data */
+ return -1;
+ }
+ t_errno = TSYSERR;
+ return -1;
+ }
+ TRC(fprintf(stderr, " read() returned %d\n", res));
+ if (res == 0)
+ {
+ t_errno = TLOOK;
+ cnt->event = T_DISCONNECT;
+ return -1;
+ }
+ got += res;
+ cnt->pending -= res;
+ TRC(fprintf(stderr, " Got total of %d octets, %d pending\n",
+ got, cnt->pending));
+ }
+ TRC(fprintf(stderr, " bottom of loop: pending=%d, got=%d\n",
+ cnt->pending, got));
- cnt->qlen = req->qlen < MAX_QLEN ? req->qlen : MAX_QLEN;
- if (req->addr.len)
- {
- p = req->addr.buf;
- if (*p > TSEL_MAXLEN)
- {
- TRC(fprintf(stderr, "Tsel too large.\n"));
- t_errno = TBADADDR;
- return -1;
- }
- cnt->ltsel_len = *p;
- if (cnt->ltsel_len)
- memcpy(cnt->ltsel, p + 1, cnt->ltsel_len);
- p += cnt->ltsel_len + 1;
- if (*p < sizeof(addr))
- {
- TRC(fprintf(stderr, "W: No NSAP provided for local bind\n"));
- }
- else
- {
- memcpy(&addr, p + 1, sizeof(addr));
- got_addr = 1;
- }
- }
+ cnt->qlen = req->qlen < MAX_QLEN ? req->qlen : MAX_QLEN;
+ if (req->addr.len)
+ {
+ p = req->addr.buf;
+ if (*p > TSEL_MAXLEN)
+ {
+ TRC(fprintf(stderr, "Tsel too large.\n"));
+ t_errno = TBADADDR;
+ return -1;
+ }
+ cnt->ltsel_len = *p;
+ if (cnt->ltsel_len)
+ memcpy(cnt->ltsel, p + 1, cnt->ltsel_len);
+ p += cnt->ltsel_len + 1;
+ if (*p < sizeof(addr))
+ {
+ TRC(fprintf(stderr, "W: No NSAP provided for local bind\n"));
+ }
+ else
+ {
+ memcpy(&addr, p + 1, sizeof(addr));
+ got_addr = 1;
+ }
+ }
- discon->sequence = -1; /* TOFIX */
- discon->reason = chead.reason;
- TRC(fprintf(stderr, "Diconnect reason %d\n", chead.reason));
- if (cnt->pending > discon->udata.maxlen)
- {
- t_errno = TBUFOVFLW;
- return -1;
- }
- if (cnt->pending)
- {
- memcpy(discon->udata.buf, udata, cnt->pending);
- udata[cnt->pending] = '\0';
- TRC(fprintf(stderr, "Discon udata: '%s'\n", udata));
- }
- discon->udata.len = cnt->pending;
+ discon->sequence = -1; /* TOFIX */
+ discon->reason = chead.reason;
+ TRC(fprintf(stderr, "Diconnect reason %d\n", chead.reason));
+ if (cnt->pending > discon->udata.maxlen)
+ {
+ t_errno = TBUFOVFLW;
+ return -1;
+ }
+ if (cnt->pending)
+ {
+ memcpy(discon->udata.buf, udata, cnt->pending);
+ udata[cnt->pending] = '\0';
+ TRC(fprintf(stderr, "Discon udata: '%s'\n", udata));
+ }
+ discon->udata.len = cnt->pending;
- switch ((unsigned char)*p)
- {
- case TPDU_PARM_TSIZE:
- new->tsize = 1 << *(p + 2); /* we go with their max */
- break;
- case TPDU_PARM_CLDID: break; /* ignore */
- case TPDU_PARM_CLGID:
- if (addrp)
- {
- if (*(p + 1) > TSEL_MAXLEN)
- {
- TRC(fprintf(stderr, "Called TSEL too long.\n"));
- t_errno = TSYSERR; /* Wrong.. ## */
- return -1;
- }
- *addrp = *(p + 1); /* length */
- memcpy(addrp + 1, p + 2, *(p + 1)); /* remote TSEL */
- addrp += *(p + 1); /* move past TSEL */
- }
- break;
- /* we silently ignore preferred TPDU size and others */
- }
- p++;
- new->hlen -= (unsigned char) *p + 2;
- p += (unsigned char) *p + 1;
+ switch ((unsigned char)*p)
+ {
+ case TPDU_PARM_TSIZE:
+ new->tsize = 1 << *(p + 2); /* we go with their max */
+ break;
+ case TPDU_PARM_CLDID: break; /* ignore */
+ case TPDU_PARM_CLGID:
+ if (addrp)
+ {
+ if (*(p + 1) > TSEL_MAXLEN)
+ {
+ TRC(fprintf(stderr, "Called TSEL too long.\n"));
+ t_errno = TSYSERR; /* Wrong.. ## */
+ return -1;
+ }
+ *addrp = *(p + 1); /* length */
+ memcpy(addrp + 1, p + 2, *(p + 1)); /* remote TSEL */
+ addrp += *(p + 1); /* move past TSEL */
+ }
+ break;
+ /* we silently ignore preferred TPDU size and others */
+ }
+ p++;
+ new->hlen -= (unsigned char) *p + 2;
+ p += (unsigned char) *p + 1;
- TRC(fprintf(stderr, " Moving to new fd (%d)\n", resfd));
- if (res->state != T_IDLE || res->qlen)
- {
- TRC(fprintf(stderr, "Trying to move new assc. to bad fd.\n"));
- t_errno = TBADF;
- return -1;
- }
- dup2(newfd, resfd); /* closes resfd */
- close(newfd);
- control[resfd] = new;
- /* transfer local bindings from res */
- if (res->ltsel_len)
- memcpy(control[resfd]->ltsel, res->ltsel, res->ltsel_len);
- control[resfd]->ltsel_len = res->ltsel_len;
- free(res);
- res = control[resfd];
- listener->event = 0;
- listener->state = T_IDLE;
+ TRC(fprintf(stderr, " Moving to new fd (%d)\n", resfd));
+ if (res->state != T_IDLE || res->qlen)
+ {
+ TRC(fprintf(stderr, "Trying to move new assc. to bad fd.\n"));
+ t_errno = TBADF;
+ return -1;
+ }
+ dup2(newfd, resfd); /* closes resfd */
+ close(newfd);
+ control[resfd] = new;
+ /* transfer local bindings from res */
+ if (res->ltsel_len)
+ memcpy(control[resfd]->ltsel, res->ltsel, res->ltsel_len);
+ control[resfd]->ltsel_len = res->ltsel_len;
+ free(res);
+ res = control[resfd];
+ listener->event = 0;
+ listener->state = T_IDLE;
- TRC(fprintf(stderr, " Moving to listener fd\n"));
- for (i = 0; i < listener->qlen; i++)
- if (listener->oci[i] >= 0)
- {
- TRC(fprintf(stderr, "Still conn indications on listener\n"));
- t_errno = TBADF;
- return -1;
- }
- dup2(newfd, fd);
- close(newfd);
- control[fd] = new;
- if (listener->ltsel_len)
- memcpy(control[resfd]->ltsel, listener->ltsel, listener->ltsel_len);
- control[resfd]->ltsel_len = listener->ltsel_len;
- free(listener);
- res = control[resfd];
+ TRC(fprintf(stderr, " Moving to listener fd\n"));
+ for (i = 0; i < listener->qlen; i++)
+ if (listener->oci[i] >= 0)
+ {
+ TRC(fprintf(stderr, "Still conn indications on listener\n"));
+ t_errno = TBADF;
+ return -1;
+ }
+ dup2(newfd, fd);
+ close(newfd);
+ control[fd] = new;
+ if (listener->ltsel_len)
+ memcpy(control[resfd]->ltsel, listener->ltsel, listener->ltsel_len);
+ control[resfd]->ltsel_len = listener->ltsel_len;
+ free(listener);
+ res = control[resfd];