2 * socket.c -- socket library functions
4 * For license terms, see the file COPYING in this directory.
9 #endif /* HAVE_CONFIG_H */
14 #endif /* HAVE_MEMORY_H */
15 #include <sys/types.h>
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
20 #if defined(STDC_HEADERS)
23 #if defined(HAVE_UNISTD_H)
26 #if defined(HAVE_STDARG_H)
35 #ifdef INADDR_BROADCAST
36 #define INADDR_NONE INADDR_BROADCAST
38 #define INADDR_NONE -1
41 #endif /* INET_ATON */
43 int SockOpen(const char *host, int clientPort)
48 #endif /* INET_ATON */
49 struct sockaddr_in ad;
52 memset(&ad, 0, sizeof(ad));
53 ad.sin_family = AF_INET;
55 /* we'll accept a quad address */
57 inaddr = inet_addr(host);
58 if (inaddr != INADDR_NONE)
59 memcpy(&ad.sin_addr, &inaddr, sizeof(inaddr));
62 if (!inet_aton(host, &ad.sin_addr))
63 #endif /* INET_ATON */
65 hp = gethostbyname(host);
68 * Add a check to make sure the address has a valid IPv4 or IPv6
69 * length. This prevents buffer spamming by a broken DNS.
71 if (hp == NULL || (hp->h_length != 4 && hp->h_length != 8))
74 memcpy(&ad.sin_addr, hp->h_addr, hp->h_length);
76 ad.sin_port = htons(clientPort);
78 sock = socket(AF_INET, SOCK_STREAM, 0);
81 if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0)
91 #if defined(HAVE_STDARG_H)
92 int SockPrintf(int sock, char* format, ...)
95 int SockPrintf(sock,format,va_alist)
104 #if defined(HAVE_STDARG_H)
105 va_start(ap, format) ;
109 #ifdef HAVE_VSNPRINTF
110 vsnprintf(buf, sizeof(buf), format, ap);
112 vsprintf(buf, format, ap);
115 return SockWrite(sock, buf, strlen(buf));
119 int SockWrite(int sock, char *buf, int len)
125 n = write(sock, buf, len);
135 int SockRead(int sock, char *buf, int len)
137 char *newline, *bp = buf;
144 * The reason for these gymnastics is that we want two things:
145 * (1) to read \n-terminated lines,
146 * (2) to return the true length of data read, even if the
147 * data coming in has embedded NULS.
149 if ((n = recv(sock, bp, len, MSG_PEEK)) <= 0)
151 if ((newline = memchr(bp, '\n', n)) != NULL)
152 n = newline - bp + 1;
153 if ((n = read(sock, bp, n)) == -1)
163 int SockPeek(int sock)
164 /* peek at the next socket character without actually reading it */
169 if ((n = recv(sock, &ch, 1, MSG_PEEK)) == -1)
177 * Use the chargen service to test input beuffering directly.
178 * You may have to uncomment the `chargen' service description in your
179 * inetd.conf (and then SIGHUP inetd) for this to work.
183 int sock = SockOpen("localhost", 19);
186 while (SockRead(sock, buf, sizeof(buf)-1))
187 SockWrite(1, buf, strlen(buf));
191 /* socket.c ends here */