/****************************************************************************** * * Copyright (c) 2017-2019 by Löwenware Ltd * Please, refer LICENSE file for legal information * ******************************************************************************/ /** * @file agent.c * @author Ilja Kartašov * @brief * * @see https://lowenware.com/ */ #include #include #include #include #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; } }