<commit_before>/*
 * Daemon that gets requests from remote library backend
 * and forwards them to local session.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <signal.h>
#include "uapi/libct.h"
#include "list.h"
#include "xmalloc.h"
#include "../protobuf/rpc.pb-c.h"

#define MAX_MSG_ONSTACK	2048

struct container_srv {
	struct list_head l;
	unsigned long rid;
	ct_handler_t hnd;
};

static LIST_HEAD(ct_srvs);
static unsigned long rids = 1;

static struct container_srv *find_ct_by_rid(unsigned long rid)
{
	struct container_srv *cs;

	list_for_each_entry(cs, &ct_srvs, l)
		if (cs->rid == rid)
			return cs;

	return NULL;
}

static void send_err_resp(int sk)
{
	RpcResponce resp = RPC_RESPONCE__INIT;
	unsigned char dbuf[MAX_MSG_ONSTACK];
	int len;

	resp.success = false;
	len = rpc_responce__pack(&resp, dbuf);
	if (len > 0)
		send(sk, dbuf, len, 0);
}

static int send_resp(int sk, RpcResponce *resp)
{
	unsigned char dbuf[MAX_MSG_ONSTACK];
	int len;

	resp->success = true;

	/* FIXME -- boundaries check */
	len = rpc_responce__pack(resp, dbuf);
	if (send(sk, dbuf, len, 0) != len)
		return -1;
	else
		return 0;
}

static int serve_ct_create(int sk, libct_session_t ses, CreateReq *req)
{
	struct container_srv *cs;
	RpcResponce resp = RPC_RESPONCE__INIT;
	CreateResp cr = CREATE_RESP__INIT;

	cs = xmalloc(sizeof(*cs));
	if (!cs)
		goto err0;

	cs->hnd = libct_container_create(ses);
	if (!cs->hnd) {
		xfree(cs);
		goto err1;
	}

	cs->rid = rids++;

	resp.create = &cr;
	cr.rid = cs->rid;

	if (send_resp(sk, &resp))
		goto err2;

	list_add_tail(&cs->l, &ct_srvs);
	return 0;

err2:
	libct_container_destroy(cs->hnd);
err1:
	xfree(cs);
err0:
	send_err_resp(sk);
	return -1;
}

static int serve_ct_destroy(int sk, libct_session_t ses, RpcRequest *req)
{
	RpcResponce resp = RPC_RESPONCE__INIT;
	struct container_srv *cs;

	cs = find_ct_by_rid(req->ct_rid);
	if (!cs) {
		send_err_resp(sk);
		return 0;
	}

	list_del(&cs->l);
	libct_container_destroy(cs->hnd);
	xfree(cs);

	return send_resp(sk, &resp);
}

static int serve_get_state(int sk, libct_session_t ses, RpcRequest *req)
{
	RpcResponce resp = RPC_RESPONCE__INIT;
	StateResp gs = STATE_RESP__INIT;
	struct container_srv *cs;

	cs = find_ct_by_rid(req->ct_rid);
	if (!cs) {
		send_err_resp(sk);
		return 0;
	}

	resp.state = &gs;
	gs.state = libct_container_state(cs->hnd);

	return send_resp(sk, &resp);
}

static int serve_spawn(int sk, libct_session_t ses, RpcRequest *req)
{
	RpcResponce resp = RPC_RESPONCE__INIT;
	struct container_srv *cs;
	int ret;

	cs = find_ct_by_rid(req->ct_rid);
	if (!cs || !req->spawn) {
		send_err_resp(sk);
		return 0;
	}

	ret = libct_container_spawn_execv(cs->hnd, req->spawn->path, req->spawn->args);
	if (ret) {
		send_err_resp(sk);
		return 0;
	}

	return send_resp(sk, &resp);
}

static int serve_req(int sk, libct_session_t ses, RpcRequest *req)
{
	switch (req->req) {
	case REQ_TYPE__CT_CREATE:
		return serve_ct_create(sk, ses, req->create);
	case REQ_TYPE__CT_DESTROY:
		return serve_ct_destroy(sk, ses, req);
	case REQ_TYPE__CT_GET_STATE:
		return serve_get_state(sk, ses, req);
	case REQ_TYPE__CT_SPAWN:
		return serve_spawn(sk, ses, req);
	default:
		break;
	}

	return -1;
}

static int serve(int sk)
{
	RpcRequest *req;
	int ret;<commit_msg>libctd: Simplify error reporting to client<commit_after>/*
 * Daemon that gets requests from remote library backend
 * and forwards them to local session.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <signal.h>
#include "uapi/libct.h"
#include "list.h"
#include "xmalloc.h"
#include "../protobuf/rpc.pb-c.h"

#define MAX_MSG_ONSTACK	2048

struct container_srv {
	struct list_head l;
	unsigned long rid;
	ct_handler_t hnd;
};

static LIST_HEAD(ct_srvs);
static unsigned long rids = 1;

static struct container_srv *find_ct_by_rid(unsigned long rid)
{
	struct container_srv *cs;

	list_for_each_entry(cs, &ct_srvs, l)
		if (cs->rid == rid)
			return cs;

	return NULL;
}

static int send_err_resp(int sk, int err)
{
	RpcResponce resp = RPC_RESPONCE__INIT;
	unsigned char dbuf[MAX_MSG_ONSTACK];
	int len;

	resp.success = false;
	len = rpc_responce__pack(&resp, dbuf);
	if (len > 0)
		send(sk, dbuf, len, 0);

	return 0;
}

static int send_resp(int sk, RpcResponce *resp)
{
	unsigned char dbuf[MAX_MSG_ONSTACK];
	int len;

	resp->success = true;

	/* FIXME -- boundaries check */
	len = rpc_responce__pack(resp, dbuf);
	if (send(sk, dbuf, len, 0) != len)
		return -1;
	else
		return 0;
}

static int serve_ct_create(int sk, libct_session_t ses, CreateReq *req)
{
	struct container_srv *cs;
	RpcResponce resp = RPC_RESPONCE__INIT;
	CreateResp cr = CREATE_RESP__INIT;

	cs = xmalloc(sizeof(*cs));
	if (!cs)
		goto err0;

	cs->hnd = libct_container_create(ses);
	if (!cs->hnd) {
		xfree(cs);
		goto err1;
	}

	cs->rid = rids++;

	resp.create = &cr;
	cr.rid = cs->rid;

	if (send_resp(sk, &resp))
		goto err2;

	list_add_tail(&cs->l, &ct_srvs);
	return 0;

err2:
	libct_container_destroy(cs->hnd);
err1:
	xfree(cs);
err0:
	return send_err_resp(sk, -1);
}

static int serve_ct_destroy(int sk, libct_session_t ses, RpcRequest *req)
{
	RpcResponce resp = RPC_RESPONCE__INIT;
	struct container_srv *cs;

	cs = find_ct_by_rid(req->ct_rid);
	if (!cs)
		return send_err_resp(sk, -1);

	list_del(&cs->l);
	libct_container_destroy(cs->hnd);
	xfree(cs);

	return send_resp(sk, &resp);
}

static int serve_get_state(int sk, libct_session_t ses, RpcRequest *req)
{
	RpcResponce resp = RPC_RESPONCE__INIT;
	StateResp gs = STATE_RESP__INIT;
	struct container_srv *cs;

	cs = find_ct_by_rid(req->ct_rid);
	if (!cs)
		return send_err_resp(sk, -1);

	resp.state = &gs;
	gs.state = libct_container_state(cs->hnd);

	return send_resp(sk, &resp);
}

static int serve_spawn(int sk, libct_session_t ses, RpcRequest *req)
{
	RpcResponce resp = RPC_RESPONCE__INIT;
	struct container_srv *cs;
	int ret;

	cs = find_ct_by_rid(req->ct_rid);
	if (!cs || !req->spawn)
		return send_err_resp(sk, -1);

	ret = libct_container_spawn_execv(cs->hnd, req->spawn->path, req->spawn->args);
	if (ret)
		return send_err_resp(sk, -1);

	return send_resp(sk, &resp);
}

static int serve_req(int sk, libct_session_t ses, RpcRequest *req)
{
	switch (req->req) {
	case REQ_TYPE__CT_CREATE:
		return serve_ct_create(sk, ses, req->create);
	case REQ_TYPE__CT_DESTROY:
		return serve_ct_destroy(sk, ses, req);
	case REQ_TYPE__CT_GET_STATE:
		return serve_get_state(sk, ses, req);
	case REQ_TYPE__CT_SPAWN:
		return serve_spawn(sk, ses, req);
	default:
		break;
	}

	return -1;
}

static int serve(int sk)
{
	RpcRequest *req;
	int ret;
{'fraction_non_alphanumeric': 0.13248502994011976, 'fraction_numerical': 0.007035928143712575, 'mean_word_length': 4.609571788413098, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2535178', 'n_tokens_mistral': 2969, 'n_tokens_neox': 2828, 'n_words': 650}