diff options
Diffstat (limited to 'daemon/daemon.c')
-rw-r--r-- | daemon/daemon.c | 197 |
1 files changed, 194 insertions, 3 deletions
diff --git a/daemon/daemon.c b/daemon/daemon.c index e7ff808..cd6ebb2 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -23,7 +23,9 @@ #include <assert.h> #include <signal.h> #include <sys/signalfd.h> +#include <sys/stat.h> #include <string.h> +#include <inttypes.h> #include <glib.h> #include <glib-unix.h> @@ -41,11 +43,42 @@ #include "dbus.h" #include "cache.h" +#define BXT_LOG_FOLDER "/run/buxton2/log" +#define BXT_NULL_STRING "(VCONF_NULL)" + +static int _log_max_line = 2000; +static bool _log_on = true; + +static FILE *_fp; + +static enum log_type { + LOG_SET, + LOG_NOTI, + LOG_DELAYED_NOTI, + LOG_SEND_DELAYED_NOTI, + LOG_REG_NOTI, + LOG_UNREG_NOTI, + LOG_MAX +}; + +static char *log_map[] = { + "SET", + "NOTIFY", + "DELAYED_NOTI", + "SEND_DELAYED_NOTI", + "REG_NOTI", + "UNREG_NOTI" +}; + + struct bxt_noti { char *layer_key; GList *clients; /* struct bxt_client */ }; +static bool _init_log(); +static void _write_file_log(enum log_type type, struct bxt_client *cli, struct request *rqst); + static gboolean signal_cb(gint fd, GIOCondition cond, gpointer data) { struct bxt_daemon *bxtd = data; @@ -230,6 +263,8 @@ static gboolean _send_notis(gpointer key, gpointer value, gpointer data) } } + _write_file_log(LOG_SEND_DELAYED_NOTI, cli, NULL); + free(_data); return TRUE; } @@ -308,8 +343,10 @@ static void send_notis(struct bxt_daemon *bxtd, struct request *rqst) g_hash_table_replace(cli->delay_notilist, strdup(rqst->key), _data); + _write_file_log(LOG_DELAYED_NOTI, cli, rqst); } } else { + _write_file_log(LOG_NOTI, cli, rqst); if (cli->delay_notilist) g_hash_table_remove(cli->delay_notilist, rqst->key); } @@ -331,6 +368,8 @@ static void proc_set(struct bxt_client *cli, resp->res = errno; return; } + _write_file_log(LOG_SET, cli, rqst); + resp->res = 0; } @@ -464,8 +503,10 @@ static void proc_notify(struct bxt_client *cli, } else { free(lykey); } - add_cli(noti, cli); + + _write_file_log(LOG_REG_NOTI, cli, rqst); + resp->res = 0; } @@ -503,6 +544,8 @@ static void proc_unnotify(struct bxt_client *cli, if (!noti->clients) /* no client */ g_hash_table_remove(cli->bxtd->notis, lykey); + _write_file_log(LOG_UNREG_NOTI, cli, rqst); + resp->res = 0; free(lykey); @@ -831,7 +874,9 @@ static int proc_client_msg(struct bxt_client *cli) static gboolean client_cb(gint fd, GIOCondition cond, gpointer data) { - int r; + int r, proc_fd; + char proc_name[512] = {0,}; + char buf[512] = {0,}; struct bxt_client *cli = data; assert(cli); @@ -853,6 +898,17 @@ static gboolean client_cb(gint fd, GIOCondition cond, gpointer data) if (cli->cred.pid == 0) { sock_get_client_cred(fd, &cli->cred); sock_get_client_label(fd, &cli->label); + + snprintf(buf, sizeof(buf), "/proc/%d/cmdline", cli->cred.pid); + + proc_fd = open(buf, O_RDONLY); + if (proc_fd > 0) { + r = read(proc_fd, proc_name, sizeof(proc_name) - 1); + close(proc_fd); + + if (strlen(proc_name) > 0) + cli->process_name = strdup(proc_name); + } } r = proc_client_msg(cli); @@ -957,11 +1013,146 @@ static void free_client(struct bxt_client *cli) if (cli->fd != -1) close(cli->fd); + if (cli->process_name) + free(cli->process_name); + free(cli->label); free(cli); bxt_dbg("free client %p", cli); } +static bool _init_log() +{ + char buffer[256] = {0, }; + int ret; + + ret = mkdir(BXT_LOG_FOLDER, 0755); + if (ret < 0 && errno != EEXIST) { + bxt_err("Failed to mkdir %s - %d", BXT_LOG_FOLDER, errno); + return false; + } + + snprintf(buffer, sizeof(buffer), + "%s/log_%d.log", BXT_LOG_FOLDER, getpid()); + _fp = fopen(buffer, "wt"); + + if (_fp == NULL) { + bxt_err("Failed to open %s - %d", buffer, errno); + return false; + } + + return true; +} + +static void _write_file_log(enum log_type type, struct bxt_client *cli, struct request *rqst) +{ + char buf[512] = {0,}; + char time_buf[32] = {0,}; + char tmp_value[32] = {0,}; + char *label; + char *value = NULL; + int ret = 0; + time_t now; + + static enum log_type prev_type = LOG_MAX; + static int _log_index = 0; + + if (_log_on == false) + return; + + if (_fp == NULL) { + if (_init_log() == false) + return; + } + + if (_log_index >= _log_max_line) { + fseek(_fp, 0, SEEK_SET); + _log_index = 0; + } + + if (cli->process_name != NULL) + label = cli->process_name; + else + label = cli->label; + + time(&now); + ctime_r(&now, time_buf); + + /* remove newline */ + if (strlen(time_buf) > 1) + time_buf[strlen(time_buf) -1] = '\0'; + + if (type == LOG_NOTI) { + if (prev_type != type) { + _log_index++; + snprintf(buf, sizeof(buf), "\n[%5d]%s %-18s %s - pid(%d:%s)", + _log_index, time_buf, log_map[type], rqst->key, cli->cred.pid, label); + + } else { + snprintf(buf, sizeof(buf), ", pid(%d:%s)", cli->cred.pid, label); + } + } else { + _log_index++; + snprintf(buf, sizeof(buf), "\n[%5d]%s %-18s - pid(%d:%s) - %s ", + _log_index, time_buf, log_map[type], cli->cred.pid, label, rqst ? rqst->key : "NULL"); + + if (type == LOG_SET && rqst) { + value = tmp_value; + + switch (rqst->val->type) { + case BUXTON_TYPE_STRING: + value = rqst->val->value.s; + break; + case BUXTON_TYPE_INT32: + snprintf(tmp_value, sizeof(tmp_value), "%d", rqst->val->value.i); + break; + case BUXTON_TYPE_UINT32: + snprintf(tmp_value, sizeof(tmp_value), "%u", rqst->val->value.u); + break; + case BUXTON_TYPE_INT64: + snprintf(tmp_value, sizeof(tmp_value), "%"PRId64, rqst->val->value.i64); + break; + case BUXTON_TYPE_UINT64: + snprintf(tmp_value, sizeof(tmp_value), "%"PRIu64, rqst->val->value.u64); + break; + case BUXTON_TYPE_DOUBLE: + snprintf(tmp_value, sizeof(tmp_value), "%lf", rqst->val->value.d); + break; + case BUXTON_TYPE_BOOLEAN: + if (rqst->val->value.b) + snprintf(tmp_value, sizeof(tmp_value), "True"); + else + snprintf(tmp_value, sizeof(tmp_value), "False"); + break; + default: + snprintf(tmp_value, sizeof(tmp_value), "Unknown type"); + break; + } + } + } + + if (value == NULL || strlen(value) == 0) + value = BXT_NULL_STRING; + + ret = fwrite(buf, strlen(buf), 1 , _fp); + if (ret <= 0) { + bxt_err("Cannot write the key log: %d, type(%d) pid(%d:%s) %s %s", + errno, type, cli->cred.pid, label, rqst ? rqst->key : BXT_NULL_STRING, value); + return; + } + + if (type == LOG_SET) { + ret = fwrite(value, strlen(value), 1, _fp); + if (ret <= 0) { + bxt_err("Cannot write the value log: %d, type(%d) pid(%d:%s) %s %s", + errno, type, cli->cred.pid, label, rqst ? rqst->key : BXT_NULL_STRING, value); + return; + } + } + + prev_type = type; +} + static void bxt_exit(struct bxt_daemon *bxtd) { buxton_cynara_exit(); @@ -1004,7 +1195,7 @@ static int bxt_init(struct bxt_daemon *bxtd, const char *confpath) bxtd->sigfd = create_sigfd(); g_unix_fd_add(bxtd->sigfd, G_IO_IN, signal_cb, bxtd); - r = direct_init(MODULE_DIR, confpath); + r = direct_init(MODULE_DIR, confpath, &_log_on, &_log_max_line); if (r == -1) return -1; |