From 77ebc47a632ddd78ec700fafdb82784d1be635c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilja=20Karta=C5=A1ov?= Date: Tue, 16 Apr 2019 14:26:37 +0200 Subject: [PATCH] Change indent spaces to tabs --- cStuff/log.c | 90 ++++++++-------- cStuff/log.h | 12 +-- cStuff/retcode.h | 8 +- cStuff/string.c | 99 ++++++++++++++++++ cStuff/string.h | 58 +++++++++++ components/mail.c | 235 ++++++++++++++++++++++++++++++++++++++++++ components/mail.h | 65 ++++++++++++ components/query.c | 184 ++++++++++++++++----------------- components/query.h | 12 +-- components/quick.c | 32 ++++++ components/quick.h | 24 +++++ components/validate.c | 119 +++++++++++++++++++++ components/validate.h | 23 +++++ mods/interface.c | 67 ++++++------ mods/interface.h | 28 ++--- mods/mod-feedback.c | 228 ++++++++++++++++++++-------------------- mods/mod-feedback.h | 48 +++++---- 17 files changed, 1001 insertions(+), 331 deletions(-) create mode 100644 cStuff/string.c create mode 100644 cStuff/string.h create mode 100644 components/mail.c create mode 100644 components/mail.h create mode 100644 components/quick.c create mode 100644 components/quick.h create mode 100644 components/validate.c create mode 100644 components/validate.h diff --git a/cStuff/log.c b/cStuff/log.c index af6c3e6..e2b051f 100644 --- a/cStuff/log.c +++ b/cStuff/log.c @@ -19,83 +19,83 @@ void cstuff_log_init(cstuff_log_t self, uint8_t level) { - self->target = stderr; - self->level = level; + self->target = stderr; + self->level = level; } void cstuff_log_release(cstuff_log_t self) { - if (self->target != stderr) - fclose(self->target); + if (self->target != stderr) + fclose(self->target); } cstuff_retcode_t cstuff_log_set_file(cstuff_log_t self, const char * filename) { - FILE * fp; + FILE * fp; - if ( !(fp = fopen(filename, "a")) ) - return CSTUFF_SYSCALL_ERROR; + if ( !(fp = fopen(filename, "a")) ) + return CSTUFF_SYSCALL_ERROR; - self->target = fp; - return CSTUFF_SUCCESS; + self->target = fp; + return CSTUFF_SUCCESS; } int cstuff_log_printf(cstuff_log_t self, uint8_t level, const char * format, ...) { - int result; - va_list vl; + int result; + va_list vl; - va_start(vl, format); - result = cstuff_log_vprintf(self, level, format, vl); - va_end(vl); + va_start(vl, format); + result = cstuff_log_vprintf(self, level, format, vl); + va_end(vl); - return result; + return result; } int cstuff_log_vprintf(cstuff_log_t self, - uint8_t level, - const char * format, - va_list vl) + uint8_t level, + const char * format, + va_list vl) { - int result; + int result; - if (self->level & level) - { - FILE * f = self->target; - char * label; - time_t rawtime; - char strtime[32+1]; - struct tm timeinfo; + if (self->level & level) + { + FILE * f = self->target; + char * label; + time_t rawtime; + char strtime[32+1]; + struct tm timeinfo; - time (&rawtime); - localtime_r (&rawtime, &timeinfo); - strftime (strtime, 32, "%F %T", &timeinfo); + time (&rawtime); + localtime_r (&rawtime, &timeinfo); + strftime (strtime, 32, "%F %T", &timeinfo); - switch (level) - { - case CSTUFF_LOG_ERROR : label = "!!"; break; - case CSTUFF_LOG_ALERT : label = "~!"; break; - case CSTUFF_LOG_DEBUG : label = "**"; break; - default : label = "--"; - } + switch (level) + { + case CSTUFF_LOG_ERROR : label = "!!"; break; + case CSTUFF_LOG_ALERT : label = "~!"; break; + case CSTUFF_LOG_DEBUG : label = "**"; break; + default : label = "--"; + } - result = fprintf(f, "%s %s ", strtime, label); - result += vfprintf(f, format, vl); - fputc('\n', f); - result++; - fflush(f); - } - else - result = 0; + result = fprintf(f, "%s %s ", strtime, label); + result += vfprintf(f, format, vl); + fputc('\n', f); + result++; + fflush(f); + } + else + result = 0; - return result; + return result; } diff --git a/cStuff/log.h b/cStuff/log.h index e2bcea6..ea7efc3 100644 --- a/cStuff/log.h +++ b/cStuff/log.h @@ -30,8 +30,8 @@ struct cstuff_log { - FILE * target; - uint8_t level; + FILE * target; + uint8_t level; }; typedef struct cstuff_log * cstuff_log_t; @@ -54,9 +54,9 @@ cstuff_log_printf(cstuff_log_t self, uint8_t level, const char * format, ...); int -cstuff_log_vprintf(cstuff_log_t self, - uint8_t level, - const char * format, - va_list vl); +cstuff_log_vprintf( cstuff_log_t self, + uint8_t level, + const char * format, + va_list vl ); #endif /* !CSTUFF_LOG_H */ diff --git a/cStuff/retcode.h b/cStuff/retcode.h index 82c425b..4aa5558 100644 --- a/cStuff/retcode.h +++ b/cStuff/retcode.h @@ -18,10 +18,10 @@ typedef enum { - CSTUFF_MALLOC_ERROR = -2 - , CSTUFF_SYSCALL_ERROR = -1 - , CSTUFF_SUCCESS = 0 - , CSTUFF_IDLE = 1 + CSTUFF_MALLOC_ERROR = -2 + , CSTUFF_SYSCALL_ERROR = -1 + , CSTUFF_SUCCESS = 0 + , CSTUFF_IDLE = 1 } cstuff_retcode_t; diff --git a/cStuff/string.c b/cStuff/string.c new file mode 100644 index 0000000..3aa1a91 --- /dev/null +++ b/cStuff/string.c @@ -0,0 +1,99 @@ +/****************************************************************************** + * + * Copyright (c) 2017-2019 by Löwenware Ltd + * Please, refer LICENSE file for legal information + * + ******************************************************************************/ + +/** + * @file string.c + * @author Ilja Kartašov + * @brief cStuff string module implementation + * + * @see https://lowenware.com/ + */ + + +#include "string.h" + +int +cstuff_strcpy(char **out, const char *in) +{ + return cstuff_strncpy(out, in, strlen(in)); +} + + +int +cstuff_strncpy(char **out, const char *in, int len) +{ + char *s; + + if (!(s = malloc( len + 1 ))) + return -1; + + strncpy(s, in, len); + s[len]=0; + + *out = s; + + return len; +} + + +int +cstuff_strset(char **out, const char *in) +{ + return cstuff_strnset(out, in, strlen(in)); +} + + +int +cstuff_strnset(char **out, const char *in, int len) +{ + char *s; + + if (!(s = realloc(*out, len+1))) + return -1; + + strncpy(s, in, len); + s[len] = 0; + + *out = s; + + return len; +} + + +int +cstuff_sprintf(char **out, const char *format, ...) +{ + int result; + va_list vl; + + va_start(vl, format); + result = cstuff_vsprintf(out, format, vl); + va_end(vl); + + return result; +} + + +int +cstuff_vsprintf(char **out, const char *format, va_list args) +{ + int result; + va_list vc; + char tmp, *s; + + va_copy(vc, args); + result = vsprintf(&tmp, 1, format, vc); + va_end(vc); + + if (!(s = malloc(result + 1))) + return -1; + + result = vsprintf(s, result+1, format, args); + + return result; +} + diff --git a/cStuff/string.h b/cStuff/string.h new file mode 100644 index 0000000..daffb55 --- /dev/null +++ b/cStuff/string.h @@ -0,0 +1,58 @@ +/****************************************************************************** + * + * Copyright (c) 2017-2019 by Löwenware Ltd + * Please, refer LICENSE file for legal information + * + ******************************************************************************/ + +/** + * @file string.h + * @author Ilja Kartašov + * @brief String module declarations + * + * @see https://lowenware.com/ + */ + +#ifndef CSTUFF_STRING_H_938B242C_B750_40E9_8B67_A69F2F37EB87 +#define CSTUFF_STRING_H_938B242C_B750_40E9_8B67_A69F2F37EB87 + +#include +#include +#include "retcode.h" + + +/** @brief Copies in string to newly allocated out buffer + * @param out a pointer to an address where new pointer must be stored + * @param in an input string + * @return length of string or -1 if out of memory + */ +int +cstuff_strcpy(char **out, const char *in); + + +int +cstuff_strncpy(char **out, const char *in, int len); + + +/** @brief Overwrites content of out buffer with in string using realloc + * @param out a pointer to an address where new string must be stored + * @param in an input string + * @return length of string or -1 if out of memory + */ +int +cstuff_strset(char **out, const char *in); + + +/** @brief Allocates memory and prints a formatted string into it + * @param out a pointer to an address where new string must be stored + * @param format a format for string (see manual for stdlib sprintf) + * @return length of string or -1 if out of memory + */ +int +cstuff_sprintf(char **out, const char *format, ...); + + +int +cstuff_vsprintf(char **out, const char *format, va_list args); + +#endif /* !CSTUFF_STRING_H */ diff --git a/components/mail.c b/components/mail.c new file mode 100644 index 0000000..dc954c1 --- /dev/null +++ b/components/mail.c @@ -0,0 +1,235 @@ +/****************************************************************************** + * + * Copyright (c) 2017-2019 by Löwenware Ltd + * Please, refer LICENSE file for legal information + * + ******************************************************************************/ + +/** + * @file mail.c + * @author Ilja Kartašov + * @brief Mail sending component source file + * + * @see https://lowenware.com/aisl/ + */ + +#include +#include +#include "mail.h" + + +struct payload +{ + char now[40]; + char *to; + char *from; + char *subject; + char *smtp_user; + char *smtp_pass; + char *smtp_url; + char *data; + size_t offset; + size_t total; +}; + + +static size_t +payload_feed(void *ptr, size_t size, size_t nmemb, void *userp) +{ + struct payload *payload = (struct payload *)userp; + size_t left; + + left = payload->total - payload->offset; + + if (left && (size = size*nmemb)) + { + cf (size > left) + size = left; + + memcpy(ptr, payload->data[payload->offset], size); + payload->offset += size; + + return size; + } + + return 0; +} + + +static void +payload__get_now(char * now, size_t size) +{ + time_t now = time(NULL); + struct tm tm; + + gmtime_r(&now, &tm); + strftime(now, size, "%a, %d %b %Y %H:%M:%S GMT", &tm); +} + + +static char * +payload__get_id(uuid_t uuid, char * server) +{ + size_t sz = strlen(server); + + char * result = malloc( sz + 3 + 36 + 1 ); + + if (result) + { + char * p =result; + *(p++) = '<'; + uuid_unparse(uuid, p); + p += 36; + *(p++) = '@'; + strncpy(p, server, sz); + p += sz; + *(p++) = '>'; + *p = 0; + } + + return result; +} + + +static struct payload * +payload_new(aislx_mail_t mail, const char * server) +{ + size_t total; + struct payload *payload; + + if (!(payload = calloc(1, sizeof(struct payload)))) + goto except; + + payload__get_now(payload->now, sizeof(payload->now)); + + if (cstuff_strcpy(&payload->to, mail->to) == -1) + goto e_cleanup; + + if (cstuff_strcpy(&payload->from, mail->from) == -1) + goto e_cleanup; + + if ( !(payload->message_id = payload__get_id(mail->msg_id, server)) ) + goto e_cleanup; + + total = cstuff_sprintf( &payload->data, AISLX_MAIL_FORMAT + , date + , payload->to + , payload->from + , mail->reply_to + , payload->message_id + , mail->subject + , mail->message ); + + if (!(total > 0)) + goto e_cleanup; + + payload->total = total; + + return payload; + +e_cleanup: + payload_free(payload); + +except: + return payload; +} + + +static void +payload_free(struct payload *payload) +{ + if (payload->data) + free(payload->data); + + free(payload); +} + + +static void * +aislx_mail_execute(void * p_ctx) +{ + void *result = NULL; + struct payload * payload = (struct payload *)p_ctx; + aisl_status_t status = AISL_MALLOC_ERROR; + + CURL *curl; + struct curl_slist *rcpts; + + if ((curl = curl_easy_init()) != NULL) + { + curl_easy_setopt(curl, CURLOPT_USERNAME, payload->smtp_user); + curl_easy_setopt(curl, CURLOPT_PASSWORD, payload->smtp_pass); + curl_easy_setopt(curl, CURLOPT_URL, payload->smtp_url); + curl_easy_setopt(curl, CURLOPT_USE_SSL, (long) CURLUSESSL_ALL); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_feed); + curl_easy_setopt(curl, CURLOPT_READDATA, payload); + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + + curl_easy_setopt(curl, CURLOPT_MAIL_FROM, payload->from); + + if ((rcpts = curl_slist_append(NULL, payload->to)) != NULL) + { + CURLcode res; + + if ((res = curl_easy_perform(curl)) != CURLE_OK) + { + fprintf(stderr, "curl_easy_perform() failed: %s\n" + , curl_easy_strerror(res)); + status = AISL_INPUT_ERROR; + } + else + { + status = AISL_SUCCESS; + } + curl_slist_free_all(rcpts); + } + curl_easy_cleanup(curl); + } + + return result + (int)status; +} + + +aisl_status_t +aislx_mail_send( aislx_mail_t mail, + const char *smtp_server, + const char *smtp_user, + const char *smtp_pass, + int flags ) +{ + struct payload * payload; + + if (!(payload = payload_new(mail, smtp_server))) + return AISL_MALLOC_ERROR; + + if (pthread_create(&mail->thread, NULL, aislx_mail_execute, (void*)payload)) + { + payload_free(payload); + return AISL_SYSCALL_ERROR; + } + + return AISL_SUCCESS; +} + + +aisl_status_t +aislx_mail_get_status(aislx_mail_t mail) +{ + int rc; + void * retval; + + rc = pthread_tryjoin_np(mail->thread, &retval); + + if (rc == 0) + { + rc = (int)(retval-0); + return rc; + } + else + { + return AISL_IDLE; + } +} + diff --git a/components/mail.h b/components/mail.h new file mode 100644 index 0000000..08836c7 --- /dev/null +++ b/components/mail.h @@ -0,0 +1,65 @@ +/****************************************************************************** + * + * Copyright (c) 2017-2019 by Löwenware Ltd + * Please, refer LICENSE file for legal information + * + ******************************************************************************/ + +/** + * @file mail.h + * @author Ilja Kartašov + * @brief Mail sending component header file + * + * @see https://lowenware.com/aisl/ + */ + +#ifndef AISLX_MAIL_H_2738BEC4_CF82_4D77_A41F_0E2615848194 +#define AISLX_MAIL_H_2738BEC4_CF82_4D77_A41F_0E2615848194 + +#include + +#include +#include + + +#ifndef AISLX_MAIL_FORMAT + +#define AISLX_MAIL_FORMAT \ + "Date: %s\r\n" \ + "To: %s\r\n" \ + "From: %s\r\n" \ + "Reply-To: %s\r\n" \ + "Message-ID: %s\r\n" \ + "Subject: %s\r\n" \ + "\r\n" \ + "%s" \ + "\r\n" \ + +#endif + +struct aislx_mail +{ + pthread_t pthread; + const char *to; + const char *from; + const char *subject; + const char *msg; + uuid_t msg_id; +}; + +typedef struct aislx_mail * aislx_mail_t; + + +aisl_status_t +aislx_mail_send( aislx_mail_t mail, + const char *smtp_server, + const char *smtp_user, + const char *smtp_pass, + int flags ); + + +aisl_status_t +aislx_mail_get_status(aislx_mail_t mail); + + +#endif /* !AISLX_MAIL_H */ diff --git a/components/query.c b/components/query.c index 55495c1..a3426f1 100644 --- a/components/query.c +++ b/components/query.c @@ -18,146 +18,146 @@ aisl_status_t aislx_query_init( aislx_query_t query, - size_t total, - aislx_query_on_var on_var, - void * p_ctx ) + size_t total, + aislx_query_on_var on_var, + void * p_ctx ) { - query->on_var = on_var; - query->p_ctx = p_ctx; - query->data = NULL; - query->size = 0; - query->total = 0; - query->separator = 0; + query->on_var = on_var; + query->p_ctx = p_ctx; + query->data = NULL; + query->size = 0; + query->total = 0; + query->separator = 0; - return AISL_SUCCESS; + return AISL_SUCCESS; } void aislx_query_release(aislx_query_t query) { - if (query->data) - free(query->data); + if (query->data) + free(query->data); } static void aislx_query_notify(const char * key, uint32_t k_len, - const cahr * val, uint32_t v_len, - aislx_query_t query) + const cahr * val, uint32_t v_len, + aislx_query_t query) { - if (query->on_var) - { - if (query->on_var(key, k_len, val, v_len, query->p_ctx) != 0) - query->on_var == NULL; - } + if (query->on_var) + { + if (query->on_var(key, k_len, val, v_len, query->p_ctx) != 0) + query->on_var == NULL; + } } static int32_t aislx_query_process(aislx_query_t query, const char * data, int32_t length) { - const char * i = data, - * key = data, - * val = NULL; + const char * i = data, + * key = data, + * val = NULL; - uint32_t k_len = 0; + uint32_t k_len = 0; - size_t result; + size_t result; - for (result=0; result < length; result++) - { - char c; + for (result=0; result < length; result++) + { + char c; - switch( (c = *i) ) - { - case '=': - if (val) - return -1; + switch( (c = *i) ) + { + case '=': + if (val) + return -1; - k_len = i-key; - val = i+1; - break; + k_len = i-key; + val = i+1; + break; - case '&': - case ';' - if (!val) - return -1; + case '&': + case ';' + if (!val) + return -1; - if (!query->separator) - query->separator = c; + if (!query->separator) + query->separator = c; - if (query->separator == c) - { - aislx_query_notify(key, k_len, val, i-val, query); - /* reset parser */ - key = (c == ';') ? i+2 : i+1; - k_len = 0; - val = NULL; - break; - } - } - i++; - } + if (query->separator == c) + { + aislx_query_notify(key, k_len, val, i-val, query); + /* reset parser */ + key = (c == ';') ? i+2 : i+1; + k_len = 0; + val = NULL; + break; + } + } + i++; + } - if (query->total == result) - { - aislx_query_notify(key, k_len, val, i-val, query); - } - else - { - result = (key > i) ? i - data : key - data; - } + if (query->total == result) + { + aislx_query_notify(key, k_len, val, i-val, query); + } + else + { + result = (key > i) ? i - data : key - data; + } - query->total -= result; + query->total -= result; - return result; + return result; } aisl_status_t aislx_query_feed(aislx_query_t query, char * data, int32_t length) { - size_t processed; - char * source; + size_t processed; + char * source; - if (query->data) - { - if (!(source = realloc(query->data, length + query->size))) - return AISL_MALLOC_ERROR; + if (query->data) + { + if (!(source = realloc(query->data, length + query->size))) + return AISL_MALLOC_ERROR; - length += query->size; - query->data = source; - query->size = length; + length += query->size; + query->data = source; + query->size = length; - memcpy(&source[query->size], data, length); - } - else - source = data; + memcpy(&source[query->size], data, length); + } + else + source = data; - processed = aislx_query_process(query, source, length); + processed = aislx_query_process(query, source, length); - if (processed < 0) - return AISL_INPUT_ERROR; + if (processed < 0) + return AISL_INPUT_ERROR; - if (processed < length) - { - char * buffer; + if (processed < length) + { + char * buffer; - length -= processed; - if (!(buffer = malloc(length))) - return AISL_MALLOC_ERROR; + length -= processed; + if (!(buffer = malloc(length))) + return AISL_MALLOC_ERROR; - memcpy(buffer, &source[processed], length); + memcpy(buffer, &source[processed], length); - if (query->data) - free(query->data); + if (query->data) + free(query->data); - query->data = buffer; - query->size = length; - } + query->data = buffer; + query->size = length; + } - return AISL_SUCCESS; + return AISL_SUCCESS; } diff --git a/components/query.h b/components/query.h index 7c4d61c..503063e 100644 --- a/components/query.h +++ b/components/query.h @@ -27,13 +27,13 @@ typedef int struct aislx_query { - aislx_query_on_var on_var; + aislx_query_on_var on_var; - void * p_ctx; - char * data; - size_t size; - size_t total; - char separator; + void * p_ctx; + char * data; + size_t size; + size_t total; + char separator; }; typedef struct aislx_query * aislx_query_t; diff --git a/components/quick.c b/components/quick.c new file mode 100644 index 0000000..8f64fe5 --- /dev/null +++ b/components/quick.c @@ -0,0 +1,32 @@ +/****************************************************************************** + * + * Copyright (c) 2017-2019 by Löwenware Ltd + * Please, refer LICENSE file for legal information + * + ******************************************************************************/ + +/** + * @file quick.c + * @author Ilja Kartašov + * @brief + * + * @see https://lowenware.com/ + */ + +#include "quick.h" + + +aisl_status_t +aislx_quick_response(aisl_stream_t stream, aisl_http_response_t http_response) +{ + aisl_status_t result; + + result = aisl_response(s, http_response, 0); + + if (result == AISL_SUCCESS) + aisl_flush(s); + else + aisl_reject(s); + + return result; +} diff --git a/components/quick.h b/components/quick.h new file mode 100644 index 0000000..dd424bf --- /dev/null +++ b/components/quick.h @@ -0,0 +1,24 @@ +/****************************************************************************** + * + * Copyright (c) 2017-2019 by Löwenware Ltd + * Please, refer LICENSE file for legal information + * + ******************************************************************************/ + +/** + * @file quick.h + * @author Ilja Kartašov + * @brief Quick AISL responses component header file + * + * @see https://lowenware.com/aisl/ + */ + +#ifndef AISLX_QUICK_H_39A26EF5_2352_4D54_A10C_203CBBEDF1DF +#define AISLX_QUICK_H_39A26EF5_2352_4D54_A10C_203CBBEDF1DF + +#include + +aisl_status_t +aislx_quick_response(aisl_stream_t stream, aisl_http_response_t http_response); + +#endif /* !AISLX_QUICK_H */ diff --git a/components/validate.c b/components/validate.c new file mode 100644 index 0000000..b7a6f32 --- /dev/null +++ b/components/validate.c @@ -0,0 +1,119 @@ +/****************************************************************************** + * + * Copyright (c) 2017-2019 by Löwenware Ltd + * Please, refer LICENSE file for legal information + * + ******************************************************************************/ + +/** + * @file validate.c + * @author Ilja Kartašov + * @brief Validation component source file + * + * @see https://lowenware.com/aisl/ + */ + +#include "validate.h" + + +int +aislx_validate_email(const char * value) +{ + const char * at = NULL, + * dot = NULL, + * i = value; + + char c; + + while ( (c = *i) != 0 ) + { + switch(c) + { + case '@': + if (at || i == value) break; + + at = i++; + dot = NULL; + continue; + + case '"': + case '(': + case ')': + case ',': + case ';': + case ':': + case '<': + case '>': + case '[': + case '\\': + case ']': + case ' ': + /* These characters are allowed in double quotes only, but it is not + * implemented in this validator, so we count them as forbidden + */ + break; + + case '!': + case '#': + case '$': + case '%': + case '&': + case '\'': + case '*': + case '+': + case '/': + case '=': + case '?': + case '^': + case '_': + case '`': + case '{': + case '|': + case '}': + case '~': + /* Allowed special local-part characters */ + if (!at) + { + i++; + continue; + } + else + break; + + case '-': + /* Allowed characters */ + i++; + continue; + + case '.': + if (dot && i == dot+1) + break; + + if (at) + { + if (i == at+1 || *(i+1) == 0) + break; + } + else + { + if (i == value || *(i+1) == '@') + break; + } + + dot = i++; + continue; + + default: + if ( isalnum(c) == 0 ) + continue; + + break; + } + return (int)(i-value)+1; + } + + if (!at || !dot) + return -1; + + return 0; +} diff --git a/components/validate.h b/components/validate.h new file mode 100644 index 0000000..74efb75 --- /dev/null +++ b/components/validate.h @@ -0,0 +1,23 @@ +/****************************************************************************** + * + * Copyright (c) 2017-2019 by Löwenware Ltd + * Please, refer LICENSE file for legal information + * + ******************************************************************************/ + +/** + * @file validate.h + * @author Ilja Kartašov + * @brief Validation component header file + * + * @see https://lowenware.com/ + */ + +#ifndef AISLX_VALIDATE_H_5EEF42FB_E99B_4768_AF28_E548CF72D2E6 +#define AISLX_VALIDATE_H_5EEF42FB_E99B_4768_AF28_E548CF72D2E6 + + +int +aislx_validate_email(const char * value); + +#endif /* !AISLX_VALIDATE_H */ diff --git a/mods/interface.c b/mods/interface.c index 677c879..ed1313d 100644 --- a/mods/interface.c +++ b/mods/interface.c @@ -12,63 +12,64 @@ * * @see https://lowenware.com/ */ - +#include +#include #include "interface.h" aisl_mod_ctx_t aisl_mod_ctx_new(aislx_mod_t mod) { - aisl_mod_ctx_t ctx; + aisl_mod_ctx_t ctx; - if ((ctx = calloc(1, mod->ctx_size)) != NULL) - { - ctx->mod = mod; - } + if ((ctx = calloc(1, mod->ctx_size)) != NULL) + { + ctx->mod = mod; + } - return ctx; + return ctx; } void aislx_mod_ctx_free(aislx_mod_ctx_t ctx) { - free(ctx); + free(ctx); } aisl_status_t aislx_mod_on_event(aislx_mod_t mod, aisl_evt_t const evt) { - switch(evt->code) - { - case AISL_EVENT_STREAM_OPEN: - { - aisl_evt_stream_open_t so_evt = (aisl_evt_stream_open_t)evt; - if ( strncmp(so_evt->path, mod->end_point, mod->ep_length) != 0) - return AISL_IDLE; + switch(evt->code) + { + case AISL_EVENT_STREAM_OPEN: + { + aisl_evt_stream_open_t so_evt = (aisl_evt_stream_open_t)evt; + if ( strncmp(so_evt->path, mod->end_point, mod->ep_length) != 0) + return AISL_IDLE; - break; - } + break; + } - case AISL_EVENT_STREAM_HEADER: - case AISL_EVENT_STREAM_INPUT: - case AISL_EVENT_STREAM_REQUEST: - case AISL_EVENT_STREAM_OUTPUT: - case AISL_EVENT_STREAM_CLOSE: - { - aislx_mod_ctx_t ctx = aisl_get_context((aisl_stream_t)evt->source); + case AISL_EVENT_STREAM_HEADER: + case AISL_EVENT_STREAM_INPUT: + case AISL_EVENT_STREAM_REQUEST: + case AISL_EVENT_STREAM_OUTPUT: + case AISL_EVENT_STREAM_CLOSE: + { + aislx_mod_ctx_t ctx = aisl_get_context((aisl_stream_t)evt->source); - if (!ctx) - return AISL_SUCCESS; + if (!ctx) + return AISL_SUCCESS; - if (ctx->mod == mod) - break; - } + if (ctx->mod == mod) + break; + } - default: - return AISL_IDLE; - } + default: + return AISL_IDLE; + } - return mod->on_event(mod, evt); + return mod->on_event(mod, evt); } diff --git a/mods/interface.h b/mods/interface.h index 82a012f..42020b0 100644 --- a/mods/interface.h +++ b/mods/interface.h @@ -20,12 +20,12 @@ #define AISLX_MOD_INIT(MOD, END_POINT) \ - do { \ - ((aislx_mod_t) mod)->end_point = END_POINT; \ - ((aislx_mod_t) mod)->ep_length = strlen(END_POINT); \ - ((aislx_mod_t) mod)->on_stream_event = MOD##_on_event; \ - ((aislx_mod_t) mod)->ctx_size = sizeof(struct context); \ - } while(0) \ + do { \ + ((aislx_mod_t) mod)->end_point = END_POINT; \ + ((aislx_mod_t) mod)->ep_length = strlen(END_POINT); \ + ((aislx_mod_t) mod)->on_stream_event = MOD##_on_event; \ + ((aislx_mod_t) mod)->ctx_size = sizeof(struct context); \ + } while(0) \ /** @brief AISL mod structure pointer @@ -36,17 +36,17 @@ typedef struct aislx_mod * aislx_mod_t; /** @brief Pointer to AISL stream event observer */ typedef aisl_status_t -(* aislx_mod_observer_t)(aislx_mode * aislx_mod_t, aisl_evt_t const evt); +(* aislx_mod_observer_t)(aislx_mod_t mod, aisl_evt_t const evt); /** @brief Root level AISL mod's structure */ struct aislx_mod { - const char * end_point; /**< Root mod's URL or NULL */ - aislx_mod_observer_t on_event; /**< Mod's stream event observer */ - size_t ctx_size; /**< Mod's context size */ - uint8_t ep_length; /**< Mod's context size */ + const char * end_point; /**< Root mod's URL or NULL */ + aislx_mod_observer_t on_event; /**< Mod's stream event observer */ + size_t ctx_size; /**< Mod's context size */ + uint8_t ep_length; /**< Mod's context size */ }; @@ -54,7 +54,7 @@ struct aislx_mod */ struct aislx_mod_ctx { - aislx_mod_t mod; /**< Mod's pointer */ + aislx_mod_t mod; /**< Mod's pointer */ }; /** @brief Root level ASIL mod's context structure pointer @@ -66,8 +66,8 @@ typedef struct aislx_mod_ctx * aislx_mod_ctx_t; * @param mod an instance of #aislx_mod_t * @return pointer to newly allocated #aisl_mox_ctx_t */ -aisl_mod_ctx_t -aisl_mod_ctx_new(aislx_mod_t mod); +aislx_mod_ctx_t +aislx_mod_ctx_new(aislx_mod_t mod); /** @brief Frees previosly allocated #aislx_mod_ctx_t diff --git a/mods/mod-feedback.c b/mods/mod-feedback.c index 60cadfa..412377e 100644 --- a/mods/mod-feedback.c +++ b/mods/mod-feedback.c @@ -21,12 +21,12 @@ struct context { - struct aislx_mod_ctx root; - struct aislx_query qs; - struct aislx_mail mail; + struct aislx_mod_ctx root; + struct aislx_query qs; + struct aislx_mail mail; - char * email; - char * message; + char * email; + char * msg; }; typedef struct context * context_t; @@ -35,196 +35,206 @@ typedef struct context * context_t; static void context_free(context_t ctx) { - aislx_query_release(&ctx->qs); - aislx_mail_release(&ctx->mail); + aislx_query_release(&ctx->qs); + aislx_mail_release(&ctx->mail); - if (ctx->email) - free(ctx->email); + if (ctx->email) + free(ctx->email); - if (ctx->message) - free(ctx->message); + if (ctx->msg) + free(ctx->msg); - aislx_mod_ctx_free(ctx); + aislx_mod_ctx_free(ctx); } static int -on_input_var( const char * key, int k_len, - const char * val, int v_len, - void * p_ctx ) +on_input_var( const char *key, int k_len, + const char *val, int v_len, + void *p_ctx ) { - context_t ctx = (context_t) p_ctx; - aislx_mod_feedback_t mod = (aislx_mod_feedback_t)((aislx_mod_ctx_t)ctx)->mod; + context_t ctx = (context_t) p_ctx; + aislx_mod_feedback_t mod = (aislx_mod_feedback_t)((aislx_mod_ctx_t)ctx)->mod; - if (!ctx->email && k_len == mod->name_email_length) - { - if (strncmp(key, mod->name_email, k_len)==0) - return cstuff_strncpy(&ctx->email, val, v_len); - } + if (!ctx->email && k_len == mod->name_email_length) + { + if (strncmp(key, mod->name_email, k_len)==0) + return cstuff_strncpy(&ctx->email, val, v_len); + } - if (!ctx->message && k_len == mod->name_message_length) - { - if (strncmp(key, mod->name_message, k_len)==0) - return cstuff_strncpy(&ctx->message, val, v_len); - } + if (!ctx->msg && k_len == mod->name_msg_length) + { + if (strncmp(key, mod->name_msg, k_len)==0) + return cstuff_strncpy(&ctx->msg, val, v_len); + } - return 0; + return 0; } static aisl_status_t on_stream_open(aislx_mod_feedback_t mod, aisl_evt_stream_open_t const evt) { - context_t ctx; - aisl_stream_t s = (aisl_stream_t) (evt->evt.source); + context_t ctx; + aisl_stream_t s = (aisl_stream_t) (evt->evt.source); - if (!(ctx = (context_t)aislx_mod_ctx_new(mod))) - return AISL_MALLOC_ERROR; + if (!(ctx = (context_t)aislx_mod_ctx_new(mod))) + return AISL_MALLOC_ERROR; - ctx->mail.from = mod->mail_from; - ctx->mail.subject = mod->mail_subject; - ctx->mail.smtp_server = mod->smtp_server; - ctx->mail.smtp_user = mod->smtp_user; - ctx->mail.smtp_password = mod->smtp_password; - ctx->mail.smtp_port = mod->smtp_port; + if (aislx_mail_init(&ctx->mail) != 0) + goto except; - aisl_set_context(s, ctx); + ctx->mail.from = mod->mail_from; + ctx->mail.reply_to = mod->mail_reply_to; + ctx->mail.subject = mod->mail_subject; + ctx->mail.smtp_server = mod->smtp_server; + ctx->mail.smtp_user = mod->smtp_user; + ctx->mail.smtp_password = mod->smtp_password; + ctx->mail.smtp_port = mod->smtp_port; - return AISL_SUCCESS; + aisl_set_context(s, ctx); + + return AISL_SUCCESS; + +except: + context_free(ctx); + return AISL_MALLOC_ERROR; } static aisl_status_t on_stream_header(aislx_mod_feedback_t mod, aisl_evt_stream_header_t const evt) { - if (strcmp(evt->key, "content-length")==0) - { - size_t total = strtoll(evt->value, NULL, 10); + if (strcmp(evt->key, "content-length")==0) + { + size_t total = strtoll(evt->value, NULL, 10); - if(aislx_query_init(&ctx->qs, total, on_input_var, (void*)ctx) != 0) - { - aisl_stream_t s = (aisl_stream_source_t)evt->source; - aislx_quick_response(s, AISL_HTTP_INTERNAL_SERVER_ERROR); - } - } - return AISL_SUCCESS; + if(aislx_query_init(&ctx->qs, total, on_input_var, (void*)ctx) != 0) + { + aisl_stream_t s = (aisl_stream_source_t)evt->source; + aislx_quick_response(s, AISL_HTTP_INTERNAL_SERVER_ERROR); + } + } + return AISL_SUCCESS; } static aisl_status_t on_stream_input(aislx_mod_feedback_t mod, aisl_evt_stream_input_t const evt) { - context_t ctx = aisl_get_context((aisl_stream_t)evt->evt.source); + context_t ctx = aisl_get_context((aisl_stream_t)evt->evt.source); - aislx_query_feed(ctx->qs, evt->data, evt->size); + aislx_query_feed(ctx->qs, evt->data, evt->size); - return AISL_SUCCESS; + return AISL_SUCCESS; } static aisl_status_t on_stream_request(aislx_mod_feedback_t mod, aisl_evt_t const evt) { - context_t ctx = aisl_get_context((aisl_stream_t)evt->evt.source); - aisl_stream_t s = (aisl_stream_t)evt->source; + context_t ctx = aisl_get_context((aisl_stream_t)evt->evt.source); + aisl_stream_t s = (aisl_stream_t)evt->source; - /* finalize input */ - aislx_query_flush(ctx->qs); + /* finalize input */ + aislx_query_flush(ctx->qs); - /* verify input */ - if (!ctx->email || !ctx->message || aislx_validate_email(ctx->email) != 0) - aislx_quick_response(s, AISL_HTTP_BAD_REQUEST); + /* verify input */ + if (!ctx->email || !ctx->msg || aislx_validate_email(ctx->email) != 0) + aislx_quick_response(s, AISL_HTTP_BAD_REQUEST); - ctx->mail.to = ctx->email; - ctx->mail.message = ctx->message; + ctx->mail.to = ctx->email; + ctx->mail.msg = ctx->msg; + uuid_generate(ctx->mail.msg_id); - /* create thread */ - if (aislx_mail_send(&ctx->mail) != AISL_SUCCESS) - aislx_quick_response(s, AISL_HTTP_INTERNAL_SERVER_ERROR); + /* create thread */ + if (aislx_mail_send(&ctx->mail) != AISL_SUCCESS) + aislx_quick_response(s, AISL_HTTP_INTERNAL_SERVER_ERROR); - aisl_set_output_event(s, true); /**< enable output event */ + aisl_set_output_event(s, true); /**< enable output event */ - return AISL_SUCCESS; + return AISL_SUCCESS; } static aisl_status_t on_stream_output(aislx_mod_feedback_t mod, aisl_evt_t const evt) { - context_t ctx = aisl_get_context((aisl_stream_t)evt->evt.source); + context_t ctx = aisl_get_context((aisl_stream_t)evt->evt.source); - aisl_http_response_t rc = AISL_HTTP_OK; + aisl_http_response_t rc = AISL_HTTP_OK; - switch (aislx_mail_get_status(&ctx->mail)) - { - case AISL_SUCCESS: break; - case AISL_IDLE: return AISL_SUCCESS; + switch (aislx_mail_get_status(&ctx->mail)) + { + case AISL_SUCCESS: break; + case AISL_IDLE: return AISL_SUCCESS; - default: - rc = AISL_HTTP_INTERNAL_SERVER_ERROR; - } + default: + rc = AISL_HTTP_INTERNAL_SERVER_ERROR; + } - aislx_quick_response((aisl_stream_t)evt->source, rc); + aislx_quick_response((aisl_stream_t)evt->source, rc); - return AISL_SUCCESS; + return AISL_SUCCESS; } static aisl_status_t on_stream_close(aislx_mod_feedback_t mod, aisl_evt_t const evt) { - context_free((context_t)aisl_get_context((aisl_stream_t)evt->evt.source)); - return AISL_SUCCESS; + context_free((context_t)aisl_get_context((aisl_stream_t)evt->evt.source)); + return AISL_SUCCESS; } static aisl_status_t aislx_mod_feedback_on_event(aislx_mod_feedback_t mod, aisl_evt_t const evt) { - switch(evt->code) - { - case AISL_EVENT_STREAM_OPEN: - return on_stream_open(mod, (aisl_evt_stream_open_t)evt); + switch(evt->code) + { + case AISL_EVENT_STREAM_OPEN: + return on_stream_open(mod, (aisl_evt_stream_open_t)evt); - case AISL_EVENT_STREAM_HEADER: - return on_stream_header(mod, (aisl_evt_stream_header_t)evt); + case AISL_EVENT_STREAM_HEADER: + return on_stream_header(mod, (aisl_evt_stream_header_t)evt); - case AISL_EVENT_STREAM_INPUT: - return on_stream_input(mod, (aisl_evt_stream_input_t)evt); + case AISL_EVENT_STREAM_INPUT: + return on_stream_input(mod, (aisl_evt_stream_input_t)evt); - case AISL_EVENT_STREAM_REQUEST: - return on_stream_request(mod, evt); + case AISL_EVENT_STREAM_REQUEST: + return on_stream_request(mod, evt); - case AISL_EVENT_STREAM_OUTPUT: - return on_stream_output(mod, evt); + case AISL_EVENT_STREAM_OUTPUT: + return on_stream_output(mod, evt); - case AISL_EVENT_STREAM_CLOSE: - return on_stream_close(mod, evt); + case AISL_EVENT_STREAM_CLOSE: + return on_stream_close(mod, evt); - default: - return AISL_IDLE; - } + default: + return AISL_IDLE; + } } aisl_status_t aislx_mod_feedback_init(aislx_mod_feedback_t mod, aislx_mod_feedback_cfg_t cfg) { - AISLX_MOD_INIT(aislx_mod_feedback, cfg->end_point); + AISLX_MOD_INIT(aislx_mod_feedback, cfg->end_point); - mod->mail_subject = cfg->mail_subject; - mod->mail_from = cfg->mail_from; - mod->name_email = cfg->name_email; - mod->name_message = cfg->name_message; - mod->smtp_server = cfg->smtp_server; - mod->smtp_user = cfg->smtp_user; - mod->smtp_password = cfg->smtp_password; - mod->smtp_port = cfg->smtp_port; + mod->mail_subject = cfg->mail_subject; + mod->mail_from = cfg->mail_from; + mod->mail_reply_to = cfg->mail_reply_to; + mod->name_email = cfg->name_email; + mod->name_msg = cfg->name_msg; + mod->smtp_server = cfg->smtp_server; + mod->smtp_user = cfg->smtp_user; + mod->smtp_password = cfg->smtp_password; + mod->smtp_port = cfg->smtp_port; - mod->name_email_length = strlen(cfg->name_email); - mod->name_message_length = strlen(cfg->name_message); + mod->name_email_length = strlen(cfg->name_email); + mod->name_msg_length = strlen(cfg->name_msg); - return AISL_SUCCESS; + return AISL_SUCCESS; } diff --git a/mods/mod-feedback.h b/mods/mod-feedback.h index 111e1a5..4cd8338 100644 --- a/mods/mod-feedback.h +++ b/mods/mod-feedback.h @@ -21,33 +21,36 @@ struct aislx_mod_feedback_cfg { - const char * end_point; - const char * mail_subject; - const char * mail_from; - const char * name_email; - const char * name_message; - const char * smtp_server; - const char * smtp_user; - const char * smtp_password; - uint16_t smtp_port; - + const char *end_point; + const char *mail_subject; + const char *mail_from; + const char *mail_to; + const char *name_email; + const char *name_msg; + const char *smtp_host; + const char *smtp_user; + const char *smtp_pass; + uint16_t smtp_port; }; +typedef struct aislx_mod_feedback_cfg * aislx_mod_feedback_cfg_t; + + struct aislx_mod_feedback { - struct aislx_mod root; + struct aislx_mod root; - const char * mail_subject; - const char * mail_from; - const char * name_email; - const char * name_message; - const char * smtp_server; - const char * smtp_user; - const char * smtp_password; - uint16_t smtp_port; + const char *mail_subject; + const char *mail_from; + const char *name_email; + const char *name_msg; + const char *smtp_host; + const char *smtp_user; + const char *smtp_pass; + uint16_t smtp_port; - uint16_t name_email_length; - uint16_t name_message_length; + uint16_t name_email_length; + uint16_t name_msg_length; }; @@ -55,7 +58,8 @@ typedef struct aislx_mod_feedback * aislx_mod_feedback_t; aisl_status_t -aislx_mod_feedback_init(aislx_mod_feedback_t mod, aislx_mod_feedback_cfg_t cfg); +aislx_mod_feedback_init(aislx_mod_feedback_t mod, + aislx_mod_feedback_cfg_t cfg); void