Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions include/monitor_conf.h
Original file line number Diff line number Diff line change
@@ -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(const char *config_file);
void monitorConf_close(void);
bool monitorConf_hasChanged(void);

#endif /* JSON_H_ */
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -42,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 \
Expand Down
45 changes: 32 additions & 13 deletions src/automatic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 <level> Set output level to <level> (default=1)\n"
" -c --configfile <path> Path to configuration file\n"
" -o --once Quit Automatic after first check of RSS feeds\n"
Expand All @@ -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[] = "anfhv: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;

Expand All @@ -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;
Expand Down Expand Up @@ -154,6 +161,7 @@ PRIVATE void shutdown_daemon(auto_handle *as) {
}
session_free(as);
SessionID_free();
monitorConf_close();
log_close();
exit(EXIT_SUCCESS);
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -770,6 +778,12 @@ int main(int argc, char **argv) {
dbg_printft( P_MSG, "Daemon started");
}

if (monitorConf) {
if (monitorConf_init(config_file) != 0) {
monitorConf = false; /* avoid testing inotify if not able to initialize */
}
}

dbg_printf(P_INFO, "verbose level: %d", verbose);
dbg_printf(P_INFO, "foreground mode: %s", nofork == true ? "yes" : "no");

Expand Down Expand Up @@ -800,6 +814,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);
}
Expand Down
125 changes: 125 additions & 0 deletions src/monitor_conf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/* $Id$
* $Name$
* $ProjectName$
*/

/**
* @file monitor_conf.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 <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <fcntl.h>

#include "utils.h"
#include "output.h"
#include "monitor_conf.h"

#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) {
dbg_printf(P_DBG, "Monitor Conf close");
if (fd || wd) {
inotify_rm_watch(fd, wd);
}
free(buffer);
}

bool monitorConf_hasChanged(void) {
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;
}