summaryrefslogtreecommitdiff
path: root/src/network.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/network.c')
-rw-r--r--src/network.c463
1 files changed, 220 insertions, 243 deletions
diff --git a/src/network.c b/src/network.c
index fc74e69..61dcbae 100644
--- a/src/network.c
+++ b/src/network.c
@@ -32,56 +32,50 @@
* Write the buffer to the socket. If an EINTR occurs, pick up and try
* again. Keep sending until the buffer has been sent.
*/
-ssize_t
-safe_write (int fd, const char *buffer, size_t count)
+ssize_t safe_write (int fd, const char *buffer, size_t count)
{
- ssize_t len;
- size_t bytestosend;
+ ssize_t len;
+ size_t bytestosend;
- assert (fd >= 0);
- assert (buffer != NULL);
- assert (count > 0);
+ assert (fd >= 0);
+ assert (buffer != NULL);
+ assert (count > 0);
- bytestosend = count;
+ bytestosend = count;
- while (1)
- {
- len = send (fd, buffer, bytestosend, MSG_NOSIGNAL);
+ while (1) {
+ len = send (fd, buffer, bytestosend, MSG_NOSIGNAL);
- if (len < 0)
- {
- if (errno == EINTR)
- continue;
- else
- return -errno;
- }
+ if (len < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ return -errno;
+ }
- if ((size_t)len == bytestosend)
- break;
+ if ((size_t) len == bytestosend)
+ break;
- buffer += len;
- bytestosend -= len;
- }
+ buffer += len;
+ bytestosend -= len;
+ }
- return count;
+ return count;
}
/*
* Matched pair for safe_write(). If an EINTR occurs, pick up and try
* again.
*/
-ssize_t
-safe_read (int fd, char *buffer, size_t count)
+ssize_t safe_read (int fd, char *buffer, size_t count)
{
- ssize_t len;
+ ssize_t len;
- do
- {
- len = read (fd, buffer, count);
- }
- while (len < 0 && errno == EINTR);
+ do {
+ len = read (fd, buffer, count);
+ } while (len < 0 && errno == EINTR);
- return len;
+ return len;
}
/*
@@ -90,52 +84,47 @@ safe_read (int fd, char *buffer, size_t count)
* was basically stolen from the snprintf() man page of Debian Linux
* (although I did fix a memory leak. :)
*/
-int
-write_message (int fd, const char *fmt, ...)
+int write_message (int fd, const char *fmt, ...)
{
- ssize_t n;
- size_t size = (1024 * 8); /* start with 8 KB and go from there */
- char *buf, *tmpbuf;
- va_list ap;
-
- if ((buf = (char *)safemalloc (size)) == NULL)
- return -1;
-
- while (1)
- {
- va_start (ap, fmt);
- n = vsnprintf (buf, size, fmt, ap);
- va_end (ap);
-
- /* If that worked, break out so we can send the buffer */
- if (n > -1 && (size_t)n < size)
- break;
-
- /* Else, try again with more space */
- if (n > -1)
- /* precisely what is needed (glibc2.1) */
- size = n + 1;
- else
- /* twice the old size (glibc2.0) */
- size *= 2;
-
- if ((tmpbuf = (char *)saferealloc (buf, size)) == NULL)
- {
- safefree (buf);
- return -1;
+ ssize_t n;
+ size_t size = (1024 * 8); /* start with 8 KB and go from there */
+ char *buf, *tmpbuf;
+ va_list ap;
+
+ if ((buf = (char *) safemalloc (size)) == NULL)
+ return -1;
+
+ while (1) {
+ va_start (ap, fmt);
+ n = vsnprintf (buf, size, fmt, ap);
+ va_end (ap);
+
+ /* If that worked, break out so we can send the buffer */
+ if (n > -1 && (size_t) n < size)
+ break;
+
+ /* Else, try again with more space */
+ if (n > -1)
+ /* precisely what is needed (glibc2.1) */
+ size = n + 1;
+ else
+ /* twice the old size (glibc2.0) */
+ size *= 2;
+
+ if ((tmpbuf = (char *) saferealloc (buf, size)) == NULL) {
+ safefree (buf);
+ return -1;
+ } else
+ buf = tmpbuf;
+ }
+
+ if (safe_write (fd, buf, n) < 0) {
+ safefree (buf);
+ return -1;
}
- else
- buf = tmpbuf;
- }
-
- if (safe_write (fd, buf, n) < 0)
- {
- safefree (buf);
- return -1;
- }
-
- safefree (buf);
- return 0;
+
+ safefree (buf);
+ return 0;
}
/*
@@ -149,152 +138,142 @@ write_message (int fd, const char *fmt, ...)
*/
#define SEGMENT_LEN (512)
#define MAXIMUM_BUFFER_LENGTH (128 * 1024)
-ssize_t
-readline (int fd, char **whole_buffer)
+ssize_t readline (int fd, char **whole_buffer)
{
- ssize_t whole_buffer_len;
- char buffer[SEGMENT_LEN];
- char *ptr;
-
- ssize_t ret;
- ssize_t diff;
-
- struct read_lines_s
- {
- char *data;
- size_t len;
- struct read_lines_s *next;
- };
- struct read_lines_s *first_line, *line_ptr;
-
- first_line = (struct read_lines_s *)safecalloc (sizeof (struct read_lines_s),
- 1);
- if (!first_line)
- return -ENOMEM;
-
- line_ptr = first_line;
-
- whole_buffer_len = 0;
- for (;;)
- {
- ret = recv (fd, buffer, SEGMENT_LEN, MSG_PEEK);
- if (ret <= 0)
- goto CLEANUP;
-
- ptr = (char *)memchr (buffer, '\n', ret);
- if (ptr)
- diff = ptr - buffer + 1;
- else
- diff = ret;
-
- whole_buffer_len += diff;
-
- /*
- * Don't allow the buffer to grow without bound. If we
- * get to more than MAXIMUM_BUFFER_LENGTH close.
- */
- if (whole_buffer_len > MAXIMUM_BUFFER_LENGTH)
- {
- ret = -ERANGE;
- goto CLEANUP;
+ ssize_t whole_buffer_len;
+ char buffer[SEGMENT_LEN];
+ char *ptr;
+
+ ssize_t ret;
+ ssize_t diff;
+
+ struct read_lines_s {
+ char *data;
+ size_t len;
+ struct read_lines_s *next;
+ };
+ struct read_lines_s *first_line, *line_ptr;
+
+ first_line =
+ (struct read_lines_s *) safecalloc (sizeof (struct read_lines_s),
+ 1);
+ if (!first_line)
+ return -ENOMEM;
+
+ line_ptr = first_line;
+
+ whole_buffer_len = 0;
+ for (;;) {
+ ret = recv (fd, buffer, SEGMENT_LEN, MSG_PEEK);
+ if (ret <= 0)
+ goto CLEANUP;
+
+ ptr = (char *) memchr (buffer, '\n', ret);
+ if (ptr)
+ diff = ptr - buffer + 1;
+ else
+ diff = ret;
+
+ whole_buffer_len += diff;
+
+ /*
+ * Don't allow the buffer to grow without bound. If we
+ * get to more than MAXIMUM_BUFFER_LENGTH close.
+ */
+ if (whole_buffer_len > MAXIMUM_BUFFER_LENGTH) {
+ ret = -ERANGE;
+ goto CLEANUP;
+ }
+
+ line_ptr->data = (char *) safemalloc (diff);
+ if (!line_ptr->data) {
+ ret = -ENOMEM;
+ goto CLEANUP;
+ }
+
+ recv (fd, line_ptr->data, diff, 0);
+ line_ptr->len = diff;
+
+ if (ptr) {
+ line_ptr->next = NULL;
+ break;
+ }
+
+ line_ptr->next =
+ (struct read_lines_s *)
+ safecalloc (sizeof (struct read_lines_s), 1);
+ if (!line_ptr->next) {
+ ret = -ENOMEM;
+ goto CLEANUP;
+ }
+ line_ptr = line_ptr->next;
}
- line_ptr->data = (char *)safemalloc (diff);
- if (!line_ptr->data)
- {
- ret = -ENOMEM;
- goto CLEANUP;
+ *whole_buffer = (char *) safemalloc (whole_buffer_len + 1);
+ if (!*whole_buffer) {
+ ret = -ENOMEM;
+ goto CLEANUP;
}
- recv (fd, line_ptr->data, diff, 0);
- line_ptr->len = diff;
+ *(*whole_buffer + whole_buffer_len) = '\0';
- if (ptr)
- {
- line_ptr->next = NULL;
- break;
- }
+ whole_buffer_len = 0;
+ line_ptr = first_line;
+ while (line_ptr) {
+ memcpy (*whole_buffer + whole_buffer_len, line_ptr->data,
+ line_ptr->len);
+ whole_buffer_len += line_ptr->len;
- line_ptr->next =
- (struct read_lines_s *)safecalloc (sizeof (struct read_lines_s), 1);
- if (!line_ptr->next)
- {
- ret = -ENOMEM;
- goto CLEANUP;
+ line_ptr = line_ptr->next;
}
- line_ptr = line_ptr->next;
- }
-
- *whole_buffer = (char *)safemalloc (whole_buffer_len + 1);
- if (!*whole_buffer)
- {
- ret = -ENOMEM;
- goto CLEANUP;
- }
- *(*whole_buffer + whole_buffer_len) = '\0';
-
- whole_buffer_len = 0;
- line_ptr = first_line;
- while (line_ptr)
- {
- memcpy (*whole_buffer + whole_buffer_len, line_ptr->data,
- line_ptr->len);
- whole_buffer_len += line_ptr->len;
-
- line_ptr = line_ptr->next;
- }
-
- ret = whole_buffer_len;
+ ret = whole_buffer_len;
CLEANUP:
- do
- {
- line_ptr = first_line->next;
- if (first_line->data)
- safefree (first_line->data);
- safefree (first_line);
- first_line = line_ptr;
- }
- while (first_line);
-
- return ret;
+ do {
+ line_ptr = first_line->next;
+ if (first_line->data)
+ safefree (first_line->data);
+ safefree (first_line);
+ first_line = line_ptr;
+ } while (first_line);
+
+ return ret;
}
/*
* Convert the network address into either a dotted-decimal or an IPv6
* hex string.
*/
-char *
-get_ip_string (struct sockaddr *sa, char *buf, size_t buflen)
+char *get_ip_string (struct sockaddr *sa, char *buf, size_t buflen)
{
- assert (sa != NULL);
- assert (buf != NULL);
- assert (buflen != 0);
- buf[0] = '\0'; /* start with an empty string */
-
- switch (sa->sa_family)
- {
- case AF_INET:
- {
- struct sockaddr_in *sa_in = (struct sockaddr_in *) sa;
-
- inet_ntop (AF_INET, &sa_in->sin_addr, buf, buflen);
- break;
- }
- case AF_INET6:
- {
- struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *) sa;
-
- inet_ntop (AF_INET6, &sa_in6->sin6_addr, buf, buflen);
- break;
- }
- default:
- /* no valid family */
- return NULL;
- }
-
- return buf;
+ assert (sa != NULL);
+ assert (buf != NULL);
+ assert (buflen != 0);
+ buf[0] = '\0'; /* start with an empty string */
+
+ switch (sa->sa_family) {
+ case AF_INET:
+ {
+ struct sockaddr_in *sa_in = (struct sockaddr_in *) sa;
+
+ inet_ntop (AF_INET, &sa_in->sin_addr, buf, buflen);
+ break;
+ }
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sa_in6 =
+ (struct sockaddr_in6 *) sa;
+
+ inet_ntop (AF_INET6, &sa_in6->sin6_addr, buf, buflen);
+ break;
+ }
+ default:
+ /* no valid family */
+ return NULL;
+ }
+
+ return buf;
}
/*
@@ -304,43 +283,41 @@ get_ip_string (struct sockaddr *sa, char *buf, size_t buflen)
*
* Returns the same as inet_pton().
*/
-int
-full_inet_pton (const char *ip, void *dst)
+int full_inet_pton (const char *ip, void *dst)
{
- char buf[24], tmp[24]; /* IPv4->IPv6 = ::FFFF:xxx.xxx.xxx.xxx\0 */
- int n;
-
- assert (ip != NULL && strlen (ip) != 0);
- assert (dst != NULL);
-
- /*
- * Check if the string is an IPv4 numeric address. We use the
- * older inet_aton() call since it handles more IPv4 numeric
- * address formats.
- */
- n = inet_aton (ip, (struct in_addr *) dst);
- if (n == 0)
- {
- /*
- * Simple case: "ip" wasn't an IPv4 numeric address, so
- * try doing the conversion as an IPv6 address. This
- * will either succeed or fail, but we can't do any
- * more processing anyway.
- */
- return inet_pton (AF_INET6, ip, dst);
- }
-
- /*
- * "ip" was an IPv4 address, so we need to convert it to
- * an IPv4-mapped IPv6 address and do the conversion
- * again to get the IPv6 network structure.
- *
- * We convert the IPv4 binary address back into the
- * standard dotted-decimal format using inet_ntop()
- * so we can be sure that inet_pton will accept the
- * full string.
- */
- snprintf (buf, sizeof (buf), "::ffff:%s",
- inet_ntop (AF_INET, dst, tmp, sizeof (tmp)));
- return inet_pton (AF_INET6, buf, dst);
+ char buf[24], tmp[24]; /* IPv4->IPv6 = ::FFFF:xxx.xxx.xxx.xxx\0 */
+ int n;
+
+ assert (ip != NULL && strlen (ip) != 0);
+ assert (dst != NULL);
+
+ /*
+ * Check if the string is an IPv4 numeric address. We use the
+ * older inet_aton() call since it handles more IPv4 numeric
+ * address formats.
+ */
+ n = inet_aton (ip, (struct in_addr *) dst);
+ if (n == 0) {
+ /*
+ * Simple case: "ip" wasn't an IPv4 numeric address, so
+ * try doing the conversion as an IPv6 address. This
+ * will either succeed or fail, but we can't do any
+ * more processing anyway.
+ */
+ return inet_pton (AF_INET6, ip, dst);
+ }
+
+ /*
+ * "ip" was an IPv4 address, so we need to convert it to
+ * an IPv4-mapped IPv6 address and do the conversion
+ * again to get the IPv6 network structure.
+ *
+ * We convert the IPv4 binary address back into the
+ * standard dotted-decimal format using inet_ntop()
+ * so we can be sure that inet_pton will accept the
+ * full string.
+ */
+ snprintf (buf, sizeof (buf), "::ffff:%s",
+ inet_ntop (AF_INET, dst, tmp, sizeof (tmp)));
+ return inet_pton (AF_INET6, buf, dst);
}