From: hyunuktak Date: Wed, 5 Sep 2018 08:24:53 +0000 (+0900) Subject: Add config and check log mode with inotify X-Git-Tag: submit/tizen/20180910.023124^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=80868c1eb01289eebe7ed406d1e4533b641e20e2;p=platform%2Fcore%2Fconnectivity%2Fstc-iptables.git Add config and check log mode with inotify Change-Id: Ie3d856c5c1ff6870b9d73fb6533b07f218cb7914 --- diff --git a/packaging/stc-iptables.spec b/packaging/stc-iptables.spec index 3dc8e20..eff0815 100644 --- a/packaging/stc-iptables.spec +++ b/packaging/stc-iptables.spec @@ -1,6 +1,6 @@ Name: stc-iptables Summary: STC(Smart Traffic Control) iptables -Version: 0.0.22 +Version: 0.0.23 Release: 0 Group: Network & Connectivity/Other License: GPL-2.0 and Apache-2.0 @@ -49,6 +49,8 @@ rm -rf %{buildroot} %make_install +mkdir -p %{buildroot}/%{_localstatedir}/lib/stc + #Systemd iptables service file mkdir -p %{buildroot}%{_libdir}/systemd/system/ cp resources/systemd/stc-iptables.service %{buildroot}%{_libdir}/systemd/system/stc-iptables.service @@ -76,6 +78,8 @@ chown network_fw:network_fw /opt/usr/data/network %attr(644,root,root) %{_libdir}/systemd/system/stc-iptables.service %attr(644,root,root) %{_libdir}/systemd/system/multi-user.target.wants/stc-iptables.service +%attr(755,network_fw,network_fw) /%{_localstatedir}/lib/stc + #DBus DAC %attr(644,root,root) %{_sysconfdir}/dbus-1/system.d/stc-iptables.conf diff --git a/src/helper/helper-config.c b/src/helper/helper-config.c new file mode 100755 index 0000000..26801e8 --- /dev/null +++ b/src/helper/helper-config.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include "helper-config.h" +#include "helper-log.h" + +static GKeyFile *__load_config_file(const char *path) +{ + GKeyFile *keyfile = NULL; + GError *error = NULL; + + STC_LOGD("Load config [%s]", path); + + keyfile = g_key_file_new(); + if (!g_key_file_load_from_file(keyfile, path, 0, &error)) { + STC_LOGD("Failed to load [%s] : %s", path, error->message); + g_clear_error(&error); + g_key_file_free(keyfile); + keyfile = NULL; + } + + return keyfile; +} + +static int __save_config_file(GKeyFile *keyfile, char *path) +{ + gchar *data = NULL; + gsize length = 0; + GError *error = NULL; + int ret = 0; + FILE *fp = NULL; + + data = g_key_file_to_data(keyfile, &length, NULL); + if (!g_file_set_contents(path, data, length, &error)) { + STC_LOGD("Failed to save [%s] : %s", path, error->message); + g_error_free(error); + ret = -EIO; + } + + fp = fopen(path, "a+"); + if (fp) { + fflush(fp); + fsync(fp->_fileno); + fclose(fp); + STC_LOGD("Sync the file to disk"); + } + + g_free(data); + return ret; +} + +int helper_config_get_int(char *key) +{ + char path[256]; + GKeyFile *keyfile; + gint value; + + snprintf(path, sizeof(path), "%s/%s", INFO_DIR, INFO_CONFIG); + + keyfile = __load_config_file(path); + if (!keyfile) + return 0; + + value = g_key_file_get_integer(keyfile, path, key, NULL); + g_key_file_free(keyfile); + + return value; +} + +void helper_config_init(void) +{ + char path[256]; + GKeyFile *keyfile; + + snprintf(path, sizeof(path), "%s/%s", INFO_DIR, INFO_CONFIG); + + keyfile = __load_config_file(path); + if (!keyfile) + keyfile = g_key_file_new(); + + g_key_file_set_integer(keyfile, path, INFO_LOGMODE, 0); + __save_config_file(keyfile, path); +} diff --git a/src/helper/helper-config.h b/src/helper/helper-config.h new file mode 100755 index 0000000..a93dbd5 --- /dev/null +++ b/src/helper/helper-config.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __STC_HELPER_CONFIG_H__ +#define __STC_HELPER_CONFIG_H__ + +#define INFO_DIR "/var/lib/stc" +#define INFO_CONFIG "iptables.config" +#define INFO_LOGMODE "logmode" + +int helper_config_get_int(char *key); +void helper_config_init(void); + +#endif /* __STC_HELPER_CONFIG_H__ */ diff --git a/src/helper/helper-inotify.c b/src/helper/helper-inotify.c new file mode 100755 index 0000000..21a3582 --- /dev/null +++ b/src/helper/helper-inotify.c @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include + +#include "helper-inotify.h" +#include "helper-log.h" + +typedef struct { + GIOChannel *channel; + uint watch; + int wd; + + inotify_event_cb cb; +} helper_inotify_s; + +static GHashTable *g_inotify_hash; + +static void __inotify_destroy(gpointer user_data) +{ + int fd; + helper_inotify_s *inotify = user_data; + + if (!inotify->channel) + return; + + if (inotify->watch > 0) + g_source_remove(inotify->watch); + + if (inotify->wd > 0) { + fd = g_io_channel_unix_get_fd(inotify->channel); + inotify_rm_watch(fd, inotify->wd); + } + + g_io_channel_unref(inotify->channel); +} + +static gboolean __inotify_data(GIOChannel *channel, + GIOCondition cond, gpointer user_data) +{ + helper_inotify_s *inotify = user_data; + char buffer[256]; + char *next_event; + gsize bytes_read; + GIOStatus status; + + if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) { + inotify->watch = 0; + return false; + } + + status = g_io_channel_read_chars(channel, buffer, + sizeof(buffer), &bytes_read, NULL); + switch (status) { + case G_IO_STATUS_NORMAL: + break; + case G_IO_STATUS_AGAIN: + return true; + default: + STC_LOGE("Failed to read from inotify channel"); + inotify->watch = 0; + return false; + } + + next_event = buffer; + + while (bytes_read > 0) { + struct inotify_event *event; + gchar *ident; + gsize len; + + event = (struct inotify_event *)next_event; + if (event->len) + ident = next_event + sizeof(struct inotify_event); + else + ident = NULL; + + len = sizeof(struct inotify_event) + event->len; + if (len > bytes_read) + break; + + next_event += len; + bytes_read -= len; + + (inotify->cb)(event, ident); + } + + return true; +} + +static int __inotify_create_watch(const char *path, helper_inotify_s *inotify) +{ + int fd; + + fd = inotify_init(); + if (fd < 0) + return -EIO; + + inotify->wd = inotify_add_watch(fd, path, IN_MODIFY | IN_CREATE | IN_DELETE); + if (inotify->wd < 0) { + STC_LOGE("Failed to create watch [%s]", path); + close(fd); + return -EIO; + } + + inotify->channel = g_io_channel_unix_new(fd); + if (!inotify->channel) { + STC_LOGE("Failed to create channel"); + inotify_rm_watch(fd, inotify->wd); + inotify->wd = 0; + + close(fd); + return -EIO; + } + + g_io_channel_set_close_on_unref(inotify->channel, TRUE); + g_io_channel_set_encoding(inotify->channel, NULL, NULL); + g_io_channel_set_buffered(inotify->channel, FALSE); + + inotify->watch = g_io_add_watch(inotify->channel, + G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR, + __inotify_data, inotify); + + return 0; +} + +int helper_inotify_register(const char *path, inotify_event_cb cb) +{ + helper_inotify_s *inotify; + int err; + + if (!cb) + return -EINVAL; + + inotify = g_hash_table_lookup(g_inotify_hash, path); + if (inotify) + goto update; + + inotify = g_try_new0(helper_inotify_s, 1); + if (!inotify) + return -ENOMEM; + + inotify->wd = -1; + err = __inotify_create_watch(path, inotify); + if (err < 0) { + g_free(inotify); + return err; + } + + g_hash_table_replace(g_inotify_hash, g_strdup(path), inotify); + +update: + inotify->cb = cb; + return 0; +} + +void helper_inotify_deregister(const char *path) +{ + helper_inotify_s *inotify; + + inotify = g_hash_table_lookup(g_inotify_hash, path); + if (!inotify) + return; + + g_hash_table_remove(g_inotify_hash, path); +} + +int helper_inotify_init(void) +{ + g_inotify_hash = g_hash_table_new_full(g_str_hash, + g_str_equal, g_free, __inotify_destroy); + return 0; +} + +void helper_inotify_deinit(void) +{ + g_hash_table_destroy(g_inotify_hash); +} diff --git a/src/helper/helper-inotify.h b/src/helper/helper-inotify.h new file mode 100755 index 0000000..eb4c6e4 --- /dev/null +++ b/src/helper/helper-inotify.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __STC_HELPER_INOTIFY_H__ +#define __STC_HELPER_INOTIFY_H__ + +#include + +struct inotify_event; +typedef void (* inotify_event_cb) (struct inotify_event *event, const char *ident); + +int helper_inotify_register(const char *path, inotify_event_cb cb); +void helper_inotify_deregister(const char *path); +int helper_inotify_init(void); +void helper_inotify_deinit(void); + +#endif /* __STC_HELPER_INOTIFY_H__ */ diff --git a/src/helper/helper-log.c b/src/helper/helper-log.c index 75edb6b..864a432 100755 --- a/src/helper/helper-log.c +++ b/src/helper/helper-log.c @@ -28,7 +28,8 @@ #define MAX_LOG_SIZE 1 * 1024 * 1024 #define MAX_LOG_COUNT 1 -static FILE *log_file = NULL; +static FILE *g_log_file = NULL; +static int g_log_mode = 0; //LCOV_EXCL_START static void __stc_iptables_log_update_file_revision(int rev) @@ -86,6 +87,11 @@ static void __stc_iptables_log_get_local_time(char *strtime, const int size) strftime(strtime, size, "%m/%d %H:%M:%S", local_ptm); } +void helper_log_set_mode(int mode) +{ + g_log_mode = mode; +} + void helper_log(const char *format, ...) { va_list ap; @@ -94,27 +100,30 @@ void helper_log(const char *format, ...) char str[256]; char strtime[40]; - if (log_file == NULL) - log_file = (FILE *)fopen(LOG_FILE_PATH, "a+"); + if (g_log_mode == 0) + return; + + if (g_log_file == NULL) + g_log_file = (FILE *)fopen(LOG_FILE_PATH, "a+"); - if (log_file == NULL) + if (g_log_file == NULL) return; va_start(ap, format); - if (fstat(fileno(log_file), &buf) == 0) + if (fstat(fileno(g_log_file), &buf) == 0) log_size = buf.st_size; if (log_size >= MAX_LOG_SIZE) { //LCOV_EXCL_START - fclose(log_file); - log_file = NULL; + fclose(g_log_file); + g_log_file = NULL; __stc_iptables_log_make_backup(); - log_file = (FILE *)fopen(LOG_FILE_PATH, "a+"); + g_log_file = (FILE *)fopen(LOG_FILE_PATH, "a+"); - if (log_file == NULL) { + if (g_log_file == NULL) { va_end(ap); return; } @@ -124,16 +133,16 @@ void helper_log(const char *format, ...) __stc_iptables_log_get_local_time(strtime, sizeof(strtime)); if (vsnprintf(str, sizeof(str), format, ap) > 0) - fprintf(log_file, "%s %s", strtime, str); + fprintf(g_log_file, "%s %s", strtime, str); va_end(ap); } void helper_log_cleanup(void) { - if (log_file == NULL) + if (g_log_file == NULL) return; - fclose(log_file); - log_file = NULL; + fclose(g_log_file); + g_log_file = NULL; } diff --git a/src/helper/helper-log.h b/src/helper/helper-log.h index 8f56b09..248bd12 100755 --- a/src/helper/helper-log.h +++ b/src/helper/helper-log.h @@ -18,6 +18,7 @@ #ifndef __STC_HELPER_LOG_H__ #define __STC_HELPER_LOG_H__ +void helper_log_set_mode(int mode); void helper_log(const char *format, ...); void helper_log_cleanup(void); diff --git a/src/stc-iptables.c b/src/stc-iptables.c index 1d8274e..96f26fc 100755 --- a/src/stc-iptables.c +++ b/src/stc-iptables.c @@ -16,14 +16,33 @@ */ #include +#include #include "stc-iptables.h" #include "stc-iptables-util.h" #include "stc-iptables-gdbus.h" #include "helper-log.h" +#include "helper-inotify.h" +#include "helper-config.h" static stc_iptables_s *g_stc_iptables = NULL; +static gboolean __validate_ident(const char *ident) +{ + unsigned int i; + int len; + + if (!ident) + return FALSE; + + len = strlen(ident); + for (i = 0; i < len; ++i) + if (!g_ascii_isprint(ident[i])) + return FALSE; + + return TRUE; +} + static void __stc_iptables_deinit(void) { __LOG_FUNC_ENTER__; @@ -59,6 +78,23 @@ static stc_iptables_s *__stc_iptables_init(void) return g_stc_iptables; } +static void __stc_inotify_handler(struct inotify_event *event, + const char *ident) +{ + if (!ident) + return; + + if (!__validate_ident(ident)) { + STC_LOGE("Invalid ident [%s]", ident); + return; + } + + if (!g_strcmp0(ident, INFO_CONFIG)) { + int mode = helper_config_get_int(INFO_LOGMODE); + helper_log_set_mode(mode); + } +} + gint32 main(gint32 argc, gchar *argv[]) { GMainLoop *main_loop = NULL; @@ -78,6 +114,11 @@ gint32 main(gint32 argc, gchar *argv[]) g_type_init(); #endif + helper_config_init(); + + helper_inotify_init(); + helper_inotify_register(INFO_DIR, __stc_inotify_handler); + /* Crate the GLIB main loop */ main_loop = g_main_loop_new(NULL, FALSE); @@ -98,6 +139,9 @@ fail: if (main_loop) g_main_loop_unref(main_loop); + helper_inotify_deregister(INFO_DIR); + helper_inotify_deinit(); + return ret; }