00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "services.h"
00016
00017
00018
00019 static char read_netbuf[NET_BUFSIZE];
00020 static char *read_curpos = read_netbuf;
00021 static char *read_bufend = read_netbuf;
00022 static char *const read_buftop = read_netbuf + NET_BUFSIZE;
00023 int32 total_read = 0;
00024 static char write_netbuf[NET_BUFSIZE];
00025 static char *write_curpos = write_netbuf;
00026 static char *write_bufend = write_netbuf;
00027 static char *const write_buftop = write_netbuf + NET_BUFSIZE;
00028 static int write_fd = -1;
00029 int32 total_written;
00030 static int lastchar = EOF;
00031
00032
00033
00038 int32 read_buffer_len()
00039 {
00040 if (read_bufend >= read_curpos) {
00041 return read_bufend - read_curpos;
00042 } else {
00043 return (read_bufend + NET_BUFSIZE) - read_curpos;
00044 }
00045 }
00046
00047
00048
00056 static int buffered_read(ano_socket_t fd, char *buf, int len)
00057 {
00058 int nread, left = len;
00059 fd_set fds;
00060 struct timeval tv = { 0, 0 };
00061 int errno_save = ano_sockgeterr();
00062
00063 if (fd < 0) {
00064 ano_sockseterr(SOCKERR_EBADF);
00065 return -1;
00066 }
00067 while (left > 0) {
00068 struct timeval *tvptr = (read_bufend == read_curpos ? NULL : &tv);
00069 FD_ZERO(&fds);
00070 FD_SET(fd, &fds);
00071 while (read_bufend != read_curpos - 1
00072 && !(read_curpos == read_netbuf
00073 && read_bufend == read_buftop - 1)
00074 && select(fd + 1, &fds, 0, 0, tvptr) == 1) {
00075 int maxread;
00076 tvptr = &tv;
00077 if (read_bufend < read_curpos)
00078 maxread = (read_curpos - 1) - read_bufend;
00079 else if (read_curpos == read_netbuf)
00080 maxread = read_buftop - read_bufend - 1;
00081 else
00082 maxread = read_buftop - read_bufend;
00083 nread = ano_sockread(fd, read_bufend, maxread);
00084 errno_save = ano_sockgeterr();
00085 if (debug >= 3)
00086 alog("debug: buffered_read wanted %d, got %d", maxread,
00087 nread);
00088 if (nread <= 0)
00089 break;
00090 read_bufend += nread;
00091 if (read_bufend == read_buftop)
00092 read_bufend = read_netbuf;
00093 }
00094 if (read_curpos == read_bufend)
00095 break;
00096
00097 if (read_curpos + left >= read_buftop && read_bufend < read_curpos) {
00098 nread = read_buftop - read_curpos;
00099 memcpy(buf, read_curpos, nread);
00100 buf += nread;
00101 left -= nread;
00102 read_curpos = read_netbuf;
00103 }
00104
00105 if (read_bufend > read_curpos && read_bufend - read_curpos < left)
00106 nread = read_bufend - read_curpos;
00107 else
00108 nread = left;
00109 if (nread) {
00110 memcpy(buf, read_curpos, nread);
00111 buf += nread;
00112 left -= nread;
00113 read_curpos += nread;
00114 }
00115 }
00116 total_read += len - left;
00117 if (debug >= 4) {
00118 alog("debug: buffered_read(%d,%p,%d) returning %d",
00119 fd, buf, len, len - left);
00120 }
00121 ano_sockseterr(errno_save);
00122 return len - left;
00123 }
00124
00125
00126
00133 static int buffered_read_one(ano_socket_t fd)
00134 {
00135 int nread;
00136 fd_set fds;
00137 struct timeval tv = { 0, 0 };
00138 char c;
00139 struct timeval *tvptr = (read_bufend == read_curpos ? NULL : &tv);
00140 int errno_save = ano_sockgeterr();
00141
00142 if (fd < 0) {
00143 ano_sockseterr(SOCKERR_EBADF);
00144 return -1;
00145 }
00146 FD_ZERO(&fds);
00147 FD_SET(fd, &fds);
00148 while (read_bufend != read_curpos - 1
00149 && !(read_curpos == read_netbuf
00150 && read_bufend == read_buftop - 1)
00151 && select(fd + 1, &fds, 0, 0, tvptr) == 1) {
00152 int maxread;
00153 tvptr = &tv;
00154 if (read_bufend < read_curpos)
00155 maxread = (read_curpos - 1) - read_bufend;
00156 else if (read_curpos == read_netbuf)
00157 maxread = read_buftop - read_bufend - 1;
00158 else
00159 maxread = read_buftop - read_bufend;
00160 nread = ano_sockread(fd, read_bufend, maxread);
00161 errno_save = ano_sockgeterr();
00162 if (debug >= 3)
00163 alog("debug: buffered_read_one wanted %d, got %d", maxread,
00164 nread);
00165 if (nread <= 0)
00166 break;
00167 read_bufend += nread;
00168 if (read_bufend == read_buftop)
00169 read_bufend = read_netbuf;
00170 }
00171 if (read_curpos == read_bufend) {
00172 if (debug >= 4)
00173 alog("debug: buffered_read_one(%d) returning %d", fd, EOF);
00174 ano_sockseterr(errno_save);
00175 return EOF;
00176 }
00177 c = *read_curpos++;
00178 if (read_curpos == read_buftop)
00179 read_curpos = read_netbuf;
00180 total_read++;
00181 if (debug >= 4)
00182 alog("debug: buffered_read_one(%d) returning %d", fd, c);
00183 return (int) c & 0xFF;
00184 }
00185
00186
00187
00192 int32 write_buffer_len()
00193 {
00194 if (write_bufend >= write_curpos) {
00195 return write_bufend - write_curpos;
00196 } else {
00197 return (write_bufend + NET_BUFSIZE) - write_curpos;
00198 }
00199 }
00200
00201
00202
00209 static int flush_write_buffer(int wait)
00210 {
00211 fd_set fds;
00212 struct timeval tv = { 0, 0 };
00213 int errno_save = ano_sockgeterr();
00214
00215 if (write_bufend == write_curpos || write_fd == -1)
00216 return 0;
00217 FD_ZERO(&fds);
00218 FD_SET(write_fd, &fds);
00219 if (select(write_fd + 1, 0, &fds, 0, wait ? NULL : &tv) == 1) {
00220 int maxwrite, nwritten;
00221 if (write_curpos > write_bufend)
00222 maxwrite = write_buftop - write_curpos;
00223 else if (write_bufend == write_netbuf)
00224 maxwrite = write_buftop - write_curpos - 1;
00225 else
00226 maxwrite = write_bufend - write_curpos;
00227 nwritten = ano_sockwrite(write_fd, write_curpos, maxwrite);
00228 errno_save = ano_sockgeterr();
00229 if (debug >= 3)
00230 alog("debug: flush_write_buffer wanted %d, got %d", maxwrite,
00231 nwritten);
00232 if (nwritten > 0) {
00233 write_curpos += nwritten;
00234 if (write_curpos == write_buftop)
00235 write_curpos = write_netbuf;
00236 total_written += nwritten;
00237 return nwritten;
00238 }
00239 }
00240 ano_sockseterr(errno_save);
00241 return 0;
00242 }
00243
00244
00245
00253 static int buffered_write(ano_socket_t fd, char *buf, int len)
00254 {
00255 int nwritten, left = len;
00256 int errno_save = ano_sockgeterr();
00257
00258 if (fd < 0) {
00259 errno = EBADF;
00260 return -1;
00261 }
00262 write_fd = fd;
00263
00264 while (left > 0) {
00265
00266
00267 if (write_curpos != write_bufend + 1 &&
00268 (write_curpos != write_netbuf
00269 || write_bufend != write_buftop - 1)) {
00270
00271 if (write_bufend + left >= write_buftop
00272 && write_curpos <= write_bufend) {
00273 nwritten = write_buftop - write_bufend;
00274 memcpy(write_bufend, buf, nwritten);
00275 buf += nwritten;
00276 left -= nwritten;
00277 write_bufend = write_netbuf;
00278 }
00279
00280 if (write_curpos > write_bufend
00281 && write_curpos - write_bufend - 1 < left)
00282 nwritten = write_curpos - write_bufend - 1;
00283 else
00284 nwritten = left;
00285 if (nwritten) {
00286 memcpy(write_bufend, buf, nwritten);
00287 buf += nwritten;
00288 left -= nwritten;
00289 write_bufend += nwritten;
00290 }
00291 }
00292
00293
00294 if (write_curpos == write_bufend + 1 ||
00295 (write_curpos == write_netbuf
00296 && write_bufend == write_buftop - 1))
00297 flush_write_buffer(1);
00298 else
00299 flush_write_buffer(0);
00300 errno_save = errno;
00301 if (write_curpos == write_bufend + 1 ||
00302 (write_curpos == write_netbuf
00303 && write_bufend == write_buftop - 1)) {
00304
00305 break;
00306 }
00307 }
00308
00309 if (debug >= 4) {
00310 alog("debug: buffered_write(%d,%p,%d) returning %d",
00311 fd, buf, len, len - left);
00312 }
00313 ano_sockseterr(errno_save);
00314 return len - left;
00315 }
00316
00317
00318
00319
00328 #if 0
00329 static int buffered_write_one(int c, ano_socket_t fd)
00330 {
00331 struct timeval tv = { 0, 0 };
00332
00333 if (fd < 0) {
00334 ano_sockseterr(SOCKERR_EBADF);
00335 return -1;
00336 }
00337 write_fd = fd;
00338
00339
00340 if (write_curpos == write_bufend + 1 ||
00341 (write_curpos == write_netbuf
00342 && write_bufend == write_buftop - 1)) {
00343 flush_write_buffer(1);
00344 if (write_curpos == write_bufend + 1 ||
00345 (write_curpos == write_netbuf
00346 && write_bufend == write_buftop - 1)) {
00347
00348 if (debug >= 4)
00349 alog("debug: buffered_write_one(%d) returning %d", fd,
00350 EOF);
00351 return EOF;
00352 }
00353 }
00354
00355
00356 *write_bufend++ = c;
00357 if (write_bufend == write_buftop)
00358 write_bufend = write_netbuf;
00359
00360
00361 flush_write_buffer(0);
00362
00363 if (debug >= 4)
00364 alog("debug: buffered_write_one(%d) returning %d", fd, c);
00365 return (int) c & 0xFF;
00366 }
00367 #endif
00368
00369
00370
00376 int sgetc(ano_socket_t s)
00377 {
00378 int c;
00379
00380 if (lastchar != EOF) {
00381 c = lastchar;
00382 lastchar = EOF;
00383 return c;
00384 }
00385 return buffered_read_one(s);
00386 }
00387
00388
00389
00396 int sungetc(int c, int s)
00397 {
00398 return lastchar = c;
00399 }
00400
00401
00402
00411 char *sgets(char *buf, int len, ano_socket_t s)
00412 {
00413 int c = 0;
00414 struct timeval tv;
00415 fd_set fds;
00416 char *ptr = buf;
00417
00418 flush_write_buffer(0);
00419
00420 if (len == 0)
00421 return NULL;
00422 FD_SET(s, &fds);
00423 tv.tv_sec = ReadTimeout;
00424 tv.tv_usec = 0;
00425 while (read_buffer_len() == 0 &&
00426 (c = select(s + 1, &fds, NULL, NULL, &tv)) < 0) {
00427 if (ano_sockgeterr() != EINTR)
00428 break;
00429 flush_write_buffer(0);
00430 }
00431 if (read_buffer_len() == 0 && c == 0)
00432 return (char *) -1;
00433 c = sgetc(s);
00434 while (--len && (*ptr++ = c) != '\n' && (c = sgetc(s)) >= 0);
00435 if (c < 0)
00436 return NULL;
00437 *ptr = 0;
00438 return buf;
00439 }
00440
00441
00442
00451 char *sgets2(char *buf, int len, ano_socket_t s)
00452 {
00453 char *str = sgets(buf, len, s);
00454
00455 if (!str || str == (char *) -1)
00456 return str;
00457 str = buf + strlen(buf) - 1;
00458 if (*str == '\n')
00459 *str-- = 0;
00460 if (*str == '\r')
00461 *str = 0;
00462 return buf;
00463 }
00464
00465
00466
00475 int sread(ano_socket_t s, char *buf, int len)
00476 {
00477 return buffered_read(s, buf, len);
00478 }
00479
00480
00481
00488 int sputs(char *str, ano_socket_t s)
00489 {
00490 return buffered_write(s, str, strlen(str));
00491 }
00492
00493
00494
00502 int sockprintf(ano_socket_t s, char *fmt, ...)
00503 {
00504 va_list args;
00505 char buf[16384];
00506 int value;
00507
00508 va_start(args, fmt);
00509 value = buffered_write(s, buf, vsnprintf(buf, sizeof(buf), fmt, args));
00510 va_end(args);
00511 return value;
00512 }
00513
00514
00515
00516 #if !HAVE_GETHOSTBYNAME
00517
00524 static char *pack_ip(const char *ipaddr)
00525 {
00526 static char ipbuf[4];
00527 int tmp[4], i;
00528
00529 if (sscanf(ipaddr, "%d.%d.%d.%d", &tmp[0], &tmp[1], &tmp[2], &tmp[3])
00530 != 4)
00531 return NULL;
00532 for (i = 0; i < 4; i++) {
00533 if (tmp[i] < 0 || tmp[i] > 255)
00534 return NULL;
00535 ipbuf[i] = tmp[i];
00536 }
00537 return ipbuf;
00538 }
00539
00540 #endif
00541
00542
00543
00553 int conn(const char *host, int port, const char *lhost, int lport)
00554 {
00555 #if HAVE_GETHOSTBYNAME
00556 struct hostent *hp;
00557 #else
00558 char *addr;
00559 #endif
00560 struct sockaddr_in sa, lsa;
00561 ano_socket_t sock;
00562
00563 memset(&lsa, 0, sizeof(lsa));
00564 if (lhost) {
00565 #if HAVE_GETHOSTBYNAME
00566 if ((hp = gethostbyname(lhost)) != NULL) {
00567 memcpy((char *) &lsa.sin_addr, hp->h_addr, hp->h_length);
00568 lsa.sin_family = hp->h_addrtype;
00569 #else
00570 if (addr = pack_ip(lhost)) {
00571 memcpy((char *) &lsa.sin_addr, addr, 4);
00572 lsa.sin_family = AF_INET;
00573 #endif
00574 } else {
00575 lhost = NULL;
00576 }
00577 }
00578 if (lport)
00579 lsa.sin_port = htons((unsigned short) lport);
00580
00581 memset(&sa, 0, sizeof(sa));
00582 #if HAVE_GETHOSTBYNAME
00583 if (!(hp = gethostbyname(host)))
00584 return -1;
00585 memcpy((char *) &sa.sin_addr, hp->h_addr, hp->h_length);
00586 sa.sin_family = hp->h_addrtype;
00587 #else
00588 if (!(addr = pack_ip(host))) {
00589 alog("conn(): `%s' is not a valid IP address", host);
00590 ano_sockseterr(SOCKERR_EINVAL);
00591 return -1;
00592 }
00593 memcpy((char *) &sa.sin_addr, addr, 4);
00594 sa.sin_family = AF_INET;
00595 #endif
00596 sa.sin_port = htons((unsigned short) port);
00597
00598 if ((sock = socket(sa.sin_family, SOCK_STREAM, 0)) < 0)
00599 return -1;
00600
00601 if ((lhost || lport)
00602 && bind(sock, (struct sockaddr *) &lsa, sizeof(lsa)) < 0) {
00603 int errno_save = ano_sockgeterr();
00604 ano_sockclose(sock);
00605 ano_sockseterr(errno_save);
00606 return -1;
00607 }
00608
00609 if (connect(sock, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
00610 int errno_save = ano_sockgeterr();
00611 ano_sockclose(sock);
00612 ano_sockseterr(errno_save);
00613 return -1;
00614 }
00615
00616 return sock;
00617 }
00618
00619
00620
00626 void disconn(ano_socket_t s)
00627 {
00628 shutdown(s, 2);
00629 ano_sockclose(s);
00630 }
00631
00632
00633
00634
00635 #ifdef _WIN32
00636
00637 struct u_WSA_errors {
00638 int error_code;
00639 char *error_string;
00640 };
00641
00642
00643 struct u_WSA_errors WSAErrors[] = {
00644 {WSAEINTR, "Interrupted system call"},
00645 {WSAEBADF, "Bad file number"},
00646 {WSAEACCES, "Permission denied"},
00647 {WSAEFAULT, "Bad address"},
00648 {WSAEINVAL, "Invalid argument"},
00649 {WSAEMFILE, "Too many open sockets"},
00650 {WSAEWOULDBLOCK, "Operation would block"},
00651 {WSAEINPROGRESS, "Operation now in progress"},
00652 {WSAEALREADY, "Operation already in progress"},
00653 {WSAENOTSOCK, "Socket operation on non-socket"},
00654 {WSAEDESTADDRREQ, "Destination address required"},
00655 {WSAEMSGSIZE, "Message too long"},
00656 {WSAEPROTOTYPE, "Protocol wrong type for socket"},
00657 {WSAENOPROTOOPT, "Bad protocol option"},
00658 {WSAEPROTONOSUPPORT, "Protocol not supported"},
00659 {WSAESOCKTNOSUPPORT, "Socket type not supported"},
00660 {WSAEOPNOTSUPP, "Operation not supported on socket"},
00661 {WSAEPFNOSUPPORT, "Protocol family not supported"},
00662 {WSAEAFNOSUPPORT, "Address family not supported"},
00663 {WSAEADDRINUSE, "Address already in use"},
00664 {WSAEADDRNOTAVAIL, "Can't assign requested address"},
00665 {WSAENETDOWN, "Network is down"},
00666 {WSAENETUNREACH, "Network is unreachable"},
00667 {WSAENETRESET, "Net connection reset"},
00668 {WSAECONNABORTED, "Software caused connection abort"},
00669 {WSAECONNRESET, "Connection reset by peer"},
00670 {WSAENOBUFS, "No buffer space available"},
00671 {WSAEISCONN, "Socket is already connected"},
00672 {WSAENOTCONN, "Socket is not connected"},
00673 {WSAESHUTDOWN, "Can't send after socket shutdown"},
00674 {WSAETOOMANYREFS, "Too many references, can't splice"},
00675 {WSAETIMEDOUT, "Connection timed out"},
00676 {WSAECONNREFUSED, "Connection refused"},
00677 {WSAELOOP, "Too many levels of symbolic links"},
00678 {WSAENAMETOOLONG, "File name too long"},
00679 {WSAEHOSTDOWN, "Host is down"},
00680 {WSAEHOSTUNREACH, "No route to host"},
00681 {WSAENOTEMPTY, "Directory not empty"},
00682 {WSAEPROCLIM, "Too many processes"},
00683 {WSAEUSERS, "Too many users"},
00684 {WSAEDQUOT, "Disc quota exceeded"},
00685 {WSAESTALE, "Stale NFS file handle"},
00686 {WSAEREMOTE, "Too many levels of remote in path"},
00687 {WSASYSNOTREADY, "Network subsystem is unavailable"},
00688 {WSAVERNOTSUPPORTED, "Winsock version not supported"},
00689 {WSANOTINITIALISED, "Winsock not yet initialized"},
00690 {WSAHOST_NOT_FOUND, "Host not found"},
00691 {WSATRY_AGAIN, "Non-authoritative host not found"},
00692 {WSANO_RECOVERY, "Non-recoverable errors"},
00693 {WSANO_DATA, "Valid name, no data record of requested type"},
00694 {WSAEDISCON, "Graceful disconnect in progress"},
00695 #ifdef WSASYSCALLFAILURE
00696 {WSASYSCALLFAILURE, "System call failure"},
00697 #endif
00698 {0, NULL}
00699 };
00700
00701 char *ano_sockstrerror(int error)
00702 {
00703 static char unkerr[64];
00704 int start = 0;
00705 int stop = sizeof(WSAErrors) / sizeof(WSAErrors[0]) - 1;
00706 int mid;
00707
00708
00709
00710
00711
00712 while (start <= stop) {
00713 mid = (start + stop) / 2;
00714 if (WSAErrors[mid].error_code > error)
00715 stop = mid - 1;
00716
00717 else if (WSAErrors[mid].error_code < error)
00718 start = mid + 1;
00719 else
00720 return WSAErrors[mid].error_string;
00721 }
00722 sprintf(unkerr, "Unknown Error: %d", error);
00723 return unkerr;
00724 }
00725
00726 int ano_socksetnonb(ano_socket_t fd)
00727 {
00728 u_long i = 1;
00729 return (!ioctlsocket(fd, FIONBIO, &i) ? -1 : 1);
00730 }
00731 #endif