/* Read a line of text */ int smtp_read(char *buf, int len) { int result; memset(buf, 0, len); result = ano_sockread(smail.sock, buf, len); if (result == SOCKET_ERROR) ano_sockclose(smail.sock); return result; }
/** * Optimized version of the above for reading a single character; returns * the character in an int or EOF, like fgetc(). * @param fd File Pointer * @return int */ static int buffered_read_one(ano_socket_t fd) { int nread; fd_set fds; struct timeval tv = { 0, 0 }; char c; struct timeval *tvptr = (read_bufend == read_curpos ? NULL : &tv); int errno_save = ano_sockgeterr(); if (fd < 0) { ano_sockseterr(SOCKERR_EBADF); return -1; } FD_ZERO(&fds); FD_SET(fd, &fds); while (read_bufend != read_curpos - 1 && !(read_curpos == read_netbuf && read_bufend == read_buftop - 1) && select(fd + 1, &fds, 0, 0, tvptr) == 1) { int maxread; tvptr = &tv; /* don't wait next time */ if (read_bufend < read_curpos) /* wrapped around? */ maxread = (read_curpos - 1) - read_bufend; else if (read_curpos == read_netbuf) maxread = read_buftop - read_bufend - 1; else maxread = read_buftop - read_bufend; nread = ano_sockread(fd, read_bufend, maxread); errno_save = ano_sockgeterr(); if (debug >= 3) alog("debug: buffered_read_one wanted %d, got %d", maxread, nread); if (nread <= 0) break; read_bufend += nread; if (read_bufend == read_buftop) read_bufend = read_netbuf; } if (read_curpos == read_bufend) { /* No more data on socket */ if (debug >= 4) alog("debug: buffered_read_one(%d) returning %d", fd, EOF); ano_sockseterr(errno_save); return EOF; } c = *read_curpos++; if (read_curpos == read_buftop) read_curpos = read_netbuf; total_read++; if (debug >= 4) alog("debug: buffered_read_one(%d) returning %d", fd, c); return (int) c & 0xFF; }
/** * Read data. * @param fd File Pointer * @param buf Buffer * @param int Length of buffer * @return int */ static int buffered_read(ano_socket_t fd, char *buf, int len) { int nread, left = len; fd_set fds; struct timeval tv = { 0, 0 }; int errno_save = ano_sockgeterr(); if (fd < 0) { ano_sockseterr(SOCKERR_EBADF); return -1; } while (left > 0) { struct timeval *tvptr = (read_bufend == read_curpos ? NULL : &tv); FD_ZERO(&fds); FD_SET(fd, &fds); while (read_bufend != read_curpos - 1 && !(read_curpos == read_netbuf && read_bufend == read_buftop - 1) && select(fd + 1, &fds, 0, 0, tvptr) == 1) { int maxread; tvptr = &tv; /* don't wait next time */ if (read_bufend < read_curpos) /* wrapped around? */ maxread = (read_curpos - 1) - read_bufend; else if (read_curpos == read_netbuf) maxread = read_buftop - read_bufend - 1; else maxread = read_buftop - read_bufend; nread = ano_sockread(fd, read_bufend, maxread); errno_save = ano_sockgeterr(); if (debug >= 3) alog("debug: buffered_read wanted %d, got %d", maxread, nread); if (nread <= 0) break; read_bufend += nread; if (read_bufend == read_buftop) read_bufend = read_netbuf; } if (read_curpos == read_bufend) /* No more data on socket */ break; /* See if we can gobble up the rest of the buffer. */ if (read_curpos + left >= read_buftop && read_bufend < read_curpos) { nread = read_buftop - read_curpos; memcpy(buf, read_curpos, nread); buf += nread; left -= nread; read_curpos = read_netbuf; } /* Now everything we need is in a single chunk at read_curpos. */ if (read_bufend > read_curpos && read_bufend - read_curpos < left) nread = read_bufend - read_curpos; else nread = left; if (nread) { memcpy(buf, read_curpos, nread); buf += nread; left -= nread; read_curpos += nread; } } total_read += len - left; if (debug >= 4) { alog("debug: buffered_read(%d,%p,%d) returning %d", fd, buf, len, len - left); } ano_sockseterr(errno_save); return len - left; }