diff --git a/cronjob/chart/Makefile b/cronjob/chart/Makefile new file mode 100644 index 0000000..48a0d73 --- /dev/null +++ b/cronjob/chart/Makefile @@ -0,0 +1,75 @@ +CC = gcc +LD = gcc +RM = rm +CFLAGS = -c +LDFLAS = -o +INCL = -I$$(pg_config --includedir) + +BIN_NAME = chart +OBJS = chart.o config.o + +CONF_NAME = chart.conf + +INSTDIR = /usr/bin/ +CONFDIR = /etc/ +INSTGRP = losinski +INSTUSR = losinski + +DESTDIR = /home/losinski + +# Alles bauen +all: $(BIN_NAME) +# $(MAKE) cleanup + + +# Binary Linken +$(BIN_NAME): $(OBJS) + @ echo Linke: $(LD) $(DEBUG) $(NOLOG) -L$$(pg_config --libdir)/pgsql -lesmtp -lssl -lpq $(LDFLAS) $(BIN_NAME) $(OBJS) + @ $(LD) $(DEBUG) $(NOLOG) -L$$(pg_config --libdir)/pgsql -lesmtp -lssl -lpq $(LDFLAS) $(BIN_NAME) $(OBJS) + @ echo Binary $(BIN_NAME) ist fertig! + +# Abhängigkeiten +chart.o: chart.c definitions.h config.h chart.h +config.o: config.c config.h definitions.h chart.h + +# Compillieren +$(OBJS): + @ echo "Kompilliere: "$(CC) $(DEBUG) $(NOLOG) $(INCL) $(CFLAGS) $*.c + @ $(CC) $(DEBUG) $(NOLOG) $(INCL) $(CFLAGS) $*.c + +# Programm mit debug-ausgabe bauen +debug: + @ echo "baue Version mit Debugoutput ..." + @ $(MAKE) all DEBUG=-DDEBUG + +# Installieren +install: + @ echo "kopiere $(BIN_NAME) nach $(DESTDIR)$(INSTDIR)" + @ mkdir -p $(DESTDIR)$(INSTDIR); \ + cp $(BIN_NAME) $(DESTDIR)$(INSTDIR) + @ echo "setze Rechte auf $(BIN_NAME)" + @ cd $(DESTDIR)$(INSTDIR); \ + chmod 755 $(BIN_NAME); \ + chgrp $(INSTGRP) $(BIN_NAME); \ + chown $(INSTUSR) $(BIN_NAME) + @ echo "kopiere $(CONF_NAME) nach $(DESTDIR)$(CONFDIR)" + @ mkdir -p $(DESTDIR)$(CONFDIR); \ + cp $(CONF_NAME) $(DESTDIR)$(CONFDIR) + @ echo "setze Rechte auf $(CONF_NAME)" + @ cd $(DESTDIR)$(CONFDIR); \ + chmod 755 $(CONF_NAME); \ + chgrp $(CONFGRP) $(CONF_NAME); \ + chown $(CONFUSR) $(CONF_NAME) + + +# Aufräumnen (alle Object-Files löschen) +cleanup: + @ echo "Räume auf..." + @ echo "...entferne Object-Files:" + @ echo " " $(OBJS) + @ $(RM) -f $(OBJS) + +clean: cleanup + @ echo "...lösche binary:" + @ echo " " $(BIN_NAME) + @ rm -f $(BIN_NAME) diff --git a/cronjob/chart/chart.c b/cronjob/chart/chart.c new file mode 100644 index 0000000..af4420a --- /dev/null +++ b/cronjob/chart/chart.c @@ -0,0 +1,100 @@ +/* + + chart.c -- Part of Chart-generator for the weatherstation + + Copyright (C) 2006 Jan Losinski + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "definitions.h" +#include "config.h" +#include "chart.h" + +static void exit_sig_handler(int); + +config global_opts; + +int main(int argc, char *argv[]){ + DEBUGOUT1("Programm gestartet\n"); + + if(signal(SIGABRT, exit_sig_handler) == SIG_ERR) + exit_error(ERROR_SEIINST); + DEBUGOUT1("Signalhandler zum beenden per SIGABRT installiert\n"); + if(signal(SIGINT, exit_sig_handler) == SIG_ERR) + exit_error(ERROR_SEIINST); + DEBUGOUT1("Signalhandler zum beenden per SIGINT installiert\n"); + if(signal(SIGQUIT, exit_sig_handler) == SIG_ERR) + exit_error(ERROR_SEIINST); + DEBUGOUT1("Signalhandler zum beenden per SIGQUIT installiert\n"); + if(signal(SIGTERM, exit_sig_handler) == SIG_ERR) + exit_error(ERROR_SEIINST); + DEBUGOUT1("Signalhandler zum beenden per SIGTERM installiert\n"); + + read_config(DEFAULT_CONFIG_FILE, 1); + + /* Debug-Ausgaben, um zu sehen, ob die Optionen richtig gesetzt werden */ + DEBUGOUT1("\nOptionen:\n"); + DEBUGOUT2(" cfg_location = %s\n", global_opts.image_cfg_location); + DEBUGOUT2(" fork = %i\n", global_opts.fork); + + DEBUGOUT1("\nPostgres:\n"); + DEBUGOUT2(" Host: = %s\n",global_opts.pg_host); + DEBUGOUT2(" User: = %s\n",global_opts.pg_user); + DEBUGOUT2(" Pass: = %s\n",global_opts.pg_pass); + DEBUGOUT2(" Datenbank = %s\n",global_opts.pg_database); + + return EXIT_SUCCESS; +} + + +/* Diese Funktion beendet das Programm mit einer Fehlermeldung. */ +void exit_error(char* err){ + DEBUGOUT1("\nEtwas unschoenes ist passiert\n"); + if(errno != 0){ + perror("Fehler"); + } + write(STDOUT_FILENO, err, strlen(err)); + exit(1); +} + +/* Wird bei Beendigungssignalen ausgefuehrt */ +static void exit_sig_handler(int signr){ + #ifdef DEBUG + DEBUGOUT1("\n"); + switch (signr){ + case SIGABRT: + DEBUGOUT1("SIGABRT Interupt erhalten!\n"); + case SIGTERM: + DEBUGOUT1("SIGTERM Interupt erhalten!\n"); + case SIGQUIT: + DEBUGOUT1("SIGQUIT Interupt erhalten!\n"); + case SIGINT: + DEBUGOUT1("SIGINT Interupt erhalten!\n"); + } + #endif + DEBUGOUT1("Beende Programm...\n"); + exit(0); +} diff --git a/cronjob/chart/chart.conf b/cronjob/chart/chart.conf new file mode 100644 index 0000000..7c3e056 --- /dev/null +++ b/cronjob/chart/chart.conf @@ -0,0 +1,10 @@ +fork yes +image_cfg bla +image_cfg_location blub/ + + +# Postgres-Einstellungen +pg_host 141.30.228.39 +pg_user losinshi +#pg_pass +pg_database wetter diff --git a/cronjob/chart/chart.h b/cronjob/chart/chart.h new file mode 100644 index 0000000..451465b --- /dev/null +++ b/cronjob/chart/chart.h @@ -0,0 +1,46 @@ +/* + + chart.h -- Part of Chart-generator for the weatherstation + + Copyright (C) 2006 Jan Losinski + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +typedef struct image_cfg_list_t *image_cfg_list_ptr; +typedef struct image_cfg_list_t { + char *image_cfg_file; + image_cfg_list_ptr next; +} image_cfg_list; + +typedef struct config_t { + char *pg_host; + char *pg_database; + char *pg_user; + char *pg_pass; + char *image_cfg_location; + image_cfg_list_ptr image_cfg; + int fork; +} config; + +extern config global_opts; + + +/* Funktionen -------------------------------------------------------------*/ + +/* Programm mit einem Fatalem Fehler beenden. + * Argument: Fehlermeldung */ +void exit_error(char*); diff --git a/cronjob/chart/config.c b/cronjob/chart/config.c new file mode 100644 index 0000000..8f3d654 --- /dev/null +++ b/cronjob/chart/config.c @@ -0,0 +1,179 @@ +/* + + config.c -- Part of Chart-generator for the weatherstation + + Copyright (C) 2006 Jan Losinski + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/* + * Wenn mehr kommentare benoetigt werden: + * losinski@wh2.tu-dresden.de + * */ + + +#include +#include +#include + +#include "config.h" +#include "definitions.h" +#include "chart.h" + +/* Funktionsdefinitionen */ +static int read_int(const char *, void *); +static int read_yn(const char *, void *); +static int add_image_cfg(const char *, void *); +static int read_str(const char *, void *); + + +/* Zuordnung zwischen Schlüsselwörtern in der Config, Der Funktion, die diese auswertet + * und dem eld in der Options-Struktur */ +static const struct config_keyword keywords[] = { + /* keyword handler variable address default */ + {"fork", read_yn, &(global_opts.fork), ""}, + {"image_cfg", add_image_cfg, &(global_opts.image_cfg), ""}, + {"image_cfg_location",read_str, &(global_opts.image_cfg_location), DEFAULT_PG_HOST}, + + {"pg_host", read_str, &(global_opts.pg_host), DEFAULT_PG_HOST}, + {"pg_user", read_str, &(global_opts.pg_user), DEFAULT_PG_USER}, + {"pg_pass", read_str, &(global_opts.pg_pass), DEFAULT_PG_PASS}, + {"pg_database", read_str, &(global_opts.pg_database), DEFAULT_PG_DATABASE}, + {"", NULL, NULL, ""} +}; + + +/* Implementierungen */ + + +/* Liest eine Option (line) als String und speichert diese in + * dem entsprechendem Feld der Optionen-Struktur (arg) */ +static int read_str(const char *line, void *arg){ + char **dest = arg; + if (*dest) free(*dest); + *dest = strdup(line); + return 1; +} + + +/* Interval lesen, indem die Sensoren das letzte mal etwas gesendet haben sollen */ +static int read_int(const char *line, void *arg){ + int *dest = arg; + *dest = atoi(line); +} + +/* lesen, ob id's aus der Datenbank gelesen werden sollen oder nicht */ +static int read_yn(const char *line, void *arg){ + char *dest = arg; + int retval = 1; + if (!strcasecmp("yes", line)) + *dest = 1; + else if (!strcasecmp("no", line)) + *dest = 0; + else retval = 0; + return retval; +} + +/* fuegt eine id zur liste hinzu */ +static int add_image_cfg(const char *line, void *arg){ + image_cfg_list_ptr cfg_new, cfg_temp; + + cfg_new = malloc(sizeof(image_cfg_list)); + cfg_new->next = NULL; + cfg_new->image_cfg_file = strdup(line); + + DEBUGOUT2("add cfg: %s\n", line); + + cfg_temp = *((image_cfg_list_ptr*)arg); + if (cfg_temp == NULL){ + cfg_temp = cfg_new; + *((image_cfg_list_ptr*)arg) = cfg_temp; + } else { + while (cfg_temp->next != NULL){ + cfg_temp = cfg_temp->next; + } + cfg_temp->next = cfg_new; + } + return 1; +} + + + +/* Liest und verarbeitet die Config-File + * der Integer reset gibt an, ob zu begin defaultwerte + * gesetzt werden sollen oder nicht */ +int read_config(const char *file, int reset){ + FILE *in; /* File-Handler */ + char buffer[CONFIG_BUFFERSIZE], *token, *line; /* Puffer zum lesen der config-file (imer 1 Zeile)*/ + char orig[CONFIG_BUFFERSIZE]; /* Originalpuffer zum lesen der config-file, um die Log und debug-ausgabe zu realisieren */ + int i; /* Laufvariable */ + int lm = 0; /* Zeilen-Nummer */ + + + /* Optionen mit default-werten füllen */ + if(reset){ + for (i = 0; keywords[i].keyword[0]; i++) + //printf("keyword: %s \n",keywords[i].keyword); + if (keywords[i].def[0]) + keywords[i].handler(keywords[i].def, keywords[i].var); + } + + /* config-file öffnen */ + if (!(in = fopen(file, "r"))) { + DEBUGOUT2("Kann Config-File: %s nicht öffnen!\n", file); + return 0; + } + + /* Datei Zeilenweise lesen */ + while (fgets(buffer, CONFIG_BUFFERSIZE, in)) { + lm++; + + /* Zeilenvorschübe gegen null-terminierungs-Zeichen ersetzen */ + if (strchr(buffer, '\n')) *(strchr(buffer, '\n')) = '\0'; + + /* Originlzeile für eventuelle log-, bzw. debug-meldungen */ + strcpy(orig, buffer); + + /* Kommentazeichen gegen null-terminierungs-Zeichen ersetzen und damit alles dahinter ignorieren */ + if (strchr(buffer, '#')) *(strchr(buffer, '#')) = '\0'; + + + if (!(token = strtok(buffer, " \t"))) continue; + if (!(line = strtok(NULL, ""))) continue; + + /* eat leading whitespace */ + line = line + strspn(line, " \t="); + /* eat trailing whitespace */ + for (i = strlen(line); i > 0 && isspace(line[i - 1]); i--); + line[i] = '\0'; + + for (i = 0; keywords[i].keyword[0]; i++){ + if (!strcasecmp(token, keywords[i].keyword)){ + if (!keywords[i].handler(line, keywords[i].var)) { + /* Fehler ins Logfile schreiben */ + DEBUGOUT4("Kann '%s' nicht Parsen (%s:%d)!\n", orig, file, lm); + /* reset back to the default value */ + keywords[i].handler(keywords[i].def, keywords[i].var); + } + } + } + } + fclose(in); + return 1; +} + + diff --git a/cronjob/chart/config.h b/cronjob/chart/config.h new file mode 100644 index 0000000..8654ca1 --- /dev/null +++ b/cronjob/chart/config.h @@ -0,0 +1,38 @@ +/* + + config.h -- Part of Chart-generator for the weatherstation + + Copyright (C) 2006 Jan Losinski + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id: process.c v 1.00 11 Aug 2006 losinski $ +*/ + + + + +/* Datenstruktur zum Auswerten des Config-Files */ +struct config_keyword { + const char *keyword; + int (* const handler)(const char *line, void *var); + void *var; + const char *def; +} ; + +/* Config lesen */ +int read_config(const char *, int); + + diff --git a/cronjob/chart/definitions.h b/cronjob/chart/definitions.h new file mode 100644 index 0000000..d4ce2d3 --- /dev/null +++ b/cronjob/chart/definitions.h @@ -0,0 +1,76 @@ +/* + + weatherdeamon -- Weather Data Capture Program for the + 'ELV-PC-Wettersensor-Empfänger' + definitions.h -- Part of the weatherdeamon + + Copyright (C) 2006 Jan Losinski + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id: process.c v 1.00 11 Aug 2006 losinski $ +*/ + +/* Default-Werte ----------------------------------------------------- */ +#define DEFAULT_PG_HOST "localhost" /* Postgres-host */ +#define DEFAULT_PG_USER "localuser" /* Postgres-Username */ +#define DEFAULT_PG_PASS "" /* Postgres-Passwort */ +#define DEFAULT_PG_DATABASE "localbase" /* Postgres-Datenbank */ +#define DEFAULT_CONFIG_FILE "./chart.conf" /* Standart-Configdatei */ + + + +/*Alle möglichen Definitionen, die in allen code-schnipseln benötigt werden*/ + + +/* Fehlermeldungen ------------------------------------------------------*/ +#define ERROR_SEIINST "Signal-Fehler: Kann Signalhandler zum beenden nicht installieren\n" + + +/* Puffergrößen -------------------------------------------------------- */ +#define CONFIG_BUFFERSIZE 512 /* Größe des Puffers zum Config-einlesen */ +#define QUERY_BUFFERSIZE 512 /* Größe des Zeichenpuffers für SQL-Anfragen */ + + +/* Verschiedenes ------------------------------------------------------- */ +#define FALSE 0 +#define TRUE 1 + + +/* Debug --------------------------------------------------------------- */ +#ifdef DEBUG + #define DEBUGOUT1(x) fprintf(stderr,x) + #define DEBUGOUT2(x,y) fprintf(stderr,x,y) + #define DEBUGOUT3(x,y,z) fprintf(stderr,x,y,z) + #define DEBUGOUT4(x,y,z,a) fprintf(stderr,x,y,z,a) + #define DEBUGOUT5(x,y,z,a,b) fprintf(stderr,x,y,z,a,b) + #define FOR(x) for(x) +#else + #define DEBUGOUT1(x) + #define DEBUGOUT2(x,y) + #define DEBUGOUT3(x,y,z) + #define DEBUGOUT4(x,y,z,a) + #define DEBUGOUT5(x,y,z,a,b) + #define FOR(x) +#endif + +/* Dumping der Daten --------------------------------------------------- */ +#ifndef NO_LOGING + #define LOG_DATA(x,y) log_data(x.y) + #define LOG_ERROR(x) log_error(x) +#else + #define LOG_DATA(x,y) + #define LOG_ERROR(x) +#endif diff --git a/cronjob/chart/main.c b/cronjob/chart/main.c new file mode 100644 index 0000000..a701ff3 --- /dev/null +++ b/cronjob/chart/main.c @@ -0,0 +1,23 @@ +#include +#include +#include +#include +#include + +int main(){ + int i; + pid_t p; + for(i=0; i<2; i++){ + if((p = fork()) == 0){ + sleep(10); + exit(0); + } + sleep(1); + printf("Process %i created\n",p); + } + while((p = wait(&i))!=-1){ + printf("pid: %i\n",p); + } +printf("alle Prozesse beendet\n"); + exit(0); +}