/*
* Copyright (c) 2023 Egor Tensin <Egor.Tensin@gmail.com>
* This file is part of the "cimple" project.
* For details, see https://github.com/egor-tensin/cimple.
* Distributed under the MIT License.
*/
#include "protocol.h"
#include "base64.h"
#include "const.h"
#include "log.h"
#include "msg.h"
#include "process.h"
#include "run_queue.h"
#include "string.h"
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
static int check_msg_length(const struct msg *msg, size_t expected)
{
size_t actual = msg_get_length(msg);
if (actual != expected) {
log_err("Invalid number of arguments for a message: %zu\n", actual);
msg_dump(msg);
return -1;
}
return 0;
}
int msg_run_parse(const struct msg *msg, struct run **run)
{
int ret = check_msg_length(msg, 3);
if (ret < 0)
return ret;
const char **argv = msg_get_strings(msg);
/* We don't know the ID yet. */
return run_create(run, 0, argv[1], argv[2]);
}
int msg_new_worker_create(struct msg **msg)
{
static const char *argv[] = {CMD_NEW_WORKER, NULL};
return msg_from_argv(msg, argv);
}
int msg_start_create(struct msg **msg, const struct run *run)
{
char id[16];
snprintf(id, sizeof(id), "%d", run_get_id(run));
const char *argv[] = {CMD_START, id, run_get_url(run), run_get_rev(run), NULL};
return msg_from_argv(msg, argv);
}
int msg_start_parse(const struct msg *msg, struct run **run)
{
int ret = 0;
ret = check_msg_length(msg, 4);
if (ret < 0)
return ret;
const char **argv = msg_get_strings(msg);
int id = 0;
ret = string_to_int(argv[1], &id);
if (ret < 0)
return ret;
return run_create(run, id, argv[2], argv[3]);
}
int msg_finished_create(struct msg **msg, int run_id, const struct proc_output *output)
{
int ret = 0;
char id[16];
char ec[16];
snprintf(id, sizeof(id), "%d", run_id);
snprintf(ec, sizeof(ec), "%d", output->ec);
char *b64data = NULL;
ret = base64_encode(output->data, output->data_size, &b64data);
if (ret < 0)
return ret;
const char *argv[] = {CMD_FINISHED, id, ec, b64data, NULL};
ret = msg_from_argv(msg, argv);
if (ret < 0)
goto free_b64data;
free_b64data:
free(b64data);
return ret;
}
int msg_finished_parse(const struct msg *msg, int *run_id, struct proc_output **_output)
{
int ret = 0;
ret = check_msg_length(msg, 4);
if (ret < 0)
return ret;
const char **argv = msg_get_strings(msg);
struct proc_output *output = NULL;
ret = proc_output_create(&output);
if (ret < 0)
return ret;
ret = string_to_int(argv[1], run_id);
if (ret < 0)
goto free_output;
ret = string_to_int(argv[2], &output->ec);
if (ret < 0)
goto free_output;
const char *b64data = argv[3];
ret = base64_decode(b64data, &output->data, &output->data_size);
if (ret < 0)
goto free_output;
*_output = output;
return ret;
free_output:
proc_output_destroy(output);
return ret;
}