2 * socket.c -- socket library functions
4 * These were designed and coded by Carl Harris <ceharris@mal.com>
5 * and are essentially unchanged from the ancestral popclient.
7 * For license terms, see the file COPYING in this directory.
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <netinet/in.h>
17 #include <arpa/inet.h>
20 #include <sys/ioctl.h>
21 #if defined(STDC_HEADERS)
25 #if defined(HAVE_UNISTD_H)
28 #if defined(HAVE_STDARG_H)
36 /* Size of buffer for internal buffering read function
37 don't increase beyond the maximum atomic read/write size for
38 your sockets, or you'll take a potentially huge performance hit */
40 #define INTERNAL_BUFSIZE 2048
42 int Socket(host, clientPort)
48 struct sockaddr_in ad;
51 memset(&ad, 0, sizeof(ad));
52 ad.sin_family = AF_INET;
54 inaddr = inet_addr(host);
55 if (inaddr != INADDR_NONE)
56 memcpy(&ad.sin_addr, &inaddr, sizeof(inaddr));
59 hp = gethostbyname(host);
62 memcpy(&ad.sin_addr, hp->h_addr, hp->h_length);
64 ad.sin_port = htons(clientPort);
66 sock = socket(AF_INET, SOCK_STREAM, 0);
69 if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0)
74 int SockPuts(socket,buf)
80 if ((rc = SockWrite(socket, buf, strlen(buf))) != 0)
82 return SockWrite(socket, "\r\n", 2);
85 int SockWrite(socket,buf,len)
94 n = write(socket, buf, len);
103 static int sbuflen = 0;
105 static int SockInternalRead (socket,buf,len)
110 static char sbuf [INTERNAL_BUFSIZE];
114 /* buffer is empty; refresh. */
115 if ((sbuflen = read(socket,sbuf,INTERNAL_BUFSIZE)) < 0) {
118 perror("SockInternalRead: read");
125 ; /* already some data in the buffer */
127 /* can't get more than we have right now. */
128 /* XXX -- should probably try to load any unused part of sbuf
129 so that as much of 'len' as possible can be satisfied */
133 ; /* wants no more than we already have */
135 /* transfer to caller's buffer */
137 /* special case: if caller only wants one character, it probably
138 costs a lot more to call bcopy than to do it ourselves. */
150 int SockRead(socket,buf,len)
160 n = SockInternalRead(socket, buf, len);
169 int SockGets(socket,buf,len)
178 if (SockInternalRead(socket, buf, 1) != 1)
184 if (*buf != '\r') /* remove all CRs */
191 /* SockDataWaiting: Return a non-zero value if this socket is waiting
193 int SockDataWaiting(int socket)
196 char sbuf[INTERNAL_BUFSIZE];
198 flags = fcntl(socket,F_GETFL,0);
200 /* set it to non-block */
201 if (fcntl(socket,F_SETFL,flags | O_NONBLOCK) == -1)
204 n = recv(socket,sbuf,INTERNAL_BUFSIZE,MSG_PEEK);
206 /* reset it to block (or, whatever it was). */
207 fcntl(socket,F_SETFL,flags);
211 /* No data to read. */
212 if (errno == EWOULDBLOCK)
222 /* SockClearHeader: call this procedure in order to kill off any
223 forthcoming Header info from the socket that we no longer want.
225 int SockClearHeader(socket)
229 static char sbuf[INTERNAL_BUFSIZE];
232 if ((res = SockDataWaiting(socket)) <= 0)
237 if (SockGets(socket,sbuf,INTERNAL_BUFSIZE) < 0)
250 #if defined(HAVE_STDARG_H)
251 int SockPrintf(int socket, char* format, ...)
254 int SockPrintf(socket,format,va_alist)
263 #if defined(HAVE_STDARG_H)
264 va_start(ap, format) ;
268 vsprintf(buf, format, ap);
270 return SockWrite(socket, buf, strlen(buf));
274 /* socket.c ends here */