204 lines
3.3 KiB
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;
|
|
}
|
|
}
|
|
|