diff options
author | rob rob@31f1291d-b8d6-0310-a050-a5561fc1590b <rob rob@31f1291d-b8d6-0310-a050-a5561fc1590b@5417fbe8-f217-4b02-8779-1006273d7864> | 2004-07-19 14:08:30 +0000 |
---|---|---|
committer | rob rob@31f1291d-b8d6-0310-a050-a5561fc1590b <rob rob@31f1291d-b8d6-0310-a050-a5561fc1590b@5417fbe8-f217-4b02-8779-1006273d7864> | 2004-07-19 14:08:30 +0000 |
commit | a1479a87757fb5e9b48f3c8bb5dd9cc247406f1a (patch) | |
tree | 06d23a51082a398c512ed8f1e39bdac60d4dd658 /sockutil.c | |
parent | 7fffea77edbe72cd66f7a55f41a3966204f9cf86 (diff) |
BUILD : 1.7.4 (264) BUGS : N/A NOTES : Switched to autoconf - try to commit part 1
git-svn-id: svn://svn.anope.org/anope/trunk@264 31f1291d-b8d6-0310-a050-a5561fc1590b
git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@169 5417fbe8-f217-4b02-8779-1006273d7864
Diffstat (limited to 'sockutil.c')
-rw-r--r-- | sockutil.c | 549 |
1 files changed, 0 insertions, 549 deletions
diff --git a/sockutil.c b/sockutil.c deleted file mode 100644 index 2ce091c2d..000000000 --- a/sockutil.c +++ /dev/null @@ -1,549 +0,0 @@ -/* Socket utility routines. - * - * (C) 2003 Anope Team - * Contact us at info@anope.org - * - * Please read COPYING and README for furhter details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * $Id$ - * - */ - -#include "services.h" - -/*************************************************************************/ -/*************************************************************************/ - -/* Read from a socket with buffering. */ - -static char read_netbuf[NET_BUFSIZE]; -static char *read_curpos = read_netbuf; /* Next byte to return */ -static char *read_bufend = read_netbuf; /* Next position for data from socket */ -static char *const read_buftop = read_netbuf + NET_BUFSIZE; -int32 total_read = 0; - - -/* Return amount of data in read buffer. */ - -int32 read_buffer_len() -{ - if (read_bufend >= read_curpos) - return read_bufend - read_curpos; - else - return (read_bufend + NET_BUFSIZE) - read_curpos; -} - - -/* Read data. */ - -static int buffered_read(int fd, char *buf, int len) -{ - int nread, left = len; - fd_set fds; - struct timeval tv = { 0, 0 }; - int errno_save = errno; - - if (fd < 0) { - errno = 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 = read(fd, read_bufend, maxread); - errno_save = errno; - 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); - } - errno = errno_save; - return len - left; -} - -/* Optimized version of the above for reading a single character; returns - * the character in an int or EOF, like fgetc(). */ - -static int buffered_read_one(int 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 = errno; - - if (fd < 0) { - errno = 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 = read(fd, read_bufend, maxread); - errno_save = errno; - 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); - errno = 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; -} - -/*************************************************************************/ - -/* Write to a socket with buffering. Note that this assumes only one - * socket. */ - -static char write_netbuf[NET_BUFSIZE]; -static char *write_curpos = write_netbuf; /* Next byte to write to socket */ -static char *write_bufend = write_netbuf; /* Next position for data to socket */ -static char *const write_buftop = write_netbuf + NET_BUFSIZE; -static int write_fd = -1; -int32 total_written; - - -/* Return amount of data in write buffer. */ - -int32 write_buffer_len() -{ - if (write_bufend >= write_curpos) - return write_bufend - write_curpos; - else - return (write_bufend + NET_BUFSIZE) - write_curpos; -} - - -/* Helper routine to try and write up to one chunk of data from the buffer - * to the socket. Return how much was written. */ - -static int flush_write_buffer(int wait) -{ - fd_set fds; - struct timeval tv = { 0, 0 }; - int errno_save = errno; - - if (write_bufend == write_curpos || write_fd == -1) - return 0; - FD_ZERO(&fds); - FD_SET(write_fd, &fds); - if (select(write_fd + 1, 0, &fds, 0, wait ? NULL : &tv) == 1) { - int maxwrite, nwritten; - if (write_curpos > write_bufend) /* wrapped around? */ - maxwrite = write_buftop - write_curpos; - else if (write_bufend == write_netbuf) - maxwrite = write_buftop - write_curpos - 1; - else - maxwrite = write_bufend - write_curpos; - nwritten = write(write_fd, write_curpos, maxwrite); - errno_save = errno; - if (debug >= 3) - alog("debug: flush_write_buffer wanted %d, got %d", maxwrite, - nwritten); - if (nwritten > 0) { - write_curpos += nwritten; - if (write_curpos == write_buftop) - write_curpos = write_netbuf; - total_written += nwritten; - return nwritten; - } - } - errno = errno_save; - return 0; -} - - -/* Write data. */ - -static int buffered_write(int fd, char *buf, int len) -{ - int nwritten, left = len; - int errno_save = errno; - - if (fd < 0) { - errno = EBADF; - return -1; - } - write_fd = fd; - - while (left > 0) { - - /* Don't try putting anything in the buffer if it's full. */ - if (write_curpos != write_bufend + 1 && - (write_curpos != write_netbuf - || write_bufend != write_buftop - 1)) { - /* See if we need to write up to the end of the buffer. */ - if (write_bufend + left >= write_buftop - && write_curpos <= write_bufend) { - nwritten = write_buftop - write_bufend; - memcpy(write_bufend, buf, nwritten); - buf += nwritten; - left -= nwritten; - write_bufend = write_netbuf; - } - /* Now we can copy a single chunk to write_bufend. */ - if (write_curpos > write_bufend - && write_curpos - write_bufend - 1 < left) - nwritten = write_curpos - write_bufend - 1; - else - nwritten = left; - if (nwritten) { - memcpy(write_bufend, buf, nwritten); - buf += nwritten; - left -= nwritten; - write_bufend += nwritten; - } - } - - /* Now write to the socket as much as we can. */ - if (write_curpos == write_bufend + 1 || - (write_curpos == write_netbuf - && write_bufend == write_buftop - 1)) - flush_write_buffer(1); - else - flush_write_buffer(0); - errno_save = errno; - if (write_curpos == write_bufend + 1 || - (write_curpos == write_netbuf - && write_bufend == write_buftop - 1)) { - /* Write failed on full buffer */ - break; - } - } - - if (debug >= 4) { - alog("debug: buffered_write(%d,%p,%d) returning %d", - fd, buf, len, len - left); - } - errno = errno_save; - return len - left; -} - -/* Optimized version of the above for writing a single character; returns - * the character in an int or EOF, like fputc(). Commented out because it - * isn't currently used. */ - -#if 0 -static int buffered_write_one(int c, int fd) -{ - struct timeval tv = { 0, 0 }; - - if (fd < 0) { - errno = EBADF; - return -1; - } - write_fd = fd; - - /* Try to flush the buffer if it's full. */ - if (write_curpos == write_bufend + 1 || - (write_curpos == write_netbuf - && write_bufend == write_buftop - 1)) { - flush_write_buffer(1); - if (write_curpos == write_bufend + 1 || - (write_curpos == write_netbuf - && write_bufend == write_buftop - 1)) { - /* Write failed */ - if (debug >= 4) - alog("debug: buffered_write_one(%d) returning %d", fd, - EOF); - return EOF; - } - } - - /* Write the character. */ - *write_bufend++ = c; - if (write_bufend == write_buftop) - write_bufend = write_netbuf; - - /* Move it to the socket if we can. */ - flush_write_buffer(0); - - if (debug >= 4) - alog("debug: buffered_write_one(%d) returning %d", fd, c); - return (int) c & 0xFF; -} -#endif /* 0 */ - -/*************************************************************************/ -/*************************************************************************/ - -static int lastchar = EOF; - -int sgetc(int s) -{ - int c; - - if (lastchar != EOF) { - c = lastchar; - lastchar = EOF; - return c; - } - return buffered_read_one(s); -} - -int sungetc(int c, int s) -{ - return lastchar = c; -} - -/*************************************************************************/ - -/* If connection was broken, return NULL. If the read timed out, return - * (char *)-1. - */ - -char *sgets(char *buf, int len, int s) -{ - int c = 0; - struct timeval tv; - fd_set fds; - char *ptr = buf; - - if (len == 0) - return NULL; - FD_SET(s, &fds); - tv.tv_sec = ReadTimeout; - tv.tv_usec = 0; - while (read_buffer_len() == 0 && - (c = select(s + 1, &fds, NULL, NULL, &tv)) < 0) { - if (errno != EINTR) - break; - } - if (read_buffer_len() == 0 && c == 0) - return (char *) -1; - c = sgetc(s); - while (--len && (*ptr++ = c) != '\n' && (c = sgetc(s)) >= 0); - if (c < 0) - return NULL; - *ptr = 0; - return buf; -} - -/*************************************************************************/ - -/* sgets2: Read a line of text from a socket, and strip newline and - * carriage return characters from the end of the line. - */ - -char *sgets2(char *buf, int len, int s) -{ - char *str = sgets(buf, len, s); - - if (!str || str == (char *) -1) - return str; - str = buf + strlen(buf) - 1; - if (*str == '\n') - *str-- = 0; - if (*str == '\r') - *str = 0; - return buf; -} - -/*************************************************************************/ - -/* Read from a socket. (Use this instead of read() because it has - * buffering.) */ - -int sread(int s, char *buf, int len) -{ - return buffered_read(s, buf, len); -} - -/*************************************************************************/ - -int sputs(char *str, int s) -{ - return buffered_write(s, str, strlen(str)); -} - -/*************************************************************************/ - -int sockprintf(int s, char *fmt, ...) -{ - va_list args; - char buf[16384]; /* Really huge, to try and avoid truncation */ - - va_start(args, fmt); - return buffered_write(s, buf, vsnprintf(buf, sizeof(buf), fmt, args)); -} - -/*************************************************************************/ -/*************************************************************************/ - -#if !HAVE_GETHOSTBYNAME - -/* Translate an IP dotted-quad address to a 4-byte character string. - * Return NULL if the given string is not in dotted-quad format. - */ - -static char *pack_ip(const char *ipaddr) -{ - static char ipbuf[4]; - int tmp[4], i; - - if (sscanf(ipaddr, "%d.%d.%d.%d", &tmp[0], &tmp[1], &tmp[2], &tmp[3]) - != 4) - return NULL; - for (i = 0; i < 4; i++) { - if (tmp[i] < 0 || tmp[i] > 255) - return NULL; - ipbuf[i] = tmp[i]; - } - return ipbuf; -} - -#endif - -/*************************************************************************/ - -/* lhost/lport specify the local side of the connection. If they are not - * given (lhost==NULL, lport==0), then they are left free to vary. - */ - -int conn(const char *host, int port, const char *lhost, int lport) -{ -#if HAVE_GETHOSTBYNAME - struct hostent *hp; -#else - char *addr; -#endif - struct sockaddr_in sa, lsa; - int sock; - - memset(&lsa, 0, sizeof(lsa)); - if (lhost) { -#if HAVE_GETHOSTBYNAME - if ((hp = gethostbyname(lhost)) != NULL) { - memcpy((char *) &lsa.sin_addr, hp->h_addr, hp->h_length); - lsa.sin_family = hp->h_addrtype; -#else - if (addr = pack_ip(lhost)) { - memcpy((char *) &lsa.sin_addr, addr, 4); - lsa.sin_family = AF_INET; -#endif - } else { - lhost = NULL; - } - } - if (lport) - lsa.sin_port = htons((unsigned short) lport); - - memset(&sa, 0, sizeof(sa)); -#if HAVE_GETHOSTBYNAME - if (!(hp = gethostbyname(host))) - return -1; - memcpy((char *) &sa.sin_addr, hp->h_addr, hp->h_length); - sa.sin_family = hp->h_addrtype; -#else - if (!(addr = pack_ip(host))) { - alog("conn(): `%s' is not a valid IP address", host); - errno = EINVAL; - return -1; - } - memcpy((char *) &sa.sin_addr, addr, 4); - sa.sin_family = AF_INET; -#endif - sa.sin_port = htons((unsigned short) port); - - if ((sock = socket(sa.sin_family, SOCK_STREAM, 0)) < 0) - return -1; - - if ((lhost || lport) - && bind(sock, (struct sockaddr *) &lsa, sizeof(lsa)) < 0) { - int errno_save = errno; - close(sock); - errno = errno_save; - return -1; - } - - if (connect(sock, (struct sockaddr *) &sa, sizeof(sa)) < 0) { - int errno_save = errno; - close(sock); - errno = errno_save; - return -1; - } - - return sock; -} - -/*************************************************************************/ - -void disconn(int s) -{ - shutdown(s, 2); - close(s); -} |