27
33
typedef struct sockaddr_in sockaddr_in;
30
sock_init_sockaddr (sockaddr_in * name, const char *hostname, unsigned short int port)
36
sock_init_sockaddr (sockaddr_in *name, const char *hostname, unsigned short int port)
32
38
struct hostent *hostinfo;
34
memset (name, 0, sizeof (*name));
40
memset (name, '\0', sizeof (*name));
35
41
name->sin_family = AF_INET;
36
42
name->sin_port = htons (port);
37
43
hostinfo = gethostbyname (hostname);
56
62
report (RPT_DEBUG, "sock_connect: Creating socket");
57
63
sock = socket (PF_INET, SOCK_STREAM, 0);
65
if (sock == INVALID_SOCKET) {
59
69
report (RPT_ERR, "sock_connect: Error creating socket");
62
72
debug (RPT_DEBUG, "sock_connect: Created socket (%i)", sock);
64
sock_init_sockaddr (&servername, host, port);
74
if (sock_init_sockaddr (&servername, host, port) < 0)
66
77
err = connect (sock, (struct sockaddr *) &servername, sizeof (servername));
79
if (err == INVALID_SOCKET) {
68
83
report (RPT_ERR, "sock_connect: connect failed");
84
shutdown (sock, SHUT_RDWR);
70
85
return 0; // Normal exit if server doesn't exist...
73
89
fcntl (sock, F_SETFL, O_NONBLOCK);
92
unsigned long tmp = 1;
94
if (ioctlsocket(sock, FIONBIO, &tmp) == SOCKET_ERROR)
95
report(RPT_ERR, "sock_connect: Error setting socket to non-blocking");
83
err = shutdown (fd, 2);
107
err = shutdown (fd, SHUT_RDWR);
115
/** send printf-like formatted output */
117
sock_printf(int fd, const char *format, .../*args*/ )
123
va_start(ap, format);
124
size = vsnprintf(buf, sizeof(buf), format, ap);
128
report(RPT_ERR, "sock_printf: vsnprintf failed");
131
if (size > sizeof(buf))
132
report(RPT_WARNING, "sock_printf: vsnprintf truncated message");
134
return sock_send_string(fd, buf);
90
137
// Send/receive lines of text
92
139
sock_send_string (int fd, char *string)
100
len = strlen (string) ;
101
while (offset != len) {
102
// write isn't guaranteed to send the entire string at once,
103
// so we have to sent it in a loop like this
104
int sent = write (fd, string + offset, len - offset);
106
if (errno != EAGAIN) {
107
report (RPT_ERR, "sock_send_string: socket write error");
108
report (RPT_DEBUG, "Message was: %s", string);
113
} else if (sent == 0) {
114
// when this returns zero, it generally means
115
// we got disconnected
116
return sent + offset;
141
return sock_send(fd, string, strlen(string));
125
144
// Recv gives only one line per call...
151
174
} else if (err == 0) {
157
if (recv == maxlen || *ptr == 0 || *ptr == 10) {
180
// stop at max. bytes allowed, at NUL or at LF
181
if (recvBytes == maxlen || *ptr == '\0' || *ptr == '\n') {
164
if (recv == 1 && dest[0] == 0) {
165
// Don't return a null string
188
// Don't return an empty string
189
if (recvBytes == 1 && dest[0] == '\0')
169
if (recv < maxlen - 1) {
192
if (recvBytes < maxlen - 1)
193
dest[recvBytes] = '\0';
176
198
// Send/receive raw data
185
207
while (offset != size) {
186
208
// write isn't guaranteed to send the entire string at once,
187
209
// so we have to sent it in a loop like this
188
int sent = write (fd, ((char *) src) + offset, size - offset);
211
int sent = write (fd, ((char *) src) + offset, size - offset);
213
int sent = send(fd, ((char *) src) + offset, size - offset, 0);
189
215
if (sent == -1) {
190
216
if (errno != EAGAIN) {
191
217
report (RPT_ERR, "sock_send: socket write error");
218
report (RPT_DEBUG, "Message was: '%.*s'", size-offset, (char *) src);
219
//shutdown(fd, SHUT_RDWR);
218
246
err = read (fd, dest, maxlen);
248
err = recv(fd, dest, maxlen, 0);
220
251
//report (RPT_DEBUG,"sock_recv: socket read error");
252
//shutdown(fd, SHUT_RDWR);
224
255
//debug(RPT_DEBUG, "sock_recv: Got message \"%s\"", (char *)dest);
260
/*****************************************************************************/
266
return strerror(errno);
268
static char retString[256];
272
err = WSAGetLastError();
274
sprintf(retString, "Error code %ld: ", err);
275
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
276
FORMAT_MESSAGE_FROM_SYSTEM |
277
FORMAT_MESSAGE_IGNORE_INSERTS,
280
0, /* Default language */
285
/* append the message text after the error code and ensure a terminating
286
character ends the string */
287
strncpy(retString + strlen(retString), tmp,
288
sizeof(retString) - strlen(retString) - 1);
289
retString[sizeof(retString) - 1] = '\0';
295
/** prints error to logfile and sends it to the client.
297
* @param message the message to send (without the "huh? ") */
298
int sock_send_error(int fd, char* message)
300
// simple: performance penalty isn't worth more work...
301
return sock_printf_error(fd, message);
304
/** prints printf-like formatted output to logfile and sends it to the
306
* @note don't add a the "huh? " to the message. This is done by this
309
* @param format a printf format */
311
sock_printf_error(int fd, const char *format, .../*args*/ )
313
static const char huh[] = "huh? ";
318
strncpy(buf, huh, sizeof(huh)); // note: sizeof(huh) < MAXMSG
320
va_start(ap, format);
321
size = vsnprintf(buf + (sizeof(huh)-1), sizeof(buf) - (sizeof(huh)-1), format, ap);
322
buf[sizeof(buf)-1] = '\0';
326
report(RPT_ERR, "sock_printf_error: vsnprintf failed");
329
if (size >= sizeof(buf) - (sizeof(huh)-1))
330
report(RPT_WARNING, "sock_printf_error: vsnprintf truncated message");
332
report(RPT_ERR, "error: %s", buf);
333
return sock_send_string(fd, buf);