arc/src/agent.c

204 lines
3.3 KiB
C

/******************************************************************************
*
* Copyright (c) 2017-2019 by Löwenware Ltd
* Please, refer LICENSE file for legal information
*
******************************************************************************/
/**
* @file agent.c
* @author Ilja Kartašov <ik@lowenware.com>
* @brief
*
* @see https://lowenware.com/
*/
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <cStuff/string.h>
#include "surgard.h"
#include "log.h"
#include "agent.h"
#define LOG_PREFIX "agent: "
static struct agent **m_agent = NULL;
static int m_count = 0;
static unsigned char m_buffer[ARC_AGENT_BUFFER_SIZE];
static struct agent *
agent__new(AgentType agent_type, const char *name, char *address, char *query)
{
struct agent *result = NULL;
switch (agent_type) {
#ifdef ARC_WITH_SURGARD
case AGENT_TYPE_SURGARD:
result = surgard_new(agent_type, name, address, query);
break;
#endif
default:
break;
}
return result;
}
static void
agent__free(struct agent *agent)
{
switch (agent->agent_type) {
#ifdef ARC_WITH_SURGARD
case AGENT_TYPE_SURGARD:
surgard_free(agent);
break;
#endif
default:
break;
}
if (agent->name) {
free(agent->name);
}
free(agent);
}
static int
agent__run(struct agent *agent, unsigned char *buffer, size_t buf_size)
{
switch (agent->agent_type) {
#ifdef ARC_WITH_SURGARD
case AGENT_TYPE_SURGARD:
return surgard_run(agent, m_buffer, sizeof (m_buffer));
#endif
default:
break;
}
return 1;
}
static AgentType
agent_read_uri(char **p_uri, char **p_query)
{
char *protocol = *p_uri, *address, *query;
if (!(address = strstr(protocol, "://"))) {
return AGENT_TYPE__UNKNOWN;
}
*address = 0;
address += 3;
if ((query = strchr(address, '?'))) {
*(address++) = 0;
}
*p_query = query;
*p_uri = address;
#ifdef ARC_WITH_SURGARD
if (surgard_supports(protocol)) {
return AGENT_TYPE_SURGARD;
}
#endif
*p_uri = protocol;
return AGENT_TYPE__UNKNOWN;
}
struct agent *
agent_alloc(const char *p_name, AgentType agent_type, size_t sz)
{
struct agent *result;
char *name;
if (!cstuff_strcpy(&name, p_name)) {
if ((result = calloc(1, sz))) {
result->name = name;
result->agent_type = agent_type;
return result;
}
free(name);
} else {
result = NULL;
}
return result;
}
void
agent_free(struct agent *agent)
{
if (agent->name)
free(agent->name);
free(agent);
}
int
agent_set(const char *name, char *uri)
{
char *query;
AgentType agent_type;
struct agent **agent;
if (!(agent_type = agent_read_uri(&uri, &query))) {
LOG_ALERT(LOG_PREFIX "unsupported protocol `%s`", uri);
return -1;
}
/* uri = address */
if (!(agent = realloc(m_agent, sizeof (*agent) * (++m_count)))) {
LOG_ALERT(LOG_PREFIX "out of memory (%d ports)", m_count);
m_count--;
return -1;
}
m_agent = agent;
if (!(agent[m_count - 1] = agent__new(agent_type, name, uri, query))) {
return -1;
}
return 0;
}
int
agent_run(void)
{
int result = 1, i, rc;
for (i = 0; i < m_count; i++) {
memset(m_buffer, 0, sizeof (m_buffer));
if (!(rc = agent__run(m_agent[i], m_buffer, sizeof (m_buffer)))) {
result = rc;
}
}
return result;
}
void
agent_unset_all(void)
{
int i;
for (i = 0; i < m_count; i++) {
agent__free(m_agent[i]);
}
if (m_agent) {
free(m_agent);
m_count = 0;
m_agent = NULL;
}
}