/* @configure_input@ */ /* ** Copyright 2000-2004 University of Illinois Board of Trustees ** Copyright 2000-2004 Mark D. Roth ** All rights reserved. ** ** @NETIO_PREFIX@_netio_recv.c - NETIO data receive code ** ** Mark D. Roth */ #include <@NETIO_PREFIX@_netio_internal.h> #include #include #ifdef STDC_HEADERS # include # include # include #endif #ifdef HAVE_UNISTD_H # include #endif /* netio_read() - read a block of data */ ssize_t @NETIO_PREFIX@_netio_read(NETIO *nio, time_t timeout, char *buf, size_t bufsize) { int i; ssize_t sz; i = @NETIO_PREFIX@_netio_wait(nio, 0, timeout); if (i == 1) { errno = ETIMEDOUT; return -1; } if (i == -1) return -1; sz = read(nio->n_fd, buf, bufsize); #ifdef DEBUG printf(" @NETIO_PREFIX@_netio_read(): read %ld bytes\n", (long)sz); #endif /* set EOF flag if we catch EOF */ if (sz == 0) nio->n_eof = 1; return sz; } #define NIO_FREE_LEN(nio) \ (((nio)->n_bufsize - 1) - ((nio)->n_writep - (nio)->n_buf)) /* netio_read_line() - read and parse a line from the server. */ ssize_t @NETIO_PREFIX@_netio_read_line(NETIO *nio, time_t timeout, char *buf, size_t bufsize) { int i; char *nextp; ssize_t sz, retlen; #ifdef DEBUG printf("==> @NETIO_PREFIX@_netio_read_line(nio=0x%lx " "{ n_fd=%d, n_buf=0x%lx, n_writep=0x%lx }, " "timeout=%lu, buf=0x%lx, bufsize=%lu)\n", nio, nio->n_fd, nio->n_buf, nio->n_writep, (unsigned long)timeout, buf, (unsigned long)bufsize); #endif /* ** keep reading until we have a line in the buffer */ while ((nextp = strpbrk(nio->n_buf, "\r\n")) == NULL) { sz = @NETIO_PREFIX@_netio_read(nio, timeout, nio->n_writep, NIO_FREE_LEN(nio)); if (sz <= 0) return sz; nio->n_writep += sz; *(nio->n_writep) = '\0'; } #ifdef DEBUG printf(" @NETIO_PREFIX@_netio_read_line(): " "writep=buf[%d], buf=\"%s\"\n", nio->n_writep - nio->n_buf, nio->n_buf); #endif /* ** FIXME: need to skip leading "\r" or "\n" in case the "\r\n" ** pair gets split between calls to read() */ /* chop off the first line and set nextp to point to the next line */ *nextp++ = '\0'; while (*nextp == '\r' || *nextp == '\n') nextp++; /* call receive hook, if set */ if (nio->n_recvhook != NULL) (*(nio->n_recvhook))(nio->n_buf, nio->n_hook_handle, nio->n_hook_data); /* copy line to caller-suppied buffer */ retlen = strlcpy(buf, nio->n_buf, bufsize); /* ** move remaining data to beginning of buffer ** and update write pointer */ sz = nio->n_writep - nextp; memmove(nio->n_buf, nextp, sz + 1); nio->n_writep = nio->n_buf + sz; return retlen; }