aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/msg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/msg.c')
-rw-r--r--src/msg.c127
1 files changed, 71 insertions, 56 deletions
diff --git a/src/msg.c b/src/msg.c
index 9262f70..863d141 100644
--- a/src/msg.c
+++ b/src/msg.c
@@ -5,29 +5,16 @@
#include <stdlib.h>
#include <string.h>
-void msg_free(const struct msg *msg)
-{
- for (int i = 0; i < msg->argc; ++i)
- free(msg->argv[i]);
- free(msg->argv);
-}
-
-int msg_from_argv(struct msg *msg, const char *argv[])
+static int msg_copy_argv(struct msg *msg, char **argv)
{
- int argc = 0;
-
- for (const char **s = argv; *s; ++s)
- ++argc;
-
- msg->argc = argc;
- msg->argv = calloc(argc, sizeof(char *));
+ msg->argv = calloc(msg->argc, sizeof(char *));
if (!msg->argv) {
print_errno("calloc");
return -1;
}
- for (int i = 0; i < argc; ++i) {
+ for (int i = 0; i < msg->argc; ++i) {
msg->argv[i] = strdup(argv[i]);
if (!msg->argv[i]) {
print_errno("strdup");
@@ -38,25 +25,62 @@ int msg_from_argv(struct msg *msg, const char *argv[])
return 0;
free:
- for (int i = 0; i < argc; ++i)
- if (msg->argv[i])
- free(msg->argv[i]);
- else
- break;
+ msg_free(msg);
- free(msg->argv);
return -1;
}
-static size_t calc_buf_len(int argc, char **argv)
+struct msg *msg_copy(const struct msg *src)
+{
+ struct msg *dest;
+ int ret = 0;
+
+ dest = malloc(sizeof(*dest));
+ if (!dest) {
+ print_errno("calloc");
+ return NULL;
+ }
+ dest->argc = src->argc;
+
+ ret = msg_copy_argv(dest, src->argv);
+ if (ret < 0)
+ goto free;
+
+ return dest;
+
+free:
+ free(dest);
+
+ return NULL;
+}
+
+void msg_free(const struct msg *msg)
+{
+ for (int i = 0; i < msg->argc; ++i)
+ free((char *)msg->argv[i]);
+ free(msg->argv);
+}
+
+int msg_from_argv(struct msg *msg, char **argv)
+{
+ int argc = 0;
+
+ for (char **s = argv; *s; ++s)
+ ++argc;
+
+ msg->argc = argc;
+ return msg_copy_argv(msg, argv);
+}
+
+static size_t calc_buf_len(const struct msg *msg)
{
size_t len = 0;
- for (int i = 0; i < argc; ++i)
- len += strlen(argv[i]) + 1;
+ for (int i = 0; i < msg->argc; ++i)
+ len += strlen(msg->argv[i]) + 1;
return len;
}
-static int calc_arr_len(const void *buf, size_t len)
+static int calc_argv_len(const void *buf, size_t len)
{
int argc = 0;
for (const char *it = buf; it < (const char *)buf + len; it += strlen(it) + 1)
@@ -64,37 +88,39 @@ static int calc_arr_len(const void *buf, size_t len)
return argc;
}
-static void arr_pack(char *dest, int argc, char **argv)
+static void argv_pack(char *dest, const struct msg *msg)
{
- for (int i = 0; i < argc; ++i) {
- strcpy(dest, argv[i]);
- dest += strlen(argv[i]) + 1;
+ for (int i = 0; i < msg->argc; ++i) {
+ strcpy(dest, msg->argv[i]);
+ dest += strlen(msg->argv[i]) + 1;
}
}
-static int arr_unpack(char **argv, int argc, const char *src)
+static int argv_unpack(struct msg *msg, const char *src)
{
- for (int i = 0; i < argc; ++i) {
+ msg->argv = calloc(msg->argc, sizeof(char *));
+ if (!msg->argv) {
+ print_errno("calloc");
+ return -1;
+ }
+
+ for (int i = 0; i < msg->argc; ++i) {
size_t len = strlen(src);
- argv[i] = malloc(len);
- if (!argv[i]) {
+ msg->argv[i] = malloc(len);
+ if (!msg->argv[i]) {
print_errno("malloc");
goto free;
}
- strcpy(argv[i], src);
+ strcpy(msg->argv[i], src);
src += len + 1;
}
return 0;
free:
- for (int i = 0; i < argc; ++i)
- if (argv[i])
- free(argv[i]);
- else
- break;
+ msg_free(msg);
return -1;
}
@@ -103,13 +129,13 @@ int msg_send(int fd, const struct msg *msg)
{
int ret = 0;
- size_t len = calc_buf_len(msg->argc, msg->argv);
+ size_t len = calc_buf_len(msg);
char *buf = malloc(len);
if (!buf) {
print_errno("malloc");
return -1;
}
- arr_pack(buf, msg->argc, msg->argv);
+ argv_pack(buf, msg);
ret = net_send_buf(fd, buf, len);
if (ret < 0)
@@ -146,22 +172,11 @@ int msg_recv(int fd, struct msg *msg)
if (ret < 0)
return ret;
- msg->argc = calc_arr_len(buf, len);
- msg->argv = calloc(msg->argc, sizeof(char *));
- if (!msg->argv) {
- print_errno("calloc");
- ret = -1;
- goto free_buf;
- }
+ msg->argc = calc_argv_len(buf, len);
- ret = arr_unpack(msg->argv, msg->argc, buf);
+ ret = argv_unpack(msg, buf);
if (ret < 0)
- goto free_argv;
-
- goto free_buf;
-
-free_argv:
- free(msg->argv);
+ goto free_buf;
free_buf:
free(buf);