Add config and check log mode with inotify 70/188470/1 accepted/tizen_5.0_unified tizen_5.0 accepted/tizen/5.0/unified/20181102.015607 accepted/tizen/unified/20180910.172050 submit/tizen/20180910.023124 submit/tizen_5.0/20181101.000003
authorhyunuktak <hyunuk.tak@samsung.com>
Wed, 5 Sep 2018 08:24:53 +0000 (17:24 +0900)
committerhyunuktak <hyunuk.tak@samsung.com>
Wed, 5 Sep 2018 08:24:53 +0000 (17:24 +0900)
Change-Id: Ie3d856c5c1ff6870b9d73fb6533b07f218cb7914

packaging/stc-iptables.spec
src/helper/helper-config.c [new file with mode: 0755]
src/helper/helper-config.h [new file with mode: 0755]
src/helper/helper-inotify.c [new file with mode: 0755]
src/helper/helper-inotify.h [new file with mode: 0755]
src/helper/helper-log.c
src/helper/helper-log.h
src/stc-iptables.c

index 3dc8e20..eff0815 100644 (file)
@@ -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 (executable)
index 0000000..26801e8
--- /dev/null
@@ -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 <glib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#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 (executable)
index 0000000..a93dbd5
--- /dev/null
@@ -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 (executable)
index 0000000..21a3582
--- /dev/null
@@ -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 <glib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <errno.h>
+
+#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 (executable)
index 0000000..eb4c6e4
--- /dev/null
@@ -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 <sys/inotify.h>
+
+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__ */
index 75edb6b..864a432 100755 (executable)
@@ -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;
 }
index 8f56b09..248bd12 100755 (executable)
@@ -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);
 
index 1d8274e..96f26fc 100755 (executable)
  */
 
 #include <stdlib.h>
+#include <string.h>
 
 #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;
 }