aboutsummaryrefslogtreecommitdiffstats
path: root/src/libmdsserver/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libmdsserver/util.c')
-rw-r--r--src/libmdsserver/util.c867
1 files changed, 435 insertions, 432 deletions
diff --git a/src/libmdsserver/util.c b/src/libmdsserver/util.c
index cac30ad..09d996a 100644
--- a/src/libmdsserver/util.c
+++ b/src/libmdsserver/util.c
@@ -49,20 +49,21 @@ static char self_exe[PATH_MAX] = {0};
* @param str The client ID string
* @return The client ID integer
*/
-uint64_t parse_client_id(const char* str)
+uint64_t
+parse_client_id(const char *str)
{
- char client_words[22];
- char* client_high;
- char* client_low;
- uint64_t client;
-
- strcpy(client_high = client_words, str);
- client_low = rawmemchr(client_words, ':');
- *client_low++ = '\0';
- client = atou64(client_high) << 32;
- client |= atou64(client_low);
-
- return client;
+ char client_words[22];
+ char *client_high;
+ char *client_low;
+ uint64_t client;
+
+ strcpy(client_high = client_words, str);
+ client_low = rawmemchr(client_words, ':');
+ *client_low++ = '\0';
+ client = atou64(client_high) << 32;
+ client |= atou64(client_low);
+
+ return client;
}
@@ -72,12 +73,11 @@ uint64_t parse_client_id(const char* str)
* @param var The environment variable's name
* @return The environment variable's value, `NULL` if empty or not defined
*/
-char* getenv_nonempty(const char* var)
+char *
+getenv_nonempty(const char *var)
{
- char* rc = getenv(var);
- if ((rc == NULL) || (*rc == '\0'))
- return NULL;
- return rc;
+ char *rc = getenv(var);
+ return (rc && *rc) ? rc : NULL;
}
@@ -97,20 +97,21 @@ char* getenv_nonempty(const char* var)
*
* @return Zero on success, -1 on error
*/
-int prepare_reexec(void)
+int
+prepare_reexec(void)
{
- ssize_t len;
- len = readlink(SELF_EXE, self_exe, (sizeof(self_exe) / sizeof(char)) - 1);
- fail_if (len < 0);
- /* ‘readlink() does not append a null byte to buf.’ */
- self_exe[len] = '\0';
- /* Handle possible race condition: file was removed. */
- if (access(self_exe, F_OK) < 0)
- if (!strcmp(self_exe + (len - 10), " (deleted)"))
- self_exe[len - 10] = '\0';
- return 0;
- fail:
- return -1;
+ ssize_t len;
+ len = readlink(SELF_EXE, self_exe, (sizeof(self_exe) / sizeof(char)) - 1);
+ fail_if (len < 0);
+ /* ‘readlink() does not append a null byte to buf.’ */
+ self_exe[len] = '\0';
+ /* Handle possible race condition: file was removed. */
+ if (access(self_exe, F_OK) < 0)
+ if (!strcmp(self_exe + (len - 10), " (deleted)"))
+ self_exe[len - 10] = '\0';
+ return 0;
+fail:
+ return -1;
}
@@ -125,30 +126,30 @@ int prepare_reexec(void)
* @param argv The command line arguments
* @param reexeced Whether the server has previously been re-exec:ed
*/
-void reexec_server(int argc, char** argv, int reexeced)
+void
+reexec_server(int argc, char **argv, int reexeced)
{
- char** reexec_args;
- char** reexec_args_;
- int i;
-
- /* Re-exec the server. */
- reexec_args = alloca(((size_t)argc + 2) * sizeof(char*));
- reexec_args_ = reexec_args;
- if (reexeced == 0)
- {
- *reexec_args_++ = *argv;
- fail_if (xstrdup(*reexec_args_, "--re-exec"));
- for (i = 1; i < argc; i++)
- reexec_args_[i] = argv[i];
- }
- else /* Don't let the --re-exec:s accumulate. */
- *reexec_args_ = *argv;
- for (i = 1; i < argc; i++)
- reexec_args_[i] = argv[i];
- reexec_args_[argc] = NULL;
- execv(self_exe[0] ? self_exe : argv[0], reexec_args);
- fail:
- return;
+ char **reexec_args;
+ char **reexec_args_;
+ int i;
+
+ /* Re-exec the server. */
+ reexec_args = alloca(((size_t)argc + 2) * sizeof(char*));
+ reexec_args_ = reexec_args;
+ if (!reexeced) {
+ *reexec_args_++ = *argv;
+ fail_if (xstrdup(*reexec_args_, "--re-exec"));
+ for (i = 1; i < argc; i++)
+ reexec_args_[i] = argv[i];
+ } else { /* Don't let the --re-exec:s accumulate. */
+ *reexec_args_ = *argv;
+ }
+ for (i = 1; i < argc; i++)
+ reexec_args_[i] = argv[i];
+ reexec_args_[argc] = NULL;
+ execv(self_exe[0] ? self_exe : argv[0], reexec_args);
+fail:
+ return;
}
@@ -164,17 +165,18 @@ void reexec_server(int argc, char** argv, int reexeced)
* @param function The function to run when the signal is caught
* @return Zero on success, -1 on error
*/
-int xsigaction(int signo, void (*function)(int signo))
+int
+xsigaction(int signo, void (*function)(int signo))
{
- struct sigaction action;
- sigset_t sigset;
-
- sigemptyset(&sigset);
- action.sa_handler = function;
- action.sa_mask = sigset;
- action.sa_flags = 0;
-
- return sigaction(signo, &action, NULL);
+ struct sigaction action;
+ sigset_t sigset;
+
+ sigemptyset(&sigset);
+ action.sa_handler = function;
+ action.sa_mask = sigset;
+ action.sa_flags = 0;
+
+ return sigaction(signo, &action, NULL);
}
@@ -186,34 +188,32 @@ int xsigaction(int signo, void (*function)(int signo))
* @param length The length of the message
* @return The number of bytes that have been sent (even on error)
*/
-size_t send_message(int socket, const char* message, size_t length)
+size_t
+send_message(int socket, const char *message, size_t length)
{
- size_t block_size = length;
- size_t sent = 0;
- ssize_t just_sent;
-
- errno = 0;
- while (length > 0)
- if ((just_sent = send(socket, message + sent, min(block_size, length), MSG_NOSIGNAL)) < 0)
- {
- if (errno == EPIPE)
- errno = ECONNRESET;
- if (errno == EMSGSIZE)
- {
- block_size >>= 1;
- if (block_size == 0)
- return sent;
- }
- else
- return sent;
- }
- else
- {
- sent += (size_t)just_sent;
- length -= (size_t)just_sent;
- }
-
- return sent;
+ size_t block_size = length;
+ size_t sent = 0;
+ ssize_t just_sent;
+
+ errno = 0;
+ while (length > 0) {
+ if ((just_sent = send(socket, message + sent, min(block_size, length), MSG_NOSIGNAL)) < 0) {
+ if (errno == EPIPE)
+ errno = ECONNRESET;
+ if (errno == EMSGSIZE) {
+ block_size >>= 1;
+ if (!block_size)
+ return sent;
+ } else {
+ return sent;
+ }
+ } else {
+ sent += (size_t)just_sent;
+ length -= (size_t)just_sent;
+ }
+ }
+
+ return sent;
}
@@ -226,20 +226,21 @@ size_t send_message(int socket, const char* message, size_t length)
* @param max The maximum accepted value
* @return Zero on success, -1 on syntax error
*/
-int strict_atoi(const char* str, int* value, int min, int max)
+int
+strict_atoi(const char *str, int *value, int min, int max)
{
- long long int r;
- char* endptr;
-
- r = strtoll(str, &endptr, 10);
- if ((*str == '\0') || isspace(*str) ||
- (endptr - str != (ssize_t)strlen(str)) ||
- (r < (long long int)min) ||
- (r > (long long int)max))
- return -1;
-
- *value = (int)r;
- return 0;
+ long long int r;
+ char *endptr;
+
+ r = strtoll(str, &endptr, 10);
+ if (!*str || isspace(*str) ||
+ endptr - str != (ssize_t)strlen(str) ||
+ r < (long long int)min ||
+ r > (long long int)max)
+ return -1;
+
+ *value = (int)r;
+ return 0;
}
@@ -252,51 +253,50 @@ int strict_atoi(const char* str, int* value, int min, int max)
* @param max The maximum accepted value
* @return Zero on success, -1 on syntax error
*/
-int strict_atoj(const char* str, intmax_t* value, intmax_t min, intmax_t max)
+int
+strict_atoj(const char *str, intmax_t *value, intmax_t min, intmax_t max)
{
- static char minstr[3 * sizeof(intmax_t) + 2] = { '\0' };
- intmax_t r = 0;
- char c;
- int neg = 0;
-
- if (*str == '-')
- {
- if (*minstr == '\0')
- sprintf(minstr, "%j", INTMAX_MIN);
- if (!strcmp(str, minstr))
- {
- r = INTMAX_MIN;
- goto done;
+ static char minstr[3 * sizeof(intmax_t) + 2] = { '\0' };
+ intmax_t r = 0;
+ char c;
+ int neg = 0;
+
+ if (*str == '-') {
+ if (!*minstr)
+ sprintf(minstr, "%j", INTMAX_MIN);
+ if (!strcmp(str, minstr)) {
+ r = INTMAX_MIN;
+ goto done;
+ }
+ neg = 1, str++;
}
- neg = 1, str++;
- }
-
- if (*str == '\0')
- return -1;
-
- while ((c = *str))
- if (('0' <= c) && (c <= '9'))
- {
- if (r > INTMAX_MAX / 10)
- return -1;
- else if (r == INTMAX_MAX / 10)
- if ((c & 15) > INTMAX_MAX % 10)
- return -1;
- r = r * 10 + (c & 15);
- }
- else
- return -1;
-
- if (neg)
- r = -r;
-
- done:
-
- if ((r < min) || (r > max))
- return -1;
-
- *value = r;
- return 0;
+
+ if (!*str)
+ return -1;
+
+ while ((c = *str)) {
+ if ('0' <= c && c <= '9') {
+ if (r > INTMAX_MAX / 10) {
+ return -1;
+ } else if (r == INTMAX_MAX / 10) {
+ if ((c & 15) > INTMAX_MAX % 10)
+ return -1;
+ }
+ r = r * 10 + (c & 15);
+ } else {
+ return -1;
+ }
+ }
+
+ if (neg)
+ r = -r;
+
+done:
+ if (r < min || r > max)
+ return -1;
+
+ *value = r;
+ return 0;
}
@@ -316,50 +316,53 @@ int strict_atoj(const char* str, intmax_t* value, intmax_t min, intmax_t max)
* @param max The maximum accepted value
* @return Zero on success, -1 on syntax error
*/
-int strict_atouj(const char* str, uintmax_t* value, uintmax_t min, uintmax_t max)
+int
+strict_atouj(const char *str, uintmax_t *value, uintmax_t min, uintmax_t max)
{
- uintmax_t r = 0;
- char c;
-
- if (*str == '\0')
- return -1;
-
- while ((c = *str))
- if (('0' <= c) && (c <= '9'))
- {
- if (r > INTMAX_MAX / 10)
- return -1;
- else if (r == INTMAX_MAX / 10)
- if ((c & 15) > INTMAX_MAX % 10)
- return -1;
- r = r * 10 + (c & 15);
- }
- else
- return -1;
-
- if ((r < min) || (r > max))
- return -1;
-
- *value = r;
- return 0;
+ uintmax_t r = 0;
+ char c;
+
+ if (!*str)
+ return -1;
+
+ while ((c = *str)) {
+ if ('0' <= c && c <= '9') {
+ if (r > INTMAX_MAX / 10) {
+ return -1;
+ } else if (r == INTMAX_MAX / 10) {
+ if ((c & 15) > INTMAX_MAX % 10)
+ return -1;
+ }
+ r = r * 10 + (c & 15);
+ } else {
+ return -1;
+ }
+ }
+
+ if (r < min || r > max)
+ return -1;
+
+ *value = r;
+ return 0;
}
#if defined(__GNUC__)
# pragma GCC diagnostic pop
#endif
-#define __strict_y(Y, TYPE, PARA_TYPE, HYPER_Y, HYPER_TYPE) \
- int strict_##Y(const char* str, TYPE* value, PARA_TYPE min, PARA_TYPE max) \
- { \
- HYPER_TYPE intermediate_value; \
- if (strict_##HYPER_Y(str, &intermediate_value, (HYPER_TYPE)min, (HYPER_TYPE)max) < 0) \
- return -1; \
- return *value = (TYPE)intermediate_value, 0; \
- }
+#define __strict_y(Y, TYPE, PARA_TYPE, HYPER_Y, HYPER_TYPE)\
+ int\
+ strict_##Y(const char *str, TYPE *value, PARA_TYPE min, PARA_TYPE max)\
+ {\
+ HYPER_TYPE intermediate_value;\
+ if (strict_##HYPER_Y(str, &intermediate_value, (HYPER_TYPE)min, (HYPER_TYPE)max) < 0)\
+ return -1;\
+ return *value = (TYPE)intermediate_value, 0;\
+ }
-#define __strict_x(X, TYPE, HYPER_X, HYPER_TYPE) \
- __strict_y(X, TYPE, TYPE, HYPER_X, HYPER_TYPE)
+#define __strict_x(X, TYPE, HYPER_X, HYPER_TYPE)\
+ __strict_y(X, TYPE, TYPE, HYPER_X, HYPER_TYPE)
/**
@@ -577,20 +580,20 @@ __strict_x(atou64, uint64_t, atouj, uintmax_t)
* @param length The length of the buffer
* @return Zero on success, -1 on error
*/
-int full_write(int fd, const char* buffer, size_t length)
+int
+full_write(int fd, const char *buffer, size_t length)
{
- ssize_t wrote;
- while (length > 0)
- {
- errno = 0;
- wrote = write(fd, buffer, length);
- fail_if (errno && (errno != EINTR));
- length -= (size_t)max(wrote, 0);
- buffer += (size_t)max(wrote, 0);
- }
- return 0;
- fail:
- return -1;
+ ssize_t wrote;
+ while (length > 0) {
+ errno = 0;
+ wrote = write(fd, buffer, length);
+ fail_if (errno && errno != EINTR);
+ length -= (size_t)max(wrote, 0);
+ buffer += (size_t)max(wrote, 0);
+ }
+ return 0;
+fail:
+ return -1;
}
@@ -601,44 +604,44 @@ int full_write(int fd, const char* buffer, size_t length)
* @param length Output parameter for the length of the file, may be `NULL`
* @return The content of the file, you will need to free it. `NULL` on error.
*/
-char* full_read(int fd, size_t* length)
+char *
+full_read(int fd, size_t *length)
{
- char* old_buf = NULL;
- size_t buffer_size = 8 << 10;
- size_t buffer_ptr = 0;
- char* buffer;
- ssize_t got;
- int saved_errno;
-
- if (length != NULL)
- *length = 0;
-
- /* Allocate buffer for data. */
- fail_if (xmalloc(buffer, buffer_size, char));
-
- /* Read the file. */
- for (;;)
- {
- /* Grow buffer if it is too small. */
- if (buffer_size == buffer_ptr)
- fail_if (xxrealloc(old_buf, buffer, buffer_size <<= 1, char));
-
- /* Read from the file into the buffer. */
- got = read(fd, buffer + buffer_ptr, buffer_size - buffer_ptr);
- fail_if ((got < 0) && (errno != EINTR));
- if (got == 0)
- break;
- buffer_ptr += (size_t)got;
- }
-
- if (length != NULL)
- *length = buffer_ptr;
- return buffer;
- fail:
- saved_errno = errno;
- free(old_buf);
- free(buffer);
- return errno = saved_errno, NULL;
+ char *old_buf = NULL;
+ size_t buffer_size = 8 << 10;
+ size_t buffer_ptr = 0;
+ char *buffer;
+ ssize_t got;
+ int saved_errno;
+
+ if (length)
+ *length = 0;
+
+ /* Allocate buffer for data. */
+ fail_if (xmalloc(buffer, buffer_size, char));
+
+ /* Read the file. */
+ for (;;) {
+ /* Grow buffer if it is too small. */
+ if (buffer_size == buffer_ptr)
+ fail_if (xxrealloc(old_buf, buffer, buffer_size <<= 1, char));
+
+ /* Read from the file into the buffer. */
+ got = read(fd, buffer + buffer_ptr, buffer_size - buffer_ptr);
+ fail_if (got < 0 && errno != EINTR);
+ if (!got)
+ break;
+ buffer_ptr += (size_t)got;
+ }
+
+ if (length)
+ *length = buffer_ptr;
+ return buffer;
+fail:
+ saved_errno = errno;
+ free(old_buf);
+ free(buffer);
+ return errno = saved_errno, NULL;
}
@@ -650,20 +653,20 @@ char* full_read(int fd, size_t* length)
* @param length The length of the message
* @return Zero on success, -1 on error
*/
-int full_send(int socket, const char* message, size_t length)
+int
+full_send(int socket, const char *message, size_t length)
{
- size_t sent;
+ size_t sent;
- while (length > 0)
- {
- sent = send_message(socket, message, length);
- fail_if ((sent < length) && (errno != EINTR));
- message += sent;
- length -= sent;
- }
- return 0;
- fail:
- return -1;
+ while (length > 0) {
+ sent = send_message(socket, message, length);
+ fail_if (sent < length && errno != EINTR);
+ message += sent;
+ length -= sent;
+ }
+ return 0;
+fail:
+ return -1;
}
@@ -677,17 +680,18 @@ int full_send(int socket, const char* message, size_t length)
* @param needle_n The length of `needle`
* @return Whether the `haystack` begins with `needle`
*/
-int startswith_n(const char* haystack, const char* needle, size_t haystack_n, size_t needle_n)
+int
+startswith_n(const char *haystack, const char *needle, size_t haystack_n, size_t needle_n)
{
- size_t i;
- if (haystack_n < needle_n)
- return 0;
-
- for (i = 0; i < needle_n; i++)
- if (haystack[i] != needle[i])
- return 0;
-
- return 1;
+ size_t i;
+ if (haystack_n < needle_n)
+ return 0;
+
+ for (i = 0; i < needle_n; i++)
+ if (haystack[i] != needle[i])
+ return 0;
+
+ return 1;
}
@@ -700,30 +704,30 @@ int startswith_n(const char* haystack, const char* needle, size_t haystack_n, si
* @param options See description of `options` in the documentation for `waitpid`
* @return See the documentation for `waitpid`
*/
-pid_t uninterruptable_waitpid(pid_t pid, int* restrict status, int options)
+pid_t
+uninterruptable_waitpid(pid_t pid, int *restrict status, int options)
{
- struct timespec time_start;
- struct timespec time_intr;
- int intr_count = 0, have_time;
- pid_t rc;
-
- have_time = (monotone(&time_start) >= 0);
-
- rewait:
- rc = waitpid(pid, status, options);
- if (rc == (pid_t)-1)
- {
- fail_if (errno != EINTR);
- if (have_time && (monotone(&time_intr) >= 0))
- if (time_start.tv_sec != time_intr.tv_sec)
- intr_count = 0;
- if (intr_count++ < 100)
- goto rewait;
- /* Don't let the CPU catch fire! */
- errno = EINTR;
- }
- fail:
- return rc;
+ struct timespec time_start;
+ struct timespec time_intr;
+ int intr_count = 0, have_time;
+ pid_t rc;
+
+ have_time = (monotone(&time_start) >= 0);
+
+rewait:
+ rc = waitpid(pid, status, options);
+ if (rc == (pid_t)-1) {
+ fail_if (errno != EINTR);
+ if (have_time && monotone(&time_intr) >= 0)
+ if (time_start.tv_sec != time_intr.tv_sec)
+ intr_count = 0;
+ if (intr_count++ < 100)
+ goto rewait;
+ /* Don't let the CPU catch fire! */
+ errno = EINTR;
+ }
+fail:
+ return rc;
}
@@ -734,72 +738,71 @@ pid_t uninterruptable_waitpid(pid_t pid, int* restrict status, int options)
* @param allow_modified_nul Whether Modified UTF-8 is allowed, which allows a two-byte encoding for NUL
* @return Zero if good, -1 on encoding error
*/
-int verify_utf8(const char* string, int allow_modified_nul)
+int
+verify_utf8(const char *string, int allow_modified_nul)
{
- static long BYTES_TO_MIN_BITS[] = {0, 0, 8, 12, 17, 22, 37};
- static long BYTES_TO_MAX_BITS[] = {0, 7, 11, 16, 21, 26, 31};
- long bytes = 0, read_bytes = 0, bits = 0, c, character;
-
- /* min bits max bits
- 0....... 0 7
- 110..... 10...... 8 11
- 1110.... 10...... 10...... 12 16
- 11110... 10...... 10...... 10...... 17 21
- 111110.. 10...... 10...... 10...... 10...... 22 26
- 1111110. 10...... 10...... 10...... 10...... 10...... 27 31
- */
-
- while ((c = (long)(*string++)))
- if (read_bytes == 0)
- {
- /* First byte of the character. */
-
- if ((c & 0x80) == 0x00)
- /* Single-byte character. */
- continue;
-
- if ((c & 0xC0) == 0x80)
- /* Single-byte character marked as multibyte, or
- a non-first byte in a multibyte character. */
- return -1;
-
- /* Multibyte character. */
- while ((c & 0x80))
- bytes++, c <<= 1;
- read_bytes = 1;
- character = c & 0x7F;
- if (bytes > 6)
- /* 31-bit characters can be encoded with 6-bytes,
- and UTF-8 does not cover higher code points. */
- return -1;
- }
- else
- {
- /* Not first byte of the character. */
-
- if ((c & 0xC0) != 0x80)
- /* Beginning of new character before a
- multibyte character has ended. */
- return -1;
-
- character = (character << 6) | (c & 0x7F);
-
- if (++read_bytes < bytes)
- /* Not at last byte yet. */
- continue;
-
- /* Check that the character is not unnecessarily long. */
- while (character)
- character >>= 1, bits++;
- bits = ((bits == 0) && (bytes == 2) && allow_modified_nul) ? 8 : bits;
- if ((bits < BYTES_TO_MIN_BITS[bytes]) || (BYTES_TO_MAX_BITS[bytes] < bits))
- return -1;
-
- read_bytes = bytes = bits = 0;
- }
-
- /* Make sure we did not stop at the middle of a multibyte character. */
- return read_bytes == 0 ? 0 : -1;
+ static long BYTES_TO_MIN_BITS[] = {0, 0, 8, 12, 17, 22, 37};
+ static long BYTES_TO_MAX_BITS[] = {0, 7, 11, 16, 21, 26, 31};
+ long bytes = 0, read_bytes = 0, bits = 0, c, character;
+
+ /* min bits max bits
+ 0....... 0 7
+ 110..... 10...... 8 11
+ 1110.... 10...... 10...... 12 16
+ 11110... 10...... 10...... 10...... 17 21
+ 111110.. 10...... 10...... 10...... 10...... 22 26
+ 1111110. 10...... 10...... 10...... 10...... 10...... 27 31
+ */
+
+ while ((c = (long)(*string++))) {
+ if (read_bytes == 0) {
+ /* First byte of the character. */
+
+ if (!(c & 0x80))
+ /* Single-byte character. */
+ continue;
+
+ if ((c & 0xC0) == 0x80)
+ /* Single-byte character marked as multibyte, or
+ a non-first byte in a multibyte character. */
+ return -1;
+
+ /* Multibyte character. */
+ while ((c & 0x80))
+ bytes++, c <<= 1;
+ read_bytes = 1;
+ character = c & 0x7F;
+ if (bytes > 6)
+ /* 31-bit characters can be encoded with 6-bytes,
+ and UTF-8 does not cover higher code points. */
+ return -1;
+ } else {
+ /* Not first byte of the character. */
+
+ if ((c & 0xC0) != 0x80)
+ /* Beginning of new character before a
+ multibyte character has ended. */
+ return -1;
+
+ character = (character << 6) | (c & 0x7F);
+
+ if (++read_bytes < bytes)
+ /* Not at last byte yet. */
+ continue;
+
+ /* Check that the character is not unnecessarily long. */
+ while (character)
+ character >>= 1, bits++;
+ bits = ((bits == 0) && (bytes == 2) && allow_modified_nul) ? 8 : bits;
+ if ((bits < BYTES_TO_MIN_BITS[bytes]) || (BYTES_TO_MAX_BITS[bytes] < bits))
+ return -1;
+
+ read_bytes = bytes = bits = 0;
+ }
+ }
+
+ /* Make sure we did not stop at the middle of a multibyte character. */
+ return read_bytes == 0 ? 0 : -1;
}
@@ -828,85 +831,85 @@ int verify_utf8(const char* string, int allow_modified_nul)
* @param message_id The message ID of this message
* @return The length of the message, zero on error
*/
-size_t construct_error_message(const char* restrict recv_client_id, const char* restrict recv_message_id,
- const char* restrict recv_command, int custom, int errnum,
- const char* restrict message, char** restrict send_buffer,
- size_t* restrict send_buffer_size, uint32_t message_id)
+size_t
+construct_error_message(const char *restrict recv_client_id, const char *restrict recv_message_id,
+ const char *restrict recv_command, int custom, int errnum,
+ const char *restrict message, char **restrict send_buffer,
+ size_t *restrict send_buffer_size, uint32_t message_id)
{
- ssize_t part_length;
- size_t length;
- char* temp;
-
- /* Measure the maximum length of message, including NUL-termination.. */
- length = sizeof("Command: error\n"
- "To: 4294967296:4294967296\n"
- "In response to: 4294967296\n"
- "Origin command: \n"
- "Message ID: 4294967296\n"
- "Error: custom \n"
- "Length: \n"
- "\n") / sizeof(char) + 3 * (sizeof(int)) + strlen(recv_command);
- if (message != NULL)
- length += (sizeof("Length: \n") / sizeof(char) - 1) + 3 * sizeof(char) + strlen(message) + 1;
-
- /* Ensure that the send buffer is large enough. */
- if (length > *send_buffer_size)
- {
- fail_if (yrealloc(temp, *send_buffer, length, char));
- *send_buffer_size = length;
- }
-
- /* Reset `length` to indicate that the currently written
- message has zero in length. */
- length = 0;
-
- /* Start writting the error message, begin with required
- headers, but exclude the error number. */
- sprintf((*send_buffer) + length,
- "Command: error\n"
- "To: %s\n"
- "In response to: %s\n"
- "Origin command: %s\n"
- "Message ID: %"PRIu32"\n"
- "Error: %s%zn",
- recv_client_id, recv_message_id, recv_command,
- message_id, custom ? "custom" : "",
- &part_length),
- length += (size_t)part_length;
-
- /* If the error is custom and has a number we need
- blank space before we write the error number. */
- if (custom && (errnum >= 0))
- (*send_buffer)[length++] = ' ';
-
- /* Add the error number of there is one. */
- if (errnum >= 0)
- sprintf((*send_buffer) + length, "%i%zn", errnum, &part_length),
- length += (size_t)part_length;
-
- /* End the `Error`-header line. */
- (*send_buffer)[length++] = '\n';
-
- /* Add the `Length`-header if there is a description. */
- if (message != NULL)
- sprintf((*send_buffer) + length, "Length: %zu\n%zn",
- strlen(message) + 1, &part_length),
- length += (size_t)part_length + strlen(message) + 1;
-
- /* Add an empty line to mark the end of headers. */
- (*send_buffer)[length++] = '\n';
-
- /* Write the description if there is one. */
- if (message)
- {
- memcpy((*send_buffer) + length, message, strlen(message) * sizeof(char));
- length += strlen(message);
- (*send_buffer)[length++] = '\n';
- }
-
- return length;
- fail:
- return 0;
+ ssize_t part_length;
+ size_t length;
+ char *temp;
+
+ /* Measure the maximum length of message, including NUL-termination.. */
+ length = sizeof("Command: error\n"
+ "To: 4294967296:4294967296\n"
+ "In response to: 4294967296\n"
+ "Origin command: \n"
+ "Message ID: 4294967296\n"
+ "Error: custom \n"
+ "Length: \n"
+ "\n") / sizeof(char) + 3 * (sizeof(int)) + strlen(recv_command);
+ if (message)
+ length += (sizeof("Length: \n") / sizeof(char) - 1) + 3 * sizeof(char) + strlen(message) + 1;
+
+ /* Ensure that the send buffer is large enough. */
+ if (length > *send_buffer_size) {
+ fail_if (yrealloc(temp, *send_buffer, length, char));
+ *send_buffer_size = length;
+ }
+
+ /* Reset `length` to indicate that the currently written
+ message has zero in length. */
+ length = 0;
+
+ /* Start writting the error message, begin with required
+ headers, but exclude the error number. */
+ sprintf((*send_buffer) + length,
+ "Command: error\n"
+ "To: %s\n"
+ "In response to: %s\n"
+ "Origin command: %s\n"
+ "Message ID: %"PRIu32"\n"
+ "Error: %s%zn",
+ recv_client_id, recv_message_id, recv_command,
+ message_id, custom ? "custom" : "",
+ &part_length);
+ length += (size_t)part_length;
+
+ /* If the error is custom and has a number we need
+ blank space before we write the error number. */
+ if (custom && errnum >= 0)
+ (*send_buffer)[length++] = ' ';
+
+ /* Add the error number of there is one. */
+ if (errnum >= 0)
+ sprintf((*send_buffer) + length, "%i%zn", errnum, &part_length),
+ length += (size_t)part_length;
+
+ /* End the `Error`-header line. */
+ (*send_buffer)[length++] = '\n';
+
+ /* Add the `Length`-header if there is a description. */
+ if (message) {
+ sprintf((*send_buffer) + length, "Length: %zu\n%zn",
+ strlen(message) + 1, &part_length);
+ length += (size_t)part_length + strlen(message) + 1;
+ }
+
+ /* Add an empty line to mark the end of headers. */
+ (*send_buffer)[length++] = '\n';
+
+ /* Write the description if there is one. */
+ if (message) {
+ memcpy((*send_buffer) + length, message, strlen(message) * sizeof(char));
+ length += strlen(message);
+ (*send_buffer)[length++] = '\n';
+ }
+
+ return length;
+fail:
+ return 0;
}
@@ -936,17 +939,17 @@ size_t construct_error_message(const char* restrict recv_client_id, const char*
* @param message_id The message ID of this message
* @return Zero on success, -1 on error
*/
-int send_error(const char* restrict recv_client_id, const char* restrict recv_message_id,
- const char* restrict recv_command, int custom, int errnum, const char* restrict message,
- char** restrict send_buffer, size_t* restrict send_buffer_size, uint32_t message_id,
- int socket_fd)
+int
+send_error(const char *restrict recv_client_id, const char *restrict recv_message_id,
+ const char *restrict recv_command, int custom, int errnum, const char *restrict message,
+ char **restrict send_buffer, size_t *restrict send_buffer_size, uint32_t message_id,
+ int socket_fd)
{
- size_t length;
- fail_if ((length = construct_error_message(recv_client_id, recv_message_id, recv_command, custom, errnum,
- message, send_buffer, send_buffer_size, message_id)) == 0);
- fail_if (full_send(socket_fd, *send_buffer, length));
- return 0;
- fail:
- return -1;
+ size_t length;
+ fail_if (!(length = construct_error_message(recv_client_id, recv_message_id, recv_command, custom, errnum,
+ message, send_buffer, send_buffer_size, message_id)));
+ fail_if (full_send(socket_fd, *send_buffer, length));
+ return 0;
+fail:
+ return -1;
}
-