From 79e8628a21f791f1370e1bdf4b1a32d63da67439 Mon Sep 17 00:00:00 2001 From: benoitm Date: Tue, 6 Jan 2015 23:52:06 +0100 Subject: [PATCH 1/3] Adding stub function and Mkaefile change for compilation check --- include/monitor_conf.h | 29 +++++++++++++++++++++++ src/Makefile.am | 6 +++-- src/automatic.c | 43 +++++++++++++++++++++++----------- src/monitor_conf.c | 52 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 15 deletions(-) create mode 100644 include/monitor_conf.h create mode 100644 src/monitor_conf.c diff --git a/include/monitor_conf.h b/include/monitor_conf.h new file mode 100644 index 0000000..a703664 --- /dev/null +++ b/include/monitor_conf.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2015 Benoit Masson (yahoo@perenite.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef MONITORCONF_H_ +#define MONITORCONF_H_ + +#include "stdbool.h" + +unsigned int monitorConf_init(void); +void monitorConf_close(void); +bool monitorConf_hasChanged(void); + +#endif /* JSON_H_ */ diff --git a/src/Makefile.am b/src/Makefile.am index 16fb35e..740b6c6 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -31,7 +31,8 @@ automatic_SOURCES = \ $(top_srcdir)/src/urlcode.c \ $(top_srcdir)/src/utils.c \ $(top_srcdir)/src/web.c \ - $(top_srcdir)/src/xml_parser.c + $(top_srcdir)/src/xml_parser.c \ + $(top_srcdir)/src/monitor_conf.c noinst_HEADERS = \ $(top_srcdir)/include/automatic.h \ @@ -55,7 +56,8 @@ noinst_HEADERS = \ $(top_srcdir)/include/urlcode.h \ $(top_srcdir)/include/utils.h \ $(top_srcdir)/include/web.h \ - $(top_srcdir)/include/xml_parser.h + $(top_srcdir)/include/xml_parser.h \ + $(top_srcdir)/include/monitor_conf.h automatic_mw_SOURCES = \ $(automatic_SOURCES) \ diff --git a/src/automatic.c b/src/automatic.c index ae95da7..44d9ecd 100644 --- a/src/automatic.c +++ b/src/automatic.c @@ -60,6 +60,7 @@ #include "version.h" #include "web.h" #include "xml_parser.h" +#include "monitor_conf.h" PRIVATE char AutoConfigFile[MAXPATHLEN + 1]; PRIVATE void session_free(auto_handle *as); @@ -69,17 +70,19 @@ PRIVATE bool closing = false; PRIVATE bool nofork = AM_DEFAULT_NOFORK; PRIVATE bool isRunning = false; PRIVATE bool seenHUP = false; +PRIVATE bool monitorConf = false; /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// PRIVATE void usage(void) { - printf("usage: automatic [-fh] [-v level] [-l logfile] [-c file]\n" + printf("usage: automatic [-fhn] [-v level] [-l logfile] [-c file]\n" "\n" "Automatic %s\n" "\n" " -f --nodeamon Run in the foreground and log to stderr\n" " -h --help Display this message\n" + " -n --config-monitor Monitor config file changes\n" " -v --verbose Set output level to (default=1)\n" " -c --configfile Path to configuration file\n" " -o --once Quit Automatic after first check of RSS feeds\n" @@ -92,20 +95,21 @@ PRIVATE void usage(void) { /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// -PRIVATE void readargs(int argc, char ** argv, char **c_file, char** logfile, char **xmlfile, +PRIVATE void readargs(int argc, char ** argv, char **c_file, bool * monitorConf, char** logfile, char **xmlfile, bool * nofork, uint8_t * verbose, uint8_t * once, uint8_t * append_log, uint8_t * match_only) { - char optstr[] = "afhv:c:l:ox:m"; + char optstr[] = "afhvn:c:l:ox:m"; struct option longopts[] = { - { "verbose", required_argument, NULL, 'v' }, - { "nodaemon", no_argument, NULL, 'f' }, - { "help", no_argument, NULL, 'h' }, - { "configfile", required_argument, NULL, 'c' }, - { "once", no_argument, NULL, 'o' }, - { "logfile", required_argument, NULL, 'l' }, - { "append-log", no_argument, NULL, 'a' }, - { "xml", required_argument, NULL, 'x' }, - { "match-only", no_argument, NULL, 'm' }, + { "verbose", required_argument, NULL, 'v' }, + { "nodaemon", no_argument, NULL, 'f' }, + { "help", no_argument, NULL, 'h' }, + { "config-monitor", no_argument, NULL, 'n' }, + { "configfile", required_argument, NULL, 'c' }, + { "once", no_argument, NULL, 'o' }, + { "logfile", required_argument, NULL, 'l' }, + { "append-log", no_argument, NULL, 'a' }, + { "xml", required_argument, NULL, 'x' }, + { "match-only", no_argument, NULL, 'm' }, { NULL, 0, NULL, 0 } }; int opt; @@ -120,6 +124,9 @@ PRIVATE void readargs(int argc, char ** argv, char **c_file, char** logfile, cha case 'f': *nofork = true; break; + case 'n': + *monitorConf = true; + break; case 'c': *c_file = optarg; break; @@ -154,6 +161,7 @@ PRIVATE void shutdown_daemon(auto_handle *as) { } session_free(as); SessionID_free(); + monitorConf_close(); log_close(); exit(EXIT_SUCCESS); } @@ -728,7 +736,7 @@ int main(int argc, char **argv) { */ log_init(NULL, verbose, 0); - readargs(argc, argv, &config_file, &logfile, &xmlfile, &nofork, &verbose, &once, &append_log, &match_only); + readargs(argc, argv, &config_file, &monitorConf, &logfile, &xmlfile, &nofork, &verbose, &once, &append_log, &match_only); /* reinitialize the logging with the values from the command line */ log_init(logfile, verbose, append_log); @@ -770,6 +778,10 @@ int main(int argc, char **argv) { dbg_printft( P_MSG, "Daemon started"); } + if (monitorConf) { + monitorConf_init(); + } + dbg_printf(P_INFO, "verbose level: %d", verbose); dbg_printf(P_INFO, "foreground mode: %s", nofork == true ? "yes" : "no"); @@ -800,6 +812,11 @@ int main(int argc, char **argv) { isRunning = false; + if (monitorConf && monitorConf_hasChanged()) { + /* consider a config file change is a SIGHUP signal */ + seenHUP = true; + } + if(seenHUP) { signal_handler(SIGHUP); } diff --git a/src/monitor_conf.c b/src/monitor_conf.c new file mode 100644 index 0000000..05810bd --- /dev/null +++ b/src/monitor_conf.c @@ -0,0 +1,52 @@ +/* $Id$ + * $Name$ + * $ProjectName$ + */ + +/** + * @file output.c + * + * Provides output functionality. + */ + +/* Copyright (C) 2015 Benoit Masson (yahoo@perenite.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "monitor_conf.h" + +unsigned int monitorConf_init(void) { + return 0; +} + +void monitorConf_close(void) { + return; +} + +bool monitorConf_hasChanged(void) { + return true; +} From bf1ce7d247d081ad185c5f1d57a5b14168c1ca43 Mon Sep 17 00:00:00 2001 From: benoitm Date: Wed, 7 Jan 2015 02:38:38 +0100 Subject: [PATCH 2/3] Adding inotify non-blocking config file monitoring -n option --- include/monitor_conf.h | 2 +- src/automatic.c | 6 ++- src/monitor_conf.c | 99 ++++++++++++++++++++++++++++++++++++------ 3 files changed, 91 insertions(+), 16 deletions(-) diff --git a/include/monitor_conf.h b/include/monitor_conf.h index a703664..b98b929 100644 --- a/include/monitor_conf.h +++ b/include/monitor_conf.h @@ -22,7 +22,7 @@ #include "stdbool.h" -unsigned int monitorConf_init(void); +unsigned int monitorConf_init(const char *config_file); void monitorConf_close(void); bool monitorConf_hasChanged(void); diff --git a/src/automatic.c b/src/automatic.c index 44d9ecd..5e8d3c3 100644 --- a/src/automatic.c +++ b/src/automatic.c @@ -98,7 +98,7 @@ PRIVATE void usage(void) { PRIVATE void readargs(int argc, char ** argv, char **c_file, bool * monitorConf, char** logfile, char **xmlfile, bool * nofork, uint8_t * verbose, uint8_t * once, uint8_t * append_log, uint8_t * match_only) { - char optstr[] = "afhvn:c:l:ox:m"; + char optstr[] = "anfhv:c:l:ox:m"; struct option longopts[] = { { "verbose", required_argument, NULL, 'v' }, { "nodaemon", no_argument, NULL, 'f' }, @@ -779,7 +779,9 @@ int main(int argc, char **argv) { } if (monitorConf) { - monitorConf_init(); + if (monitorConf_init(config_file) != 0) { + monitorConf = false; /* avoid testing inotify of not able to initialize */ + } } dbg_printf(P_INFO, "verbose level: %d", verbose); diff --git a/src/monitor_conf.c b/src/monitor_conf.c index 05810bd..8fea96b 100644 --- a/src/monitor_conf.c +++ b/src/monitor_conf.c @@ -4,7 +4,7 @@ */ /** - * @file output.c + * @file monitor_conf.c * * Provides output functionality. */ @@ -26,27 +26,100 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ - - -#include -#include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include "utils.h" +#include "output.h" #include "monitor_conf.h" -unsigned int monitorConf_init(void) { +#define MAX_EVENTS 1024 /*Max. number of events to process at one go*/ +#define LEN_NAME 16 /*Assuming that the length of the filename won't exceed 16 bytes*/ +#define EVENT_SIZE ( sizeof (struct inotify_event) ) /*size of one event*/ +#define BUF_LEN ( MAX_EVENTS * ( EVENT_SIZE + LEN_NAME )) /*buffer to store the data of events*/ + +PRIVATE int fd = 0; +PRIVATE int wd = 0; +PRIVATE char *buffer; + +unsigned int monitorConf_init(const char *config_file) { + + /* check fd, wd are null if not close them */ + if (fd || wd ) { + monitorConf_close(); + } + + dbg_printf(P_DBG, "Monitor Conf init"); + + fd = inotify_init(); + if ( fd < 0 ) { + dbg_printf(P_ERROR, "Couldn't initialize inotify"); + return 1; + } + + /* non blocking inotify */ + if (fcntl (fd, F_SETFL, fcntl (fd, F_GETFL) | O_NONBLOCK) <0 ) { + dbg_printf(P_ERROR, "Couldn't initialize non blocking IO inotify"); + monitorConf_close(); + return 1; + } + + /* add watch to config directory */ + wd = inotify_add_watch(fd, config_file, IN_CREATE | IN_MODIFY | IN_DELETE); + + if (wd == -1) { + dbg_printf(P_ERROR, "Couldn't add watch to %s\n",config_file); + } else { + dbg_printf(P_MSG, "Watching: %s\n",config_file); + } + + /* inititialize buffer for inotify read events */ + buffer = (char *) malloc(BUF_LEN); + return 0; } void monitorConf_close(void) { - return; + dbg_printf(P_DBG, "Monitor Conf close"); + if (fd || wd) { + inotify_rm_watch(fd, wd); + } + free(buffer); } bool monitorConf_hasChanged(void) { - return true; + bool changed = false; + struct inotify_event *event = NULL; + int length = 0; + int i = 0; + + dbg_printf(P_DBG, "Monitor file conf check haschanged"); + + if ( fd ) { + dbg_printf(P_DBG, "Monitor file conf fd > 0"); + + dbg_printf(P_DBG, "Monitor file conf before read"); + length = read( fd, buffer, BUF_LEN ); + dbg_printf(P_DBG, "Monitor file conf after read, length:%d", length); + + if (length >0) { /* >0 include both no data & EAGAIN error for non-blocking */ + while ( i < length ) { + event = ( struct inotify_event * ) &buffer[ i ]; + dbg_printf(P_DBG, "Monitor file conf event->len:%d , event->mask:%d", event->len, event->mask); + if ( event->mask & IN_MODIFY) { + dbg_printf(P_INFO2, "Monitor file conf MODIFY event detected"); + changed = true; + } + i += EVENT_SIZE + event->len; + } + } + } + + dbg_printf(P_DBG, "Monitor file conf check haschanged end"); + return changed; } From 65125ed4d4a6e30d4c339e640efaf9c5aac2167e Mon Sep 17 00:00:00 2001 From: benoitm Date: Wed, 7 Jan 2015 02:45:20 +0100 Subject: [PATCH 3/3] small typos --- src/Makefile.am | 8 ++++---- src/automatic.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 740b6c6..6d96a1f 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,6 +18,7 @@ automatic_SOURCES = \ $(top_srcdir)/src/file.c \ $(top_srcdir)/src/json.c \ $(top_srcdir)/src/list.c \ + $(top_srcdir)/src/monitor_conf.c \ $(top_srcdir)/src/output.c \ $(top_srcdir)/src/filters.c \ $(top_srcdir)/src/prowl.c \ @@ -31,8 +32,7 @@ automatic_SOURCES = \ $(top_srcdir)/src/urlcode.c \ $(top_srcdir)/src/utils.c \ $(top_srcdir)/src/web.c \ - $(top_srcdir)/src/xml_parser.c \ - $(top_srcdir)/src/monitor_conf.c + $(top_srcdir)/src/xml_parser.c noinst_HEADERS = \ $(top_srcdir)/include/automatic.h \ @@ -43,6 +43,7 @@ noinst_HEADERS = \ $(top_srcdir)/include/file.h \ $(top_srcdir)/include/json.h \ $(top_srcdir)/include/list.h \ + $(top_srcdir)/include/monitor_conf.h \ $(top_srcdir)/include/output.h \ $(top_srcdir)/include/filters.h \ $(top_srcdir)/include/prowl.h \ @@ -56,8 +57,7 @@ noinst_HEADERS = \ $(top_srcdir)/include/urlcode.h \ $(top_srcdir)/include/utils.h \ $(top_srcdir)/include/web.h \ - $(top_srcdir)/include/xml_parser.h \ - $(top_srcdir)/include/monitor_conf.h + $(top_srcdir)/include/xml_parser.h automatic_mw_SOURCES = \ $(automatic_SOURCES) \ diff --git a/src/automatic.c b/src/automatic.c index 5e8d3c3..36b3a1a 100644 --- a/src/automatic.c +++ b/src/automatic.c @@ -780,7 +780,7 @@ int main(int argc, char **argv) { if (monitorConf) { if (monitorConf_init(config_file) != 0) { - monitorConf = false; /* avoid testing inotify of not able to initialize */ + monitorConf = false; /* avoid testing inotify if not able to initialize */ } }