diff --git a/Makefile.am b/Makefile.am index 552c043..f2460c2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ INCLUDES=${gammu_CFLAGS} yasnd_LDADD = ${libconfuse_LIBS} yasnd_LDADD += ${gammu_LIBS} bin_PROGRAMS = yasnd -yasnd_SOURCES = yasnd.c yasnd-gammu.c +yasnd_SOURCES = yasnd.c yasnd-gammu.c yasnd-ipc.c distclean-local: rm -rf aclocal.m4 autom4te.cache depcomp install-sh missing configure Makefile.in config.h* &>/dev/null diff --git a/yasnd-ipc.c b/yasnd-ipc.c new file mode 100644 index 0000000..c337b63 --- /dev/null +++ b/yasnd-ipc.c @@ -0,0 +1,80 @@ +#include +#include + +#include "yasnd.h" + +pid_t ipc_clone_pid; + +int open_queue() +{ + key_t keyval=ftok(".",'m'); + int qid; + if((qid = msgget( keyval, IPC_CREAT | 0660 )) == -1) + { + log_event("Error opening/creating IPC message queue"); + exit(EXIT_FAILURE); + } + return qid; +} + +int send_message(int qid, mymsgbuf* qbuf) +{ + int result; + /* The length is essentially the size of the structure minus sizeof(mtype) */ + int length = sizeof(mymsgbuf) - sizeof(long); + + if((result = msgsnd( qid, qbuf, length, 0)) == -1) + { + return -1; + } + + return result; +} + +int read_message(int qid, mymsgbuf* qbuf, long type) +{ + int result; + int length = sizeof(mymsgbuf) - sizeof(long); + if((result = msgrcv( qid, qbuf, length, type, 0)) == -1) + { + return -1; + } + return result; +} + +int remove_queue( int qid ) +{ + if( msgctl(qid, IPC_RMID, 0) == -1) + { + return -1; + } + return 0; +} + +int ipc_queue_loop() +{ + // set default signal handlers + signal(SIGTERM,SIG_DFL); + signal(SIGHUP,SIG_DFL); + // + mymsgbuf qbuf; + while(1) + { + int result=read_message(qid, &qbuf, 1); + if (result==-1) + { + log_event("Error: finishing IPC loop process..."); + return 1; + } + char dbg_txt[150]; + sprintf(dbg_txt,"Read IPC message - Type: %ld Text: %s", qbuf.mtype, qbuf.mtext); + log_debug(dbg_txt,DEBUG_ALL); + } +} + +void ipc_init() +{ + qid = open_queue(); + unsigned char ipc_child_stack[16384]; + ipc_clone_pid=clone(ipc_queue_loop,ipc_child_stack+8192,CLONE_VM,NULL); +} diff --git a/yasnd.c b/yasnd.c index a1eb011..38a0009 100644 --- a/yasnd.c +++ b/yasnd.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include "yasnd.h" @@ -16,6 +15,7 @@ cfg_t *cfg; // pointer to configuration structure host_decl* hosts=NULL; // structure with hosts' definitions int hosts_count=0; // count of hosts +int qid=-1; // IPC queue id int debug_flag=0; bool sms_send_enable=false; // send or not send alerts via SMS char* phone_device=NULL; // phone device for gammu, for example: "/dev/ttyACM0" @@ -109,7 +109,6 @@ void init() } // initialize gammu structures gammu_init(); - } void check_host(int num,host_decl* host) @@ -121,6 +120,10 @@ void check_host(int num,host_decl* host) } // If pid == 0, then we are in the child if (pid == 0) { + // Set default signal handlers + signal(SIGTERM, SIG_DFL); + signal(SIGHUP, SIG_DFL); + // char tmp[50]; sprintf(tmp, "Pinging host %s", host->hostname); log_debug(tmp,DEBUG_BASE); @@ -205,6 +208,10 @@ void signal_handler(int signum) { void free_resources() { + // Stop IPC loop and remove IPC queue + kill(ipc_clone_pid,SIGTERM); + waitpid(ipc_clone_pid,NULL,__WCLONE); + remove_queue(qid); // free config structure cfg_free(cfg); // free gammu structure @@ -224,6 +231,8 @@ void signal_handler(int signum) // free all resources free_resources(); + // Init IPC loop again + ipc_init(); // run init again init(); // sleep 5 seconds and unlock Main Loop @@ -234,8 +243,13 @@ void signal_handler(int signum) if (signum==SIGTERM) { log_event("SIGTERM captured, daemon stopping"); + // close log decriptor closelog(); - free_resources(); // free all other resources + // free resources + free_resources(); + // remove IPC message queue + remove_queue(qid); + // exit(EXIT_SUCCESS); } } @@ -278,21 +292,25 @@ int main(void) { close(STDOUT_FILENO); close(STDERR_FILENO); - // Set signal handlers - signal(SIGTERM, signal_handler); - signal(SIGHUP, signal_handler); + // initialize IPC queue and create process + // that will watch for new messages in it + ipc_init(); // Init apropriate structures init(); + // Set signal handlers + signal(SIGTERM, signal_handler); + signal(SIGHUP, signal_handler); + /* The Main Loop */ while (1) { if (!loop_locked) { loop_function(); -// sleep(60); /* wait 60 seconds */ - log_event("Exiting"); - exit(EXIT_SUCCESS); + sleep(60); /* wait 60 seconds */ +// log_event("Exiting"); +// exit(EXIT_SUCCESS); } else { diff --git a/yasnd.h b/yasnd.h index 4a19990..9c0d6cc 100644 --- a/yasnd.h +++ b/yasnd.h @@ -5,17 +5,14 @@ #define DEBUG_BASE 1 #define DEBUG_ALL 2 +#include #include #include #include +#define _GNU_SOURCE +#include -// External functions -extern void log_event(const char *message); -extern void log_debug(const char *message,int verbosity); -extern bool check_gammu_error(GSM_Error err); -extern bool gammu_init(); -extern bool gammu_send_sms(const char* message); - +// Structure, that described single checked host typedef struct { char* hostname; // address of host pid_t helper_pid; // pid of helper('pinger') child process @@ -23,6 +20,23 @@ typedef struct { bool alert_sent; // variable, that changed when host goes online/offline } host_decl; +// Structure, that described single IPC message +typedef struct { + long mtype; /* Message type */ + char mtext[100]; +} mymsgbuf; + +// External functions +extern void log_event(const char *message); +extern void log_debug(const char *message,int verbosity); +extern void* allocate_memory(int bytes); +extern bool check_gammu_error(GSM_Error err); +extern bool gammu_init(); +extern bool gammu_send_sms(const char* message); +extern void ipc_init(); +extern int remove_queue(int qid); +extern int send_message(int qid, mymsgbuf* qbuf); + // External variables extern int hosts_count; // count of hosts extern int debug_flag; @@ -32,5 +46,7 @@ extern char* recipient_number; extern char* phone_device; // phone device for gammu, for example: "/dev/ttyACM0" extern char* phone_model; // gammu phone model, for example: "at" extern char* phone_connection; // gammu phone connection type, for example: "at" +extern int qid; +extern pid_t ipc_clone_pid; #endif