/************************************************************************** S0/Impulse to Volkszaehler 'RaspberryPI deamon'. https://github.com/w3llschmidt/s0vz.git Henrik Wellschmidt **************************************************************************/ #define DAEMON_NAME "s0vz" #define DAEMON_VERSION "1.4" #define DAEMON_BUILD "4" /************************************************************************** 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 3 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, see . **************************************************************************/ #include /* standard library functions for file input and output */ #include /* standard library for the C programming language, */ #include /* functions implementing operations on strings */ #include /* provides access to the POSIX operating system API */ #include /* declares the stat() functions; umask */ #include /* file descriptors */ #include /* send messages to the system logger */ #include /* macros to report error conditions through error codes */ #include /* signal processing */ #include /* defines the macros NULL and offsetof as well as the types ptrdiff_t, wchar_t, and size_t */ #include /* reading, manipulating, and writing structured configuration files */ #include /* multiprotocol file transfer library */ #include /* wait for events on file descriptors */ #include /* */ #define BUF_LEN 64 void daemonShutdown(); void signal_handler(int sig); void daemonize(char *rundir, char *pidfile); int pidFilehandle, vzport, i, len, running_handles, rc; const char *vzserver, *vzpath, *vzuuid[64]; char gpio_pin_id[] = { 17, 18, 27, 22, 23, 24 }, url[128]; int inputs = sizeof(gpio_pin_id)/sizeof(gpio_pin_id[0]); struct timeval tv; CURL *easyhandle[sizeof(gpio_pin_id)/sizeof(gpio_pin_id[0])]; CURLM *multihandle; CURLMcode multihandle_res; static char errorBuffer[CURL_ERROR_SIZE+1]; void signal_handler(int sig) { switch(sig) { case SIGHUP: syslog(LOG_WARNING, "Received SIGHUP signal."); break; case SIGINT: case SIGTERM: syslog(LOG_INFO, "Daemon exiting"); daemonShutdown(); exit(EXIT_SUCCESS); break; default: syslog(LOG_WARNING, "Unhandled signal %s", strsignal(sig)); break; } } void daemonShutdown() { close(pidFilehandle); remove("/tmp/s0vz.pid"); } void daemonize(char *rundir, char *pidfile) { int pid, sid, i; char str[10]; struct sigaction newSigAction; sigset_t newSigSet; if (getppid() == 1) { return; } sigemptyset(&newSigSet); sigaddset(&newSigSet, SIGCHLD); sigaddset(&newSigSet, SIGTSTP); sigaddset(&newSigSet, SIGTTOU); sigaddset(&newSigSet, SIGTTIN); sigprocmask(SIG_BLOCK, &newSigSet, NULL); newSigAction.sa_handler = signal_handler; sigemptyset(&newSigAction.sa_mask); newSigAction.sa_flags = 0; sigaction(SIGHUP, &newSigAction, NULL); sigaction(SIGTERM, &newSigAction, NULL); sigaction(SIGINT, &newSigAction, NULL); pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } if (pid > 0) { printf("Child process created: %d\n", pid); exit(EXIT_SUCCESS); } umask(027); sid = setsid(); if (sid < 0) { exit(EXIT_FAILURE); } for (i = getdtablesize(); i >= 0; --i) { close(i); } close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); chdir(rundir); pidFilehandle = open(pidfile, O_RDWR|O_CREAT, 0600); if (pidFilehandle == -1 ) { syslog(LOG_INFO, "Could not open PID lock file %s, exiting", pidfile); exit(EXIT_FAILURE); } if (lockf(pidFilehandle,F_TLOCK,0) == -1) { syslog(LOG_INFO, "Could not lock PID lock file %s, exiting", pidfile); exit(EXIT_FAILURE); } sprintf(str,"%d\n",getpid()); write(pidFilehandle, str, strlen(str)); } void cfile() { config_t cfg; //config_setting_t *setting; config_init(&cfg); int chdir(const char *path); chdir ("/etc"); if(!config_read_file(&cfg, DAEMON_NAME".cfg")) { syslog(LOG_INFO, "Config error > /etc/%s - %s\n", config_error_file(&cfg),config_error_text(&cfg)); config_destroy(&cfg); daemonShutdown(); exit(EXIT_FAILURE); } if (!config_lookup_string(&cfg, "vzserver", &vzserver)) { syslog(LOG_INFO, "Missing 'VzServer' setting in configuration file."); config_destroy(&cfg); daemonShutdown(); exit(EXIT_FAILURE); } else syslog(LOG_INFO, "VzServer:%s", vzserver); if (!config_lookup_int(&cfg, "vzport", &vzport)) { syslog(LOG_INFO, "Missing 'VzPort' setting in configuration file."); config_destroy(&cfg); daemonShutdown(); exit(EXIT_FAILURE); } else syslog(LOG_INFO, "VzPort:%d", vzport); if (!config_lookup_string(&cfg, "vzpath", &vzpath)) { syslog(LOG_INFO, "Missing 'VzPath' setting in configuration file."); config_destroy(&cfg); daemonShutdown(); exit(EXIT_FAILURE); } else syslog(LOG_INFO, "VzPath:%s", vzpath); for (i=0; i0) { for (i=0; i