Add clang-tidy target and fix problems

This commit is contained in:
Tobias Reisinger 2020-11-13 02:06:48 +01:00
parent fca35ade9e
commit f97b149376
25 changed files with 199 additions and 115 deletions

2
.clang-tidy Normal file
View file

@ -0,0 +1,2 @@
---
Checks: 'clang-diagnostics-*,clang-analyzer-*,linuxkernel-*,modernize-*'

View file

@ -7,6 +7,7 @@ add_executable(core src/main.c)
target_link_libraries(core -lsqlite3) target_link_libraries(core -lsqlite3)
target_link_libraries(core -luuid) target_link_libraries(core -luuid)
target_link_libraries(core -lbsd)
set(CMAKE_C_FLAGS "$ENV{CFLAGS}") set(CMAKE_C_FLAGS "$ENV{CFLAGS}")
set(CMAKE_C_FLAGS "-D'__FILENAME__=\"$(subst $(realpath ${CMAKE_SOURCE_DIR}/src/)/,,$(abspath $<))\"'") set(CMAKE_C_FLAGS "-D'__FILENAME__=\"$(subst $(realpath ${CMAKE_SOURCE_DIR}/src/)/,,$(abspath $<))\"'")
@ -14,6 +15,12 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -std=gnu99 -Wpedantic -Werror -Wall -Wex
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g -fprofile-arcs -ftest-coverage") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g -fprofile-arcs -ftest-coverage")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
file(GLOB_RECURSE ALL_SOURCE_FILES src/*.c)
add_definitions("-DMG_ENABLE_EXTRA_ERRORS_DESC -DMG_ENABLE_MQTT_BROKER") add_definitions("-DMG_ENABLE_EXTRA_ERRORS_DESC -DMG_ENABLE_MQTT_BROKER")
aux_source_directory(src/ SRC_DIR) aux_source_directory(src/ SRC_DIR)
@ -88,4 +95,18 @@ IF(CMAKE_BUILD_TYPE MATCHES Debug)
DEPENDS core DEPENDS core
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests
) )
add_custom_target(
clang-tidy
COMMAND /usr/bin/clang-tidy
${ALL_SOURCE_FILES}
--header-filter=${CMAKE_SOURCE_DIR}/include/*
--
-std=gnu99
-I${CMAKE_SOURCE_DIR}/include
-I${CMAKE_SOURCE_DIR}/vendor
-I${CMAKE_BINARY_DIR}
-DMG_ENABLE_EXTRA_ERRORS_DESC
-DMG_ENABLE_MQTT_BROKER
)
ENDIF(CMAKE_BUILD_TYPE MATCHES Debug) ENDIF(CMAKE_BUILD_TYPE MATCHES Debug)

View file

@ -2,6 +2,7 @@
#define CORE_CONTANTS_H #define CORE_CONTANTS_H
#define SECONDS_PER_DAY 86400 // 60 * 60 * 24 #define SECONDS_PER_DAY 86400 // 60 * 60 * 24
#define DAYS_PER_WEEK 7
#define SECONDS_PER_MINUTE 60 #define SECONDS_PER_MINUTE 60
@ -22,5 +23,8 @@
#define PIFACE_GPIO_BASE 200 #define PIFACE_GPIO_BASE 200
#define DEFAULT_CONFIG_PATH "emgauwa-core.ini" #define DEFAULT_CONFIG_PATH "emgauwa-core.ini"
#define DEFAULT_DISCOVERY_PORT 4421
#define DEFAULT_MQTT_PORT 1885
#define DEFAULT_SERVER_PORT 5000
#endif /* CORE_CONTANTS_H */ #endif /* CORE_CONTANTS_H */

View file

@ -10,6 +10,10 @@
#define LOG_NONE INT_MAX #define LOG_NONE INT_MAX
#ifndef __FILENAME__
#define __FILENAME__ __FILE__
#endif
void void
logger_log(int level, const char *filename, int line, const char *func, const char *msg, ...); logger_log(int level, const char *filename, int line, const char *func, const char *msg, ...);

View file

@ -65,4 +65,10 @@ schedule_uid_parse(const char *uid_str, uuid_t result);
void void
schedule_uid_unparse(const uuid_t uid, char *result); schedule_uid_unparse(const uuid_t uid, char *result);
void
schedule_get_uid_off(uuid_t target);
void
schedule_get_uid_on(uuid_t target);
#endif /* CORE_SCHEDULE_H */ #endif /* CORE_SCHEDULE_H */

View file

@ -1,9 +1,11 @@
#include <bsd/string.h>
#include <cache.h> #include <cache.h>
#include <logger.h> #include <logger.h>
#include <sql/cache.h>
#include <models/macro_action.h>
#include <models/junction_tag.h>
#include <models/junction_relay_schedule.h> #include <models/junction_relay_schedule.h>
#include <models/junction_tag.h>
#include <models/macro_action.h>
#include <sql/cache.h>
sqlite3 *cache_database; sqlite3 *cache_database;
@ -25,8 +27,14 @@ cache_get_value(char *key)
if (s == SQLITE_ROW) if (s == SQLITE_ROW)
{ {
const char *found_value = (const char *)sqlite3_column_text(stmt, 0); const char *found_value = (const char *)sqlite3_column_text(stmt, 0);
result = (char*)malloc(sizeof(char) * (strlen(found_value) + 1)); size_t found_value_len = sqlite3_column_bytes(stmt, 0);
strcpy(result, found_value);
if(result)
{
free(result);
}
result = (char*)malloc(sizeof(char) * (found_value_len + 1));
strlcpy(result, found_value, found_value_len + 1);
} }
else else
{ {

View file

@ -35,7 +35,7 @@ cli_parse(int argc, const char **argv, config_t *config)
"\nA brief description of what the program does and how it works.", "\nA brief description of what the program does and how it works.",
"\nAdditional description of the program after the description of the arguments." "\nAdditional description of the program after the description of the arguments."
); );
argc = argparse_parse(&argparse, argc, argv); argparse_parse(&argparse, argc, argv);
if(config_file) if(config_file)
{ {

View file

@ -221,12 +221,12 @@ command_send(controller_t *controller, char *payload, uint32_t payload_size)
return 1; return 1;
} }
if((bytes_transferred = send(fd_controller, &payload_size, sizeof(payload_size), 0)) <= 0) if(send(fd_controller, &payload_size, sizeof(payload_size), 0) <= 0)
{ {
LOGGER_ERR("error during sending size\n"); LOGGER_ERR("error during sending size\n");
return 1; return 1;
} }
if((bytes_transferred = send(fd_controller, payload, payload_size, 0)) <= 0) if(send(fd_controller, payload, payload_size, 0) <= 0)
{ {
LOGGER_ERR("error during sending\n"); LOGGER_ERR("error during sending\n");
return 1; return 1;

View file

@ -1,5 +1,5 @@
#include <bsd/string.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <config.h> #include <config.h>
#include <constants.h> #include <constants.h>
@ -86,9 +86,9 @@ config_init()
config_load_string(&global_config->file, DEFAULT_CONFIG_PATH); config_load_string(&global_config->file, DEFAULT_CONFIG_PATH);
global_config->discovery_port = 4421; global_config->discovery_port = DEFAULT_DISCOVERY_PORT;
global_config->mqtt_port = 1885; global_config->mqtt_port = DEFAULT_MQTT_PORT;
global_config->server_port = 5000; global_config->server_port = DEFAULT_SERVER_PORT;
global_config->log_level = LOG_DEBUG; global_config->log_level = LOG_DEBUG;
global_config->log_file = stdout; global_config->log_file = stdout;
@ -130,8 +130,7 @@ config_load_string(char **holder, const char *value)
size_t value_len = strlen(value); size_t value_len = strlen(value);
char *new_holder = malloc(sizeof(char) * (value_len + 1)); char *new_holder = malloc(sizeof(char) * (value_len + 1));
strcpy(new_holder, value); strlcpy(new_holder, value, value_len + 1);
new_holder[value_len] = '\0';
*holder = new_holder; *holder = new_holder;
} }

View file

@ -1,3 +1,4 @@
#include <bsd/string.h>
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
@ -192,6 +193,10 @@ database_helper_get_ids(sqlite3_stmt *stmt)
} }
else else
{ {
if(result)
{
free(result);
}
LOGGER_ERR("error selecting ids from database: %s\n", sqlite3_errstr(s)); LOGGER_ERR("error selecting ids from database: %s\n", sqlite3_errstr(s));
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
return NULL; return NULL;
@ -218,8 +223,14 @@ database_helper_get_string(sqlite3_stmt *stmt)
if (s == SQLITE_ROW) if (s == SQLITE_ROW)
{ {
const char *found_string = (const char *)sqlite3_column_text(stmt, 0); const char *found_string = (const char *)sqlite3_column_text(stmt, 0);
result = (char*)malloc(sizeof(char) * (strlen(found_string) + 1)); size_t found_string_len = sqlite3_column_bytes(stmt, 0);
strcpy(result, found_string);
if(result)
{
free(result);
}
result = (char*)malloc(sizeof(char) * (found_string_len + 1));
strlcpy(result, found_string, found_string_len + 1);
} }
else else
{ {
@ -229,6 +240,10 @@ database_helper_get_string(sqlite3_stmt *stmt)
} }
else else
{ {
if(result)
{
free(result);
}
LOGGER_ERR("error selecting string from database: %s\n", sqlite3_errstr(s)); LOGGER_ERR("error selecting string from database: %s\n", sqlite3_errstr(s));
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
return NULL; return NULL;
@ -256,12 +271,12 @@ database_helper_get_strings(sqlite3_stmt *stmt)
if (s == SQLITE_ROW) if (s == SQLITE_ROW)
{ {
const char *new_string = (const char *)sqlite3_column_text(stmt, 0); const char *new_string = (const char *)sqlite3_column_text(stmt, 0);
int new_string_len = strlen(new_string); size_t new_string_len = sqlite3_column_bytes(stmt, 0);
row++; row++;
result = (char**)realloc(result, sizeof(char*) * (row + 1)); result = (char**)realloc(result, sizeof(char*) * (row + 1));
result[row - 1] = malloc(sizeof(char) * (new_string_len + 1)); result[row - 1] = malloc(sizeof(char) * (new_string_len + 1));
strcpy(result[row - 1], new_string); strlcpy(result[row - 1], new_string, new_string_len + 1);
} }
else else
{ {

View file

@ -1,3 +1,5 @@
#include <bsd/string.h>
#include <cJSON.h> #include <cJSON.h>
#include <macros.h> #include <macros.h>
#include <constants.h> #include <constants.h>
@ -172,7 +174,7 @@ api_v1_controllers_discover_PUT(struct mg_connection *nc, struct http_message *h
char *answer_payload = (char*)malloc((payload_length)); char *answer_payload = (char*)malloc((payload_length));
ssize_t bytes_transferred; ssize_t bytes_transferred;
if((bytes_transferred = recv(client_fd, answer_payload, payload_length, 0)) <= 0) if(recv(client_fd, answer_payload, payload_length, 0) <= 0)
{ {
LOGGER_ERR("error receiving payload from client\n"); LOGGER_ERR("error receiving payload from client\n");
continue; continue;
@ -219,8 +221,8 @@ api_v1_controllers_discover_PUT(struct mg_connection *nc, struct http_message *h
LOGGER_DEBUG("rediscovered a known controller at %s\n", inet_ntoa(addr.sin_addr)); LOGGER_DEBUG("rediscovered a known controller at %s\n", inet_ntoa(addr.sin_addr));
known_controllers[i]->active = 1; known_controllers[i]->active = 1;
strncpy(known_controllers[i]->name, discovered_name, discovered_name_len); strlcpy(known_controllers[i]->name, discovered_name, discovered_name_len + 1);
strcpy(known_controllers[i]->ip, inet_ntoa(addr.sin_addr)); strlcpy(known_controllers[i]->ip, inet_ntoa(addr.sin_addr), IP_LENGTH + 1);
known_controllers[i]->name[discovered_name_len] = '\0'; known_controllers[i]->name[discovered_name_len] = '\0';
known_controllers[i]->port = discovered_command_port; known_controllers[i]->port = discovered_command_port;
known_controllers[i]->relay_count = discovered_relay_count; known_controllers[i]->relay_count = discovered_relay_count;
@ -244,8 +246,8 @@ api_v1_controllers_discover_PUT(struct mg_connection *nc, struct http_message *h
controller_t *discovered_controller = malloc(sizeof(controller_t)); controller_t *discovered_controller = malloc(sizeof(controller_t));
discovered_controller->id = 0; discovered_controller->id = 0;
strcpy(discovered_controller->ip, inet_ntoa(addr.sin_addr)); strlcpy(discovered_controller->ip, inet_ntoa(addr.sin_addr), IP_LENGTH + 1);
memcpy(discovered_controller->uid, discovered_id, sizeof(uuid_t)); uuid_copy(discovered_controller->uid, discovered_id);
strncpy(discovered_controller->name, discovered_name, discovered_name_len); strncpy(discovered_controller->name, discovered_name, discovered_name_len);
discovered_controller->name[discovered_name_len] = '\0'; discovered_controller->name[discovered_name_len] = '\0';
discovered_controller->relay_count = discovered_relay_count; discovered_controller->relay_count = discovered_relay_count;

View file

@ -1,3 +1,5 @@
#include <bsd/string.h>
#include <cJSON.h> #include <cJSON.h>
#include <macros.h> #include <macros.h>
#include <constants.h> #include <constants.h>
@ -81,10 +83,15 @@ api_v1_tags_POST(struct mg_connection *nc, struct http_message *hm, endpoint_arg
{ {
LOGGER_DEBUG("new tag saved\n"); LOGGER_DEBUG("new tag saved\n");
char *tag = malloc(sizeof(char) * (strlen(json_tag->valuestring) + 1)); size_t tag_len = strlen(json_tag->valuestring);
strcpy(tag, json_tag->valuestring);
// NOLINT(clang-analyzer-unix.Malloc): The endpoint response will be freed later.
char *tag = malloc(sizeof(char) * (tag_len + 1));
strlcpy(tag, json_tag->valuestring, tag_len + 1);
endpoint_response_text(response, 201, tag, 0); endpoint_response_text(response, 201, tag, 0);
free(tag);
} }
cJSON_Delete(json); cJSON_Delete(json);

View file

@ -1,3 +1,4 @@
#include <bsd/string.h>
#include <string.h> #include <string.h>
#include <status.h> #include <status.h>
@ -21,7 +22,7 @@ add_extra_headers(char *extra_headers)
if(extra_headers == NULL) if(extra_headers == NULL)
{ {
result = malloc(sizeof(char) * (std_headers_len + 1)); result = malloc(sizeof(char) * (std_headers_len + 1));
strcpy(result, global_config->http_server_opts.extra_headers); strlcpy(result, global_config->http_server_opts.extra_headers, std_headers_len + 1);
return result; return result;
} }

View file

@ -27,7 +27,7 @@ helper_connect_tcp_server(char* host, uint16_t port)
//res got filled out by getaddrinfo() for us //res got filled out by getaddrinfo() for us
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); //creating Socket s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); //creating Socket
if ((status = connect(s, res->ai_addr, res->ai_addrlen)) != 0) { if (connect(s, res->ai_addr, res->ai_addrlen) != 0) {
LOGGER_ERR("connect() failed\n"); LOGGER_ERR("connect() failed\n");
freeaddrinfo(res); freeaddrinfo(res);
return -1; return -1;

View file

@ -15,21 +15,20 @@ get_uid_for_user(char *user)
{ {
return getuid(); return getuid();
} }
struct passwd *pwd = calloc(1, sizeof(struct passwd)); struct passwd pwd;
struct passwd *result = NULL;
size_t buffer_len = sysconf(_SC_GETPW_R_SIZE_MAX) * sizeof(char); size_t buffer_len = sysconf(_SC_GETPW_R_SIZE_MAX) * sizeof(char);
char *buffer = malloc(buffer_len); char *buffer = malloc(buffer_len);
getpwnam_r(user, pwd, buffer, buffer_len, &pwd); getpwnam_r(user, &pwd, buffer, buffer_len, &result);
if(pwd == NULL) if(result == NULL)
{ {
LOGGER_CRIT("couldn't find user to drop privileges\n"); LOGGER_CRIT("couldn't find user to drop privileges\n");
exit(1); exit(1);
} }
uid_t result = pwd->pw_uid;
free(buffer); free(buffer);
free(pwd); return result->pw_uid;
return result;
} }
static gid_t static gid_t
@ -39,21 +38,20 @@ get_gid_for_group(char *group)
{ {
return getgid(); return getgid();
} }
struct group *grp = calloc(1, sizeof(struct group)); struct group grp;
struct group *result = NULL;
size_t buffer_len = sysconf(_SC_GETPW_R_SIZE_MAX) * sizeof(char); size_t buffer_len = sysconf(_SC_GETPW_R_SIZE_MAX) * sizeof(char);
char *buffer = malloc(buffer_len); char *buffer = malloc(buffer_len);
getgrnam_r(group, grp, buffer, buffer_len, &grp); getgrnam_r(group, &grp, buffer, buffer_len, &result);
if(grp == NULL) if(result == NULL)
{ {
LOGGER_CRIT("couldn't find group to drop privileges\n"); LOGGER_CRIT("couldn't find group to drop privileges\n");
exit(1); exit(1);
} }
gid_t result = grp->gr_gid;
free(buffer); free(buffer);
free(grp); return result->gr_gid;
return result;
} }
int int

View file

@ -1,11 +1,12 @@
#include <time.h> #include <time.h>
#include <constants.h>
#include <helpers.h> #include <helpers.h>
int int
helper_get_weekday(const struct tm *time_struct) helper_get_weekday(const struct tm *time_struct)
{ {
int wday_sun_sat = time_struct->tm_wday; int wday_sun_sat = time_struct->tm_wday;
int wday_mon_sun = (wday_sun_sat + 6) % 7; int wday_mon_sun = (wday_sun_sat + (DAYS_PER_WEEK - 1)) % DAYS_PER_WEEK;
return wday_mon_sun; return wday_mon_sun;
} }

View file

@ -66,8 +66,6 @@ logger_log(int level, const char *filename, int line, const char *func, const ch
char *buffer = malloc(sizeof(char) * (128 + strlen(msg))); char *buffer = malloc(sizeof(char) * (128 + strlen(msg)));
sprintf(buffer, "%s[%5s] %s:%d:%s " COLOR_NONE "%s", color, level_str, filename, line, func, msg); sprintf(buffer, "%s[%5s] %s:%d:%s " COLOR_NONE "%s", color, level_str, filename, line, func, msg);
//fprintf(stream, "%s %s:%d:%s " COLOR_NONE, timestamp_str, filename, line, func);
va_list args; va_list args;
va_start(args, msg); va_start(args, msg);
vsyslog(level, buffer, args); vsyslog(level, buffer, args);
@ -75,8 +73,9 @@ logger_log(int level, const char *filename, int line, const char *func, const ch
char *buffer_timed = malloc(sizeof(char) * (strlen(timestamp_str) + strlen(buffer) + 2)); char *buffer_timed = malloc(sizeof(char) * (strlen(timestamp_str) + strlen(buffer) + 2));
sprintf(buffer_timed, "%s %s", timestamp_str, buffer); sprintf(buffer_timed, "%s %s", timestamp_str, buffer);
va_start(args, msg); va_start(args, msg);
vfprintf(global_config->log_file, buffer_timed, args); vfprintf(global_config->log_file, buffer_timed, args); // NOLINT(clang-analyzer-valist.Uninitialized): clang-tidy bug
fflush(global_config->log_file); fflush(global_config->log_file);
va_end(args); va_end(args);

View file

@ -1,22 +1,22 @@
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdio.h>
#include <syslog.h> #include <syslog.h>
#include <mongoose.h>
#include <confini.h> #include <confini.h>
#include <mongoose.h>
#include <cache.h> #include <cache.h>
#include <cli.h> #include <cli.h>
#include <router.h>
#include <logger.h>
#include <config.h> #include <config.h>
#include <database.h> #include <database.h>
#include <handlers.h>
#include <enums.h> #include <enums.h>
#include <handlers.h>
#include <helpers.h> #include <helpers.h>
#include <status.h> #include <logger.h>
#include <models/controller.h> #include <models/controller.h>
#include <router.h>
#include <status.h>
static struct mg_mgr mgr; static struct mg_mgr mgr;

View file

@ -1,3 +1,4 @@
#include <bsd/string.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sqlite3.h> #include <sqlite3.h>
@ -35,6 +36,8 @@ static controller_t*
controller_db_select_mapper(sqlite3_stmt *stmt) controller_db_select_mapper(sqlite3_stmt *stmt)
{ {
controller_t *new_controller = malloc(sizeof(controller_t)); controller_t *new_controller = malloc(sizeof(controller_t));
new_controller->id = 0;
for(int i = 0; i < sqlite3_column_count(stmt); i++) for(int i = 0; i < sqlite3_column_count(stmt); i++)
{ {
const char *name = sqlite3_column_name(stmt, i); const char *name = sqlite3_column_name(stmt, i);
@ -50,14 +53,14 @@ controller_db_select_mapper(sqlite3_stmt *stmt)
new_controller->id = sqlite3_column_int(stmt, i); new_controller->id = sqlite3_column_int(stmt, i);
break; break;
case 'p': // ip case 'p': // ip
strncpy(new_controller->ip, (const char*)sqlite3_column_text(stmt, i), 16); strlcpy(new_controller->ip, (const char*)sqlite3_column_text(stmt, i), sizeof(new_controller->ip));
break; break;
default: // ignore columns not implemented default: // ignore columns not implemented
break; break;
} }
break; break;
case 'n': // name case 'n': // name
strncpy(new_controller->name, (const char*)sqlite3_column_text(stmt, i), 127); strlcpy(new_controller->name, (const char*)sqlite3_column_text(stmt, i), sizeof(new_controller->name));
break; break;
case 'p': // port case 'p': // port
new_controller->port = sqlite3_column_int(stmt, i); new_controller->port = sqlite3_column_int(stmt, i);

View file

@ -1,3 +1,4 @@
#include <bsd/string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
@ -42,7 +43,8 @@ junction_relay_schedule_insert_weekdays(int relay_id, int *schedule_ids)
size_t query_len = M_STRLEN(query_base) + (7 * (M_STRLEN(query_extender) + 1)) + 1; size_t query_len = M_STRLEN(query_base) + (7 * (M_STRLEN(query_extender) + 1)) + 1;
char *query = malloc(sizeof(char) * query_len + 1); char *query = malloc(sizeof(char) * query_len + 1);
strncpy(query, query_base, query_len); strlcpy(query, query_base, query_len + 1);
query_len -= M_STRLEN(query_base); query_len -= M_STRLEN(query_base);
for(int i = 0; i < 7; ++i) for(int i = 0; i < 7; ++i)
{ {

View file

@ -1,3 +1,4 @@
#include <bsd/string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stddef.h> #include <stddef.h>
@ -69,7 +70,7 @@ junction_tag_insert_list(int *tag_ids, int relay_id, int schedule_id, int count)
size_t query_len = M_STRLEN(query_base) + (count * (M_STRLEN(query_extender) + 1)) + 1; size_t query_len = M_STRLEN(query_base) + (count * (M_STRLEN(query_extender) + 1)) + 1;
char *query = malloc(sizeof(char) * query_len + 1); char *query = malloc(sizeof(char) * query_len + 1);
strncpy(query, query_base, query_len); strlcpy(query, query_base, query_len + 1);
query_len -= M_STRLEN(query_base); query_len -= M_STRLEN(query_base);
for(int i = 0; i < count; ++i) for(int i = 0; i < count; ++i)
{ {

View file

@ -1,3 +1,4 @@
#include <bsd/string.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sqlite3.h> #include <sqlite3.h>
@ -42,7 +43,7 @@ macro_db_select_mapper(sqlite3_stmt *stmt)
new_macro->id = sqlite3_column_int(stmt, i); new_macro->id = sqlite3_column_int(stmt, i);
break; break;
case 'n': // name case 'n': // name
strncpy(new_macro->name, (const char*)sqlite3_column_text(stmt, i), MAX_NAME_LENGTH); strlcpy(new_macro->name, (const char*)sqlite3_column_text(stmt, i), sizeof(new_macro->name));
new_macro->name[MAX_NAME_LENGTH] = '\0'; new_macro->name[MAX_NAME_LENGTH] = '\0';
break; break;
case 'u': // uid case 'u': // uid

View file

@ -1,18 +1,20 @@
#include <bsd/string.h>
#include <sqlite3.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sqlite3.h>
#include <cache.h>
#include <cJSON.h> #include <cJSON.h>
#include <logger.h> #include <cache.h>
#include <constants.h>
#include <database.h> #include <database.h>
#include <status.h> #include <logger.h>
#include <models/relay.h>
#include <models/controller.h> #include <models/controller.h>
#include <models/schedule.h>
#include <models/junction_tag.h>
#include <models/junction_relay_schedule.h> #include <models/junction_relay_schedule.h>
#include <models/junction_tag.h>
#include <models/relay.h>
#include <models/schedule.h>
#include <models/tag.h> #include <models/tag.h>
#include <status.h>
static int static int
db_update_insert(relay_t *relay, sqlite3_stmt *stmt) db_update_insert(relay_t *relay, sqlite3_stmt *stmt)
@ -35,6 +37,7 @@ static relay_t*
relay_db_select_mapper(sqlite3_stmt *stmt) relay_db_select_mapper(sqlite3_stmt *stmt)
{ {
relay_t *new_relay = malloc(sizeof(relay_t)); relay_t *new_relay = malloc(sizeof(relay_t));
new_relay->id = 0;
new_relay->is_on = 0; new_relay->is_on = 0;
for(int i = 0; i < sqlite3_column_count(stmt); i++) for(int i = 0; i < sqlite3_column_count(stmt); i++)
@ -52,7 +55,7 @@ relay_db_select_mapper(sqlite3_stmt *stmt)
switch(name[1]) switch(name[1])
{ {
case 'a': // name case 'a': // name
strncpy(new_relay->name, (const char*)sqlite3_column_text(stmt, i), 127); strlcpy(new_relay->name, (const char*)sqlite3_column_text(stmt, i), sizeof(new_relay->name));
break; break;
case 'u': // number case 'u': // number
new_relay->number = sqlite3_column_int(stmt, i); new_relay->number = sqlite3_column_int(stmt, i);
@ -66,7 +69,7 @@ relay_db_select_mapper(sqlite3_stmt *stmt)
} }
} }
memset(new_relay->schedules, 0, sizeof(schedule_t*) * 7); memset(new_relay->schedules, 0, sizeof(schedule_t*) * DAYS_PER_WEEK);
relay_reload_schedules(new_relay); relay_reload_schedules(new_relay);
relay_reload_active_schedule(new_relay); relay_reload_active_schedule(new_relay);
@ -100,13 +103,11 @@ relay_db_select(sqlite3_stmt *stmt)
{ {
break; break;
} }
else
{
LOGGER_ERR("error selecting relays from database: %s\n", sqlite3_errstr(s)); LOGGER_ERR("error selecting relays from database: %s\n", sqlite3_errstr(s));
break; break;
} }
} }
}
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
all_relays[row] = NULL; all_relays[row] = NULL;
return all_relays; return all_relays;
@ -154,8 +155,8 @@ relay_save(relay_t *relay)
junction_relay_schedule_remove_for_relay(relay->id); junction_relay_schedule_remove_for_relay(relay->id);
LOGGER_DEBUG("rebuilding relay_schedule junction\n"); LOGGER_DEBUG("rebuilding relay_schedule junction\n");
int schedule_ids[7]; int schedule_ids[DAYS_PER_WEEK];
for(int i = 0; i < 7; ++i) for(int i = 0; i < DAYS_PER_WEEK; ++i)
{ {
schedule_ids[i] = relay->schedules[i]->id; schedule_ids[i] = relay->schedules[i]->id;
} }
@ -183,17 +184,16 @@ relay_reload_schedules(relay_t *relay)
{ {
schedule_t **schedules = schedule_get_relay_weekdays(relay->id); schedule_t **schedules = schedule_get_relay_weekdays(relay->id);
uuid_t off_id; uuid_t off_uid;
memset(off_id, 0, sizeof(uuid_t)); schedule_get_uid_off(off_uid);
memcpy(off_id, "off", 3);
int fill_with_off = 0; int fill_with_off = 0;
for(int i = 0; i < 7; ++i) for(int i = 0; i < DAYS_PER_WEEK; ++i)
{ {
if(schedules[i] == NULL || fill_with_off) if(schedules[i] == NULL || fill_with_off)
{ {
LOGGER_WARNING("got only %d/7 schedules for relay_id %d\n", i, relay->id); LOGGER_WARNING("got only %d/7 schedules for relay_id %d\n", i, relay->id);
relay->schedules[i] = schedule_get_by_uid(off_id); relay->schedules[i] = schedule_get_by_uid(off_uid);
fill_with_off = 1; fill_with_off = 1;
} }
@ -213,7 +213,7 @@ relay_reload_schedules(relay_t *relay)
void void
relay_free(relay_t *relay) relay_free(relay_t *relay)
{ {
for(int i = 0; i < 7; ++i) for(int i = 0; i < DAYS_PER_WEEK; ++i)
{ {
schedule_free(relay->schedules[i]); schedule_free(relay->schedules[i]);
} }
@ -306,7 +306,7 @@ relay_to_json(relay_t *relay, int status_relay)
cJSON_AddItemToObject(json, "active_schedule", json_active_schedule); cJSON_AddItemToObject(json, "active_schedule", json_active_schedule);
cJSON *json_schedules = cJSON_CreateArray(); cJSON *json_schedules = cJSON_CreateArray();
for(int i = 0; i < 7; ++i) for(int i = 0; i < DAYS_PER_WEEK; ++i)
{ {
cJSON *json_schedule = schedule_to_json(relay->schedules[i]); cJSON *json_schedule = schedule_to_json(relay->schedules[i]);
cJSON_AddItemToArray(json_schedules, json_schedule); cJSON_AddItemToArray(json_schedules, json_schedule);

View file

@ -1,3 +1,4 @@
#include <bsd/string.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sqlite3.h> #include <sqlite3.h>
@ -37,6 +38,8 @@ schedule_db_select_mapper(sqlite3_stmt *stmt)
{ {
const uint16_t *periods_blob; const uint16_t *periods_blob;
schedule_t *new_schedule = malloc(sizeof(schedule_t)); schedule_t *new_schedule = malloc(sizeof(schedule_t));
new_schedule->id = 0;
for(int i = 0; i < sqlite3_column_count(stmt); i++) for(int i = 0; i < sqlite3_column_count(stmt); i++)
{ {
const char *name = sqlite3_column_name(stmt, i); const char *name = sqlite3_column_name(stmt, i);
@ -46,7 +49,7 @@ schedule_db_select_mapper(sqlite3_stmt *stmt)
new_schedule->id = sqlite3_column_int(stmt, i); new_schedule->id = sqlite3_column_int(stmt, i);
break; break;
case 'n': // name case 'n': // name
strncpy(new_schedule->name, (const char*)sqlite3_column_text(stmt, i), MAX_NAME_LENGTH); strlcpy(new_schedule->name, (const char*)sqlite3_column_text(stmt, i), sizeof(new_schedule->name));
new_schedule->name[MAX_NAME_LENGTH] = '\0'; new_schedule->name[MAX_NAME_LENGTH] = '\0';
break; break;
case 'p': // periods case 'p': // periods
@ -97,13 +100,11 @@ schedule_db_select(sqlite3_stmt *stmt)
{ {
break; break;
} }
else
{
LOGGER_ERR("error selecting schedules from database: %s\n", sqlite3_errstr(s)); LOGGER_ERR("error selecting schedules from database: %s\n", sqlite3_errstr(s));
break; break;
} }
} }
}
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
all_schedules[row] = NULL; all_schedules[row] = NULL;
return all_schedules; return all_schedules;
@ -177,18 +178,16 @@ schedule_remove(schedule_t *schedule)
int int
schedule_is_protected(schedule_t *schedule) schedule_is_protected(schedule_t *schedule)
{ {
uuid_t tmp_uuid; uuid_t tmp_uid;
memset(tmp_uuid, 0, sizeof(uuid_t)); schedule_get_uid_off(tmp_uid);
memcpy(tmp_uuid, "off", 3); if(uuid_compare(schedule->uid, tmp_uid) == 0)
if(uuid_compare(schedule->uid, tmp_uuid) == 0)
{ {
return 1; return 1;
} }
memset(tmp_uuid, 0, sizeof(uuid_t)); schedule_get_uid_on(tmp_uid);
memcpy(tmp_uuid, "on", 2); if(uuid_compare(schedule->uid, tmp_uid) == 0)
if(uuid_compare(schedule->uid, tmp_uuid) == 0)
{ {
return 1; return 1;
} }
@ -280,7 +279,8 @@ schedule_to_json(schedule_t *schedule)
continue; continue;
} }
char start_str[8], end_str[8]; char start_str[8];
char end_str[8];
period_t *period = &schedule->periods[i]; period_t *period = &schedule->periods[i];
sprintf(start_str, "%02d:%02d", period->start / 60 , period->start % 60); sprintf(start_str, "%02d:%02d", period->start / 60 , period->start % 60);
sprintf(end_str, "%02d:%02d", period->end / 60, period->end % 60); sprintf(end_str, "%02d:%02d", period->end / 60, period->end % 60);
@ -359,11 +359,10 @@ schedule_get_by_id_or_off(int id)
return result; return result;
} }
uuid_t tmp_uuid; uuid_t tmp_uid;
memset(tmp_uuid, 0, sizeof(uuid_t)); schedule_get_uid_off(tmp_uid);
memcpy(tmp_uuid, "off", 3);
return schedule_get_by_uid(tmp_uuid); return schedule_get_by_uid(tmp_uid);
} }
schedule_t* schedule_t*
@ -404,11 +403,10 @@ schedule_get_by_uid_or_off(uuid_t uid)
return result; return result;
} }
uuid_t tmp_uuid; uuid_t tmp_uid;
memset(tmp_uuid, 0, sizeof(uuid_t)); schedule_get_uid_off(tmp_uid);
memcpy(tmp_uuid, "off", 3);
return schedule_get_by_uid(tmp_uuid); return schedule_get_by_uid(tmp_uid);
} }
schedule_t* schedule_t*
@ -459,14 +457,12 @@ schedule_uid_parse(const char *uid_str, uuid_t result)
{ {
if(strcmp("off", uid_str) == 0) if(strcmp("off", uid_str) == 0)
{ {
memset(result, 0, sizeof(uuid_t)); schedule_get_uid_off(result);
memcpy(result, "off", 3);
return 0; return 0;
} }
if(strcmp("on", uid_str) == 0) if(strcmp("on", uid_str) == 0)
{ {
memset(result, 0, sizeof(uuid_t)); schedule_get_uid_on(result);
memcpy(result, "on", 2);
return 0; return 0;
} }
@ -480,23 +476,35 @@ schedule_uid_parse(const char *uid_str, uuid_t result)
void void
schedule_uid_unparse(const uuid_t uid, char *result) schedule_uid_unparse(const uuid_t uid, char *result)
{ {
uuid_t tmp_uuid; uuid_t tmp_uid;
memset(tmp_uuid, 0, sizeof(uuid_t)); schedule_get_uid_off(tmp_uid);
memcpy(tmp_uuid, "off", 3); if(uuid_compare(uid, tmp_uid) == 0)
if(uuid_compare(uid, tmp_uuid) == 0)
{ {
strcpy(result, "off"); strlcpy(result, "off", 4);
return; return;
} }
memset(tmp_uuid, 0, sizeof(uuid_t)); schedule_get_uid_on(tmp_uid);
memcpy(tmp_uuid, "on", 2); if(uuid_compare(uid, tmp_uid) == 0)
if(uuid_compare(uid, tmp_uuid) == 0)
{ {
strcpy(result, "on"); strlcpy(result, "on", 3);
return; return;
} }
uuid_unparse(uid, result); uuid_unparse(uid, result);
} }
void
schedule_get_uid_off(uuid_t target)
{
uuid_clear(target);
strlcpy((char*)target, "off", sizeof(uuid_t));
}
void
schedule_get_uid_on(uuid_t target)
{
uuid_clear(target);
strlcpy((char*)target, "on", sizeof(uuid_t));
}

View file

@ -1,3 +1,4 @@
#include <bsd/string.h>
#include <string.h> #include <string.h>
#include <logger.h> #include <logger.h>
@ -341,8 +342,9 @@ router_find_endpoint(const char *uri_str, size_t uri_len, struct mg_str *method_
{ {
if(best_endpoint->args[i].type == ENDPOINT_ARG_TYPE_STR) if(best_endpoint->args[i].type == ENDPOINT_ARG_TYPE_STR)
{ {
char *arg_value_str = malloc(sizeof(char) * (strlen(best_endpoint->args[i].value.v_str) + 1)); size_t arg_value_str_len = strlen(best_endpoint->args[i].value.v_str);
strcpy(arg_value_str, best_endpoint->args[i].value.v_str); char *arg_value_str = malloc(sizeof(char) * (arg_value_str_len + 1));
strlcpy(arg_value_str, best_endpoint->args[i].value.v_str, arg_value_str_len);
best_endpoint->args[i].value.v_str = arg_value_str; best_endpoint->args[i].value.v_str = arg_value_str;
} }
} }