diff --git a/project.mk b/project.mk index f6db044..2788fbc 100644 --- a/project.mk +++ b/project.mk @@ -70,6 +70,8 @@ PROJECT_CFLAGS = -D_POSIX_C_SOURCE=200809L PROJECT_CFLAGS += -D_ISOC99_SOURCE PROJECT_CFLAGS += -D_XOPEN_SOURCE=500 PROJECT_CFLAGS += -D_GNU_SOURCE + +PROJECT_CFLAGS += -DARC_WITH_SURGARD # PROJECT_CFLAGS += -DDEBUG diff --git a/src/agent.c b/src/agent.c index 968b199..7c08e3d 100644 --- a/src/agent.c +++ b/src/agent.c @@ -12,33 +12,192 @@ * * @see https://lowenware.com/ */ - +#include +#include +#include +#include #include "surgard.h" +#include "log.h" #include "agent.h" +#define LOG_PREFIX "agent: " -int -agent_init(void) + +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) { - return 0; + 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_release(void) +agent_free(struct agent *agent) { - + if (agent->name) + free(agent->name); + free(agent); } int -agent_run_cycle(void) +agent_set(const char *name, char *uri) { - int result = 1, rc; + char *query; + AgentType agent_type; + struct agent **agent; - if (!(rc = surgard_run_cycle())) { - result = rc; + 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; + } +} + diff --git a/src/agent.h b/src/agent.h index 232455f..8f02aa7 100644 --- a/src/agent.h +++ b/src/agent.h @@ -16,16 +16,46 @@ #ifndef AGENT_H_D0CDB429_AC49_4BC6_83FA_9163404D387E #define AGENT_H_D0CDB429_AC49_4BC6_83FA_9163404D387E +#include -int -agent_init(void); + +#ifndef ARC_AGENT_BUFFER_SIZE +#define ARC_AGENT_BUFFER_SIZE (4*1024) +#endif + + +typedef enum { + AGENT_TYPE__UNKNOWN +#ifdef ARC_WITH_SURGARD + , AGENT_TYPE_SURGARD +#endif +} AgentType; + + +struct agent { + char *name; + AgentType agent_type; +}; + + +struct agent * +agent_alloc(const char *name, AgentType agent_type, size_t sz); void -agent_release(void); +agent_free(struct agent *agent); int -agent_run_cycle(void); +agent_set(const char *name, char *uri); + + +int +agent_run(void); + + +void +agent_unset_all(void); + #endif /* !AGENT_H */ diff --git a/src/main.c b/src/main.c index d1932e2..b17c16a 100644 --- a/src/main.c +++ b/src/main.c @@ -112,25 +112,21 @@ main(int argc, char **argv) /* Initialize instance */ if ((aisl = aisl_new(&m_cfg)) != NULL) { if (observer_init() == 0) { - if (agent_init() == 0) { - /* launch application loop */ - fprintf(stdout, "Entering main loop"); - for(;;) { - int rc, do_sleep = 1; + /* launch application loop */ + fprintf(stdout, "Entering main loop"); + for(;;) { + int rc, do_sleep = 1; + if ((rc = aisl_run_cycle(aisl)) == AISL_SUCCESS) + do_sleep = 0; + if ((rc = agent_run()) == 0) + do_sleep = 0; - if ((rc = aisl_run_cycle(aisl)) == AISL_SUCCESS) - do_sleep = 0; + if (!do_sleep) + continue; - if ((rc = agent_run_cycle()) == 0) - do_sleep = 0; - - if (!do_sleep) - continue; - - aisl_sleep(aisl, 500); - } - agent_release(); + aisl_sleep(aisl, 500); } + agent_unset_all(); observer_release(); } aisl_free(aisl); diff --git a/src/surgard.c b/src/surgard.c index b0a3125..a954cab 100644 --- a/src/surgard.c +++ b/src/surgard.c @@ -13,13 +13,43 @@ * @see https://lowenware.com/ */ +#include #include "surgard.h" -int -surgard_run_cycle(void) +struct surgard { + struct agent parent; +}; + + +bool +surgard_supports(const char *protocol) { - return 1; + return !strcmp(protocol, "surgard"); } +struct agent * +surgard_new(AgentType agent_type, const char *name, char *address, char *params) +{ + struct agent *agent; + + if ((agent = agent_alloc(name, agent_type, sizeof (struct surgard)))) { + + } + return agent; +} + + +void +surgard_free(struct agent *agent) +{ + agent_free(agent); +} + + +int +surgard_run(struct agent *agent, unsigned char *buffer, size_t buf_sz) +{ + return 1; +} diff --git a/src/surgard.h b/src/surgard.h index 61b6a4b..4b34d59 100644 --- a/src/surgard.h +++ b/src/surgard.h @@ -16,7 +16,22 @@ #ifndef SURGARD_H_0C382373_4757_4FC1_A2DE_991F9D71CDBC #define SURGARD_H_0C382373_4757_4FC1_A2DE_991F9D71CDBC +#include "agent.h" + + +struct agent * +surgard_new(AgentType agent_type, const char *name, char *address, char *params); + + +void +surgard_free(struct agent *agent); + + int -surgard_run_cycle(void); +surgard_run(struct agent *agent, unsigned char *buffer, size_t buf_sz); + + +bool +surgard_supports(const char *protocol); #endif /* !SURGARD_H */