summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore11
-rw-r--r--LICENSE2
-rw-r--r--Makefile59
-rw-r--r--src/Makefile122
-rw-r--r--src/client_list.c137
-rw-r--r--src/client_list.h52
-rw-r--r--src/command_queue.c118
-rw-r--r--src/command_queue.h46
-rwxr-xr-xsrc/configure194
-rw-r--r--src/daemon.h161
-rw-r--r--src/datatypes.h54
-rw-r--r--src/health-watch.lua107
-rw-r--r--src/heartbeatclient.c428
-rw-r--r--src/key_value_storage.c92
-rw-r--r--src/key_value_storage.h41
-rw-r--r--src/l_cmd.c158
-rw-r--r--src/l_cmd.h32
-rw-r--r--src/l_log.c117
-rw-r--r--src/l_log.h30
-rw-r--r--src/l_sig_handler.c96
-rw-r--r--src/l_sig_handler.h30
-rw-r--r--src/log.c246
-rw-r--r--src/log.h76
-rw-r--r--src/log_targets.h349
-rw-r--r--src/luaclient.c293
-rw-r--r--src/mode-tcpserver.lua175
-rw-r--r--src/mode-watch.lua119
-rw-r--r--src/options.c555
-rw-r--r--src/options.h87
-rw-r--r--src/rhctl/main.go103
-rw-r--r--src/serialclient.c287
-rw-r--r--src/sig_handler.c149
-rw-r--r--src/sig_handler.h31
-rw-r--r--src/silence-watch.lua87
-rw-r--r--src/stdioclient.c190
-rw-r--r--src/string_list.c99
-rw-r--r--src/string_list.h42
-rw-r--r--src/switchctl.c1211
-rw-r--r--src/utils.c172
-rw-r--r--src/utils.h35
-rw-r--r--src/utils.lua35
41 files changed, 166 insertions, 6262 deletions
diff --git a/.gitignore b/.gitignore
index 171da9e..23950cf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,3 @@
-src/*.d
-src/*.o
-src/include.mk
-src/switchctl
-src/serialclient
-src/stdioclient
-src/heartbeatclient
-src/luaclient
+bin/
+pkg/
+src/github.com
diff --git a/LICENSE b/LICENSE
index 9bad8f0..525d296 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,7 +1,7 @@
/*
* rhctl
*
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
+ * Copyright (C) 2009-2016 Christian Pointner <equinox@helsinki.at>
*
* This file is part of rhctl.
*
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..2b06bd5
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,59 @@
+##
+## rhctl
+##
+## Copyright (C) 2009-2016 Christian Pointner <equinox@helsinki.at>
+##
+## This file is part of rhctl.
+##
+## rhctl 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
+## any later version.
+##
+## rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
+##
+
+curdir:= $(shell pwd)
+GOCMD := GOPATH=$(curdir) go
+
+EXECUTEABLE := rhctl
+
+LIBS := "github.com/schleibinger/sio"
+
+
+.PHONY: getlibs updatelibs vet format build clean distclean
+all: build
+
+
+getlibs:
+ @$(foreach lib,$(LIBS), echo "fetching lib: $(lib)"; $(GOCMD) get $(lib);)
+
+updatelibs:
+ @$(foreach lib,$(LIBS), echo "updating lib: $(lib)"; $(GOCMD) get -u $(lib);)
+
+vet:
+ @echo "vetting: $(EXECUTEABLE)"
+ @$(GOCMD) vet $(EXECUTEABLE)
+
+format:
+ @echo "formating: $(EXECUTEABLE)"
+ @$(GOCMD) fmt $(EXECUTEABLE)
+
+build: getlibs
+ @echo "installing: $(EXECUTEABLE)"
+ @$(GOCMD) install $(EXECUTEABLE)
+
+
+clean:
+ rm -rf pkg/*/$(EXECUTEABLE)
+ rm -rf bin
+
+distclean: clean
+ @$(foreach dir,$(shell ls src/),$(if $(subst $(EXECUTEABLE),,$(dir)),$(shell rm -rf src/$(dir))))
+ rm -rf pkg
diff --git a/src/Makefile b/src/Makefile
deleted file mode 100644
index 2751eb7..0000000
--- a/src/Makefile
+++ /dev/null
@@ -1,122 +0,0 @@
-##
-## rhctl
-##
-## Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
-##
-## This file is part of rhctl.
-##
-## rhctl 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
-## any later version.
-##
-## rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
-##
-
-ifneq ($(MAKECMDGOALS),distclean)
-include include.mk
-endif
-
-EXE_SWITCHCTL := switchctl
-EXE_SERIALCLIENT := serialclient
-EXE_STDIOCLIENT := stdioclient
-EXE_HEARTBEATCLIENT := heartbeatclient
-EXE_LUACLIENT := luaclient
-
-COMMONOBJ := log.o \
- sig_handler.o \
- string_list.o \
- key_value_storage.o \
- utils.o
-
-SWITCHCTLOBJ := command_queue.o \
- client_list.o \
- opt-switchctl.o \
- switchctl.o
-
-SERIALCLIENTOBJ := opt-serialclient.o \
- serialclient.o
-
-STDIOCLIENTOBJ := opt-stdioclient.o \
- stdioclient.o
-
-HEARTBEATCLIENTOBJ := opt-heartbeatclient.o \
- heartbeatclient.o
-
-LUACLIENTOBJ := opt-luaclient.o \
- l_log.o \
- l_sig_handler.o \
- l_cmd.o \
- luaclient.o
-
-
-SRC := $(COMMONOBJ:%.o=%.c) $(SWITCHCTLOBJ:%.o=%.c) $(SERIALCLIENTOBJ:%.o=%.c) $(STDIOCLIENTOBJ:%.o=%.c) $(HEARTBEATCLIENTOBJ:%.o=%.c) $(LUACLIENTOBJ:%.o=%.c) options.c
-
-.PHONY: clean distclean
-
-all: $(EXE_SWITCHCTL) $(EXE_SERIALCLIENT) $(EXE_STDIOCLIENT) $(EXE_HEARTBEATCLIENT) $(EXE_LUACLIENT)
-
-%.d: %.c
- @set -e; rm -f $@; \
- $(CC) -MM $(CFLAGS) $< > $@.$$$$; \
- sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
- rm -f $@.$$$$; echo '(re)building $@'
-
-ifneq ($(MAKECMDGOALS),distclean)
--include $(SRC:%.c=%.d)
-endif
-
-$(EXE_SWITCHCTL): $(COMMONOBJ) $(SWITCHCTLOBJ)
- $(CC) $(COMMONOBJ) $(SWITCHCTLOBJ) -o $@ $(LDFLAGS)
-
-$(EXE_SERIALCLIENT): $(COMMONOBJ) $(SERIALCLIENTOBJ)
- $(CC) $(COMMONOBJ) $(SERIALCLIENTOBJ) -o $@ $(LDFLAGS)
-
-$(EXE_STDIOCLIENT): $(COMMONOBJ) $(STDIOCLIENTOBJ)
- $(CC) $(COMMONOBJ) $(STDIOCLIENTOBJ) -o $@ $(LDFLAGS)
-
-$(EXE_HEARTBEATCLIENT): $(COMMONOBJ) $(HEARTBEATCLIENTOBJ)
- $(CC) $(COMMONOBJ) $(HEARTBEATCLIENTOBJ) -o $@ $(LDFLAGS)
-
-$(EXE_LUACLIENT): $(COMMONOBJ) $(LUACLIENTOBJ)
- $(CC) $(COMMONOBJ) $(LUACLIENTOBJ) -o $@ $(LDFLAGS) $(LUA_LDFLAGS)
-
-opt-switchctl.o: options.c
- $(CC) $(CFLAGS) -DOPT_SWITCHCTL -o $@ -c $<
-
-opt-serialclient.o: options.c
- $(CC) $(CFLAGS) -DOPT_SERIALCLIENT -o $@ -c $<
-
-opt-stdioclient.o: options.c
- $(CC) $(CFLAGS) -DOPT_STDIOCLIENT -o $@ -c $<
-
-opt-heartbeatclient.o: options.c
- $(CC) $(CFLAGS) -DOPT_HEARTBEATCLIENT -o $@ -c $<
-
-opt-luaclient.o: options.c
- $(CC) $(CFLAGS) -DOPT_LUACLIENT -o $@ -c $<
-
-%.o: %.c
- $(CC) $(CFLAGS) -c $<
-
-
-distclean: clean
- find . -name *.o -exec rm -f {} \;
- find . -name "*.\~*" -exec rm -rf {} \;
- rm -f include.mk
-
-clean:
- rm -f *.o
- rm -f *.d
- rm -f *.d.*
- rm -f $(EXE_SWITCHCTL)
- rm -f $(EXE_SERIALCLIENT)
- rm -f $(EXE_STDIOCLIENT)
- rm -f $(EXE_HEARTBEATCLIENT)
- rm -f $(EXE_LUACLIENT)
diff --git a/src/client_list.c b/src/client_list.c
deleted file mode 100644
index f21aea3..0000000
--- a/src/client_list.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "client_list.h"
-#include "datatypes.h"
-
-char* client_type_tostring(client_type_t type)
-{
- switch(type)
- {
- case MASTER: return "master";
- case STANDBY: return "standby";
- case HB_MASTER: return "hb_master";
- case HB_STANDBY: return "hb_standby";
- case DEFAULT: return "unspecified";
- }
- return "<invalid>";
-}
-
-client_t* client_get_last(client_t* first)
-{
- if(!first)
- return NULL;
-
- while(first->next) {
- first = first->next;
- }
-
- return first;
-}
-
-int client_add(client_t** first, int fd)
-{
- if(!first)
- return -1;
-
- client_t* new_client = malloc(sizeof(client_t));
- if(!new_client)
- return -2;
-
- new_client->fd = fd;
- new_client->type = DEFAULT;
- new_client->request_listener = 0;
- new_client->mode_listener = 0;
- new_client->status_listener = 0;
- new_client->gpi_listener = 0;
- new_client->oc_listener = 0;
- new_client->relay_listener = 0;
- new_client->silence_listener = 0;
- new_client->health_listener = 0;
- new_client->next = NULL;
- new_client->buffer.offset = 0;
-
- if(!(*first)) {
- *first = new_client;
- return 0;
- }
-
- client_get_last(*first)->next = new_client;
-
- return 0;
-}
-
-void client_remove(client_t** first, int fd)
-{
- if(!first || !(*first))
- return;
-
- client_t* deletee = *first;
- if((*first)->fd == fd) {
- *first = (*first)->next;
- close(deletee->fd);
- free(deletee);
- return;
- }
-
- client_t* prev = deletee;
- deletee = deletee->next;
- while(deletee) {
- if(deletee->fd == fd) {
- prev->next = deletee->next;
- close(deletee->fd);
- free(deletee);
- return;
- }
- prev = deletee;
- deletee = deletee->next;
- }
-}
-
-client_t* client_find(client_t* first, int fd)
-{
- if(!first)
- return NULL;
-
- while(first) {
- if(first->fd == fd)
- return first;
-
- first = first->next;
- }
- return NULL;
-}
-
-void client_clear(client_t** first)
-{
- if(!first || !(*first))
- return;
-
- while(*first) {
- client_t* deletee = *first;
- *first = (*first)->next;
- close(deletee->fd);
- free(deletee);
- }
-}
diff --git a/src/client_list.h b/src/client_list.h
deleted file mode 100644
index d0b6d3e..0000000
--- a/src/client_list.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef RHCTL_client_list_h_INCLUDED
-#define RHCTL_client_list_h_INCLUDED
-
-#include "datatypes.h"
-
-enum client_type_enum { DEFAULT, MASTER, STANDBY, HB_MASTER, HB_STANDBY };
-typedef enum client_type_enum client_type_t;
-char* client_type_tostring(client_type_t);
-
-struct client_struct {
- int fd;
- client_type_t type;
- int request_listener;
- int mode_listener;
- int status_listener;
- int gpi_listener;
- int oc_listener;
- int relay_listener;
- int silence_listener;
- int health_listener;
- struct client_struct* next;
- read_buffer_t buffer;
-};
-typedef struct client_struct client_t;
-
-int client_add(client_t** first, int fd);
-void client_remove(client_t** first, int fd);
-client_t* client_find(client_t* first, int fd);
-void client_clear(client_t** first);
-
-#endif
diff --git a/src/command_queue.c b/src/command_queue.c
deleted file mode 100644
index d59f7ef..0000000
--- a/src/command_queue.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "command_queue.h"
-#include "datatypes.h"
-
-cmd_t* cmd_get_last(cmd_t* first)
-{
- if(!first)
- return NULL;
-
- while(first->next) {
- first = first->next;
- }
-
- return first;
-}
-
-int cmd_push(cmd_t** first, int fd, cmd_id_t cmd, const char* param)
-{
- if(!first)
- return -1;
-
- cmd_t* new_cmd = malloc(sizeof(cmd_t));
- if(!new_cmd)
- return -2;
-
- new_cmd->fd = fd;
- new_cmd->cmd = cmd;
- if(param) {
- new_cmd->param = strdup(param);
- if(!new_cmd->param) {
- free(new_cmd);
- return -2;
- }
- }
- else
- new_cmd->param = NULL;
- new_cmd->sent = 0;
- new_cmd->tv_start.tv_sec = 0;
- new_cmd->tv_start.tv_usec = 0;
- new_cmd->next = NULL;
-
- if(!(*first)) {
- *first = new_cmd;
- return 0;
- }
-
- cmd_get_last(*first)->next = new_cmd;
-
- return 0;
-}
-
-void cmd_sent(cmd_t* cmd)
-{
- if(!cmd)
- return;
-
- cmd->sent = 1;
- gettimeofday(&cmd->tv_start, NULL);
-}
-
-int cmd_has_expired(cmd_t cmd)
-{
- struct timeval now;
- timerclear(&now);
- gettimeofday(&now, NULL);
- cmd.tv_start.tv_sec++;
-
- return timercmp(&cmd.tv_start, &now, <);
-}
-
-void cmd_pop(cmd_t** first)
-{
- if(!first || !(*first))
- return;
-
- cmd_t* deletee = *first;
- *first = (*first)->next;
- if(deletee->param)
- free(deletee->param);
- free(deletee);
-}
-
-void cmd_clear(cmd_t** first)
-{
- if(!first || !(*first))
- return;
-
- while(*first) {
- cmd_t* deletee = *first;
- *first = (*first)->next;
- if(deletee->param)
- free(deletee->param);
- free(deletee);
- }
-}
diff --git a/src/command_queue.h b/src/command_queue.h
deleted file mode 100644
index 3e5cdb2..0000000
--- a/src/command_queue.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef RHCTL_command_queue_h_INCLUDED
-#define RHCTL_command_queue_h_INCLUDED
-
-#include <sys/time.h>
-
-enum cmd_id_enum { SWITCH, CHANNEL, TYPE, MODE, HEARTBEAT, STATUS, HEALTH, LOG, LISTEN };
-typedef enum cmd_id_enum cmd_id_t;
-
-struct cmd_struct {
- int fd;
- cmd_id_t cmd;
- char* param;
- int sent;
- struct timeval tv_start;
- struct cmd_struct* next;
-};
-typedef struct cmd_struct cmd_t;
-
-int cmd_push(cmd_t** first, int fd, cmd_id_t cmd, const char* param);
-void cmd_sent(cmd_t* cmd);
-int cmd_has_expired(cmd_t cmd);
-void cmd_pop(cmd_t** first);
-void cmd_clear(cmd_t** first);
-
-#endif
diff --git a/src/configure b/src/configure
deleted file mode 100755
index 6b8bdf6..0000000
--- a/src/configure
+++ /dev/null
@@ -1,194 +0,0 @@
-#!/bin/sh
-#
-# rhctl
-#
-# Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
-#
-# This file is part of rhctl.
-#
-# rhctl 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
-# any later version.
-#
-# rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
-#
-
-TARGET=`uname -s`
-
-USE_CLANG=0
-
-LUA_LDFLAGS='-lm'
-LUA_DIR=''
-LUA=''
-LUA_VER=''
-
-
-print_usage() {
- echo "configure --help print this"
- echo " --target=<TARGET> build target i.e. Linux (default: autodetect)"
- echo " --with-lua=<DIR> use this lua tree instead of system default"
- echo " --lua-version=nnn set fixed Lua version for automatic detection (501 -> 5.1, 502 -> 5.2)"
- echo " --use-clang use clang/llvm as compiler/linker"
-}
-
-for arg
-do
- case $arg in
- --target=*)
- TARGET=${arg#--target=}
- ;;
- --use-clang)
- USE_CLANG=1
- ;;
- --with-lua=*)
- LUA_DIR=${arg#--with-lua=}
- ;;
- --lua-version=*)
- LUA_VER=${arg#--lua-version=}
- ;;
- --help)
- print_usage
- exit 0
- ;;
- *)
- echo "Unknown argument: $arg"
- print_usage
- exit 1
- ;;
- esac
-done
-
-if [ $USE_CLANG -eq 0 ]; then
- CFLAGS='-g -Wall -O2'
- LDFLAGS='-g -Wall -O2'
- COMPILER='gcc'
-else
- CFLAGS='-g -O2'
- LDFLAGS='-g -O2'
- COMPILER='clang'
-fi
-
-rm -f include.mk
-case $TARGET in
- Linux)
- echo "Linux specific build options"
- LUA_LDFLAGS=$LUA_LDFLAGS' -ldl'
- ;;
- OpenBSD|FreeBSD|NetBSD)
- echo "BSD specific build options"
- CFLAGS=$CFLAGS' -I/usr/local/include'
- LDFLAGS=$LDFLAGS' -L/usr/local/lib'
- ;;
- *)
- echo "Plattform not supported"
- exit 1;
- ;;
-esac
-
-test_lua_version()
-{
- LUA_VERSION_MAJ=`cat $1 | grep "#define LUA_VERSION_MAJOR[ ]" | cut -f2- | tr -d '"'`
- LUA_VERSION_MIN=`cat $1 | grep "#define LUA_VERSION_MINOR[ ]" | cut -f2- | tr -d '"'`
- LUA_VERSION_REL=`cat $1 | grep "#define LUA_VERSION_RELEASE[ ]" | cut -f2- | tr -d '"'`
-
- LUA_VERSION="$LUA_VERSION_MAJ.$LUA_VERSION_MIN"
- LUA_RELEASE="$LUA_VERSION_MAJ.$LUA_VERSION_MIN.$LUA_VERSION_REL"
-
- if [ -z "$LUA_VERSION_MAJ" ]; then
- LUA_VERSION=`cat $1 | grep "#define LUA_VERSION[ ]" | cut -f2- | tr -d '"' | sed -e 's/Lua \([0-9][0-9.]*\)/\1/'`
- LUA_RELEASE=`cat $1 | grep "#define LUA_RELEASE[ ]" | cut -f2- | tr -d '"' | sed -e 's/Lua //'`
- fi
-
- LUA_VERSION_NUM=`cat $1 | grep "#define LUA_VERSION_NUM" | awk '{ print $3 }'`
-
- if [ -n "$LUA_VER" ]; then
- if [ "$LUA_VER" -eq $LUA_VERSION_NUM ]; then
- return 1
- else
- return 0
- fi
- else
- if [ $LUA_VERSION_NUM -ge 501 ]; then
- return 1
- else
- return 0
- fi
- fi
-}
-
-if [ -z "$LUA_DIR" ]; then
- for prefix in /usr /usr/local; do
- if [ -e $prefix/include/lua.h ]; then
- test_lua_version $prefix/include/lua.h
- if [ $? -eq 1 ]; then
- echo "using Lua $LUA_VERSION ($LUA_RELEASE) found at $prefix/include"
- CFLAGS="$CFLAGS -I'$prefix/include'"
- LUA_LDFLAGS="$LUA_LDFLAGS -L'$prefix/lib' -llua"
- LUA=$prefix/lua
- LUAC=$prefix/luac
- break
- fi
- else
- for dir in `ls -r -d $prefix/include/lua* 2> /dev/null`; do
- if [ -e $dir/lua.h ]; then
- test_lua_version $dir/lua.h
- if [ $? -eq 1 ]; then
- echo "using Lua $LUA_VERSION ($LUA_RELEASE) found at $dir"
- CFLAGS="$CFLAGS -I$dir"
- if [ -x "$prefix/bin/lua$LUA_VERSION" ]; then
- LUA_LDFLAGS="$LUA_LDFLAGS -L'$prefix/lib' -llua$LUA_VERSION"
- LUA=$prefix/bin/lua$LUA_VERSION
- LUAC=$prefix/bin/luac$LUA_VERSION
- elif [ -x "$prefix/bin/lua-$LUA_VERSION" ]; then
- LUA_LDFLAGS="$LUA_LDFLAGS -L'$prefix/lib' -llua-$LUA_VERSION"
- LUA=$prefix/bin/lua-$LUA_VERSION
- LUAC=$prefix/bin/luac-$LUA_VERSION
- else
- echo "ERROR: found lua.h at $dir/lua.h but no matching lua and luac"
- return 1
- fi
- break
- fi
- fi
- done
- if [ -n "$LUAC" ]; then
- break
- fi
- fi
- done
-
- if [ -z "$LUAC" ]; then
- echo "ERROR: no suitable lua found .. please install lua 5.1 or higher or use --with-lua"
- return 1
- fi
-
-else
- CFLAGS="$CFLAGS -I'$LUA_DIR/include'"
- LUA_LDFLAGS="$LUA_LDFLAGS '$LUA_DIR/lib/liblua.a'"
- LUA=$LUA_DIR/bin/lua
- LUAC=$LUA_DIR/bin/luac
-fi
-
-
-cat > include.mk <<EOF
-# this file was created automatically
-# do not edit this file directly
-# use ./configure instead
-
-TARGET := $TARGET
-CC := $COMPILER
-CFLAGS := $CFLAGS
-LDFLAGS := $LDFLAGS
-LUA := $LUA
-LUAC := $LUAC
-LUA_LDFLAGS := $LUA_LDFLAGS
-EOF
-
-exit 0
diff --git a/src/daemon.h b/src/daemon.h
deleted file mode 100644
index a75c328..0000000
--- a/src/daemon.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef RHCTL_daemon_h_INCLUDED
-#define RHCTL_daemon_h_INCLUDED
-
-#include <poll.h>
-#include <fcntl.h>
-#include <pwd.h>
-#include <grp.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-struct priv_info_struct {
- struct passwd* pw_;
- struct group* gr_;
-};
-typedef struct priv_info_struct priv_info_t;
-
-int priv_init(priv_info_t* priv, const char* username, const char* groupname)
-{
- if(!priv)
- return -1;
-
- priv->pw_ = NULL;
- priv->gr_ = NULL;
-
- priv->pw_ = getpwnam(username);
- if(!priv->pw_) {
- log_printf(ERROR, "unknown user %s", username);
- return -1;
- }
-
- if(groupname)
- priv->gr_ = getgrnam(groupname);
- else
- priv->gr_ = getgrgid(priv->pw_->pw_gid);
-
- if(!priv->gr_) {
- log_printf(ERROR, "unknown group %s", groupname);
- return -1;
- }
-
- return 0;
-}
-
-int priv_drop(priv_info_t* priv)
-{
- if(!priv || !priv->pw_ || !priv->gr_) {
- log_printf(ERROR, "privileges not initialized properly");
- return -1;
- }
-
- if(setgid(priv->gr_->gr_gid)) {
- log_printf(ERROR, "setgid('%s') failed: %s", priv->gr_->gr_name, strerror(errno));
- return -1;
- }
-
- gid_t gr_list[1];
- gr_list[0] = priv->gr_->gr_gid;
- if(setgroups (1, gr_list)) {
- log_printf(ERROR, "setgroups(['%s']) failed: %s", priv->gr_->gr_name, strerror(errno));
- return -1;
- }
-
- if(setuid(priv->pw_->pw_uid)) {
- log_printf(ERROR, "setuid('%s') failed: %s", priv->pw_->pw_name, strerror(errno));
- return -1;
- }
-
- log_printf(NOTICE, "dropped privileges to %s:%s", priv->pw_->pw_name, priv->gr_->gr_name);
- return 0;
-}
-
-
-int do_chroot(const char* chrootdir)
-{
- if(getuid() != 0) {
- log_printf(ERROR, "this program has to be run as root in order to run in a chroot");
- return -1;
- }
-
- if(chroot(chrootdir)) {
- log_printf(ERROR, "can't chroot to %s: %s", chrootdir, strerror(errno));
- return -1;
- }
- log_printf(NOTICE, "we are in chroot jail (%s) now", chrootdir);
- if(chdir("/")) {
- log_printf(ERROR, "can't change to /: %s", strerror(errno));
- return -1;
- }
-
- return 0;
-}
-
-void daemonize()
-{
- pid_t pid;
-
- pid = fork();
- if(pid < 0) {
- log_printf(ERROR, "daemonizing failed at fork(): %s, exitting", strerror(errno));
- exit(-1);
- }
- if(pid) exit(0);
-
- umask(0);
-
- if(setsid() < 0) {
- log_printf(ERROR, "daemonizing failed at setsid(): %s, exitting", strerror(errno));
- exit(-1);
- }
-
- pid = fork();
- if(pid < 0) {
- log_printf(ERROR, "daemonizing failed at fork(): %s, exitting", strerror(errno));
- exit(-1);
- }
- if(pid) exit(0);
-
- if ((chdir("/")) < 0) {
- log_printf(ERROR, "daemonizing failed at chdir(): %s, exitting", strerror(errno));
- exit(-1);
- }
-
- int fd;
- for (fd=0;fd<=2;fd++) // close all file descriptors
- close(fd);
- fd = open("/dev/null",O_RDWR); // stdin
- if(fd == -1)
- log_printf(WARNING, "can't open stdin (chroot and no link to /dev/null?)");
- else {
- if(dup(fd) == -1) // stdout
- log_printf(WARNING, "can't open stdout");
- if(dup(fd) == -1) // stderr
- log_printf(WARNING, "can't open stderr");
- }
- umask(027);
-}
-
-#endif
-
diff --git a/src/datatypes.h b/src/datatypes.h
deleted file mode 100644
index e6715b1..0000000
--- a/src/datatypes.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef RHCTL_datatypes_h_INCLUDED
-#define RHCTL_datatypes_h_INCLUDED
-
-#define _GNU_SOURCE
-#include <stdint.h>
-#include <arpa/inet.h>
-
-typedef uint8_t bool;
-#define FALSE 0
-#define TRUE 1
-
-typedef uint8_t u_int8_t;
-typedef uint16_t u_int16_t;
-typedef uint32_t u_int32_t;
-typedef uint64_t u_int64_t;
-/* typedef int8_t int8_t; */
-/* typedef int16_t int16_t; */
-/* typedef int32_t int32_t; */
-/* typedef int64_t int64_t; */
-
-struct buffer_struct {
- u_int32_t length_;
- u_int8_t* buf_;
-};
-typedef struct buffer_struct buffer_t;
-
-struct read_buffer_struct {
- u_int32_t offset;
- u_int8_t buf[100];
-};
-typedef struct read_buffer_struct read_buffer_t;
-
-#endif
diff --git a/src/health-watch.lua b/src/health-watch.lua
deleted file mode 100644
index 2c2c32a..0000000
--- a/src/health-watch.lua
+++ /dev/null
@@ -1,107 +0,0 @@
---
--- rhctl
---
--- Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
---
--- This file is part of rhctl.
---
--- rhctl 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
--- any later version.
---
--- rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
---
-
-package.path = package.path .. ';/usr/share/rhctl/?.lua'
-
-socket = require("socket")
-utils = require("utils")
-
-old_state = {}
-current_state = {}
-
-function state_changed()
- for k,v in pairs(old_state) do
- if v ~= current_state[k] then
- return true
- end
- end
- for k,v in pairs(current_state) do
- if old_state[k] == nil then
- return true
- end
- end
- return false
-end
-
-function process_cmd(message)
- local exps = { hs = "^Health: (%a+)$", mc = "^Master: (%a+)$", sc = "^Standby: (%a+)$", hbm = "^Hearbeat Master: (%a+, %a+)$", hbs = "^Hearbeat Standby: (%a+, %a+)$" }
- for key, exp in pairs(exps) do
- local state = string.match(message, exp)
- if(state) then
- if(key == 'hs') then
- current_state = {}
- end
- current_state[key] = state
- end
- end
-
- if(current_state['hbs'] ~= nil) then
- if(state_changed()) then
- body = "RHCTL Health Output:\n\n"
- body = body .. "Health: " .. current_state['hs'] .. "\n"
- body = body .. "Master: " .. current_state['mc'] .. "\n"
- body = body .. "Standby: " .. current_state['sc'] .. "\n"
- body = body .. "Master Hearbeat: " .. current_state['hbm'] .. "\n"
- body = body .. "Standby Hearbeat: " .. current_state['hbs'] .. "\n"
- utils.send_mail("logs@helsinki.at", "[RHCTL] health: " .. current_state['hs'], body)
- old_state = current_state
- end
- end
-
- return 0
-end
-
-function main_loop(opt)
- log.printf(log.NOTICE, "main_loop started")
- local sig = signal.init()
- local cmdfd = cmd.init()
-
- cmd.send_string("listen health");
- cmd.send_string("health");
-
- local return_value = 0
- while return_value == 0 do
- local readable, _, err = socket.select({ sig , cmdfd }, nil)
- if(err) then
- log.printf(log.ERROR, "select returned with error: %s", err)
- return_value = -1
- else
- for _, input in ipairs(readable) do
- if(input == sig) then
- return_value = signal.handle()
- if(return_value == 1) then break end
- else
- if(input == cmdfd) then
- return_value = cmd.recv_data(process_cmd)
- if(return_value ~= 0) then break end
- else
- log.printf(log.ERROR, "select returned invalid handle??")
- return_value = -1
- break;
- end
- end
- end
- end
- end
-
- signal.stop()
- return return_value
-end
diff --git a/src/heartbeatclient.c b/src/heartbeatclient.c
deleted file mode 100644
index 975581f..0000000
--- a/src/heartbeatclient.c
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "datatypes.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include "log.h"
-#include "sig_handler.h"
-#include "options.h"
-
-#include "daemon.h"
-#include "utils.h"
-
-int process_serial(read_buffer_t* buffer, int serial_fd, int led_pipe_fd, bool *state)
-{
- int ret = 0;
- struct timeval tv;
- fd_set fds;
- FD_ZERO(&fds);
- FD_SET(serial_fd, &fds);
-
- for(;;) {
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- ret = select(serial_fd+1, &fds, NULL, NULL, &tv);
- if(!ret)
- return 0;
- else if(ret < 0)
- return ret;
-
- ret = read(serial_fd, &buffer->buf[buffer->offset], 1);
- if(!ret)
- return 2;
- if(ret == -1 && errno == EAGAIN)
- return 0;
- else if(ret < 0)
- break;
-
- if(buffer->buf[buffer->offset] == '\n') {
- buffer->buf[buffer->offset] = 0;
-
- if(buffer->offset > 0 && buffer->buf[buffer->offset-1] == '\r')
- buffer->buf[buffer->offset-1] = 0;
-
- if(strlen((char *)(buffer->buf))) {
- *state = TRUE;
- if(led_pipe_fd >= 0) {
- char buf = '1';
- ret = write(led_pipe_fd, &buf, 1);
- if(ret == -1 && errno != EAGAIN)
- log_printf(WARNING, "write to led process pipe returned with error: %s", strerror(errno));
- }
- }
-
- buffer->offset = 0;
- return 0;
- }
-
- buffer->offset++;
- if(buffer->offset >= sizeof(buffer->buf)) {
- log_printf(DEBUG, "string too long (fd=%d)", serial_fd);
- buffer->offset = 0;
- return 0;
- }
- }
-
- return ret;
-}
-
-int main_loop(int serial_fd, int cmd_fd, int led_pipe_fd, options_t* opt)
-{
- log_printf(NOTICE, "entering main loop");
-
- fd_set readfds, tmpfds;
- FD_ZERO(&readfds);
- FD_SET(serial_fd, &readfds);
- FD_SET(cmd_fd, &readfds);
- int max_fd = serial_fd > cmd_fd ? serial_fd : cmd_fd;
-
- int sig_fd = signal_init();
- if(sig_fd < 0)
- return -1;
- FD_SET(sig_fd, &readfds);
- max_fd = (max_fd < sig_fd) ? sig_fd : max_fd;
-
- int return_value = 0;
- return_value = send_string(cmd_fd, "type heartbeat\n");
- if(return_value <= 0) {
- log_printf(ERROR, "error setting client type");
- return_value = -1;
- }
- else {
- log_printf(NOTICE, "connecting as type heartbeat");
- return_value = 0;
- }
-
- bool state = FALSE;
- send_string(cmd_fd, "heartbeat 0\n");
-
- read_buffer_t serial_buffer;
- serial_buffer.offset = 0;
- struct timeval timeout;
- u_int32_t time = 0;
- while(!return_value) {
- memcpy(&tmpfds, &readfds, sizeof(tmpfds));
-
- timeout.tv_sec = 0;
- timeout.tv_usec = 100000;
- int ret = select(max_fd+1, &tmpfds, NULL, NULL, &timeout);
- if(ret == -1 && errno != EINTR) {
- log_printf(ERROR, "select returned with error: %s", strerror(errno));
- return_value = -1;
- break;
- }
- if(ret == -1)
- continue;
- if(!ret) {
- time++;
- if(time >= opt->timeout_) {
- if(state == TRUE) {
- log_printf(WARNING, "heartbeat timeout");
- send_string(cmd_fd, "heartbeat 0\n");
- state = FALSE;
- }
- time = 0;
- }
- continue;
- }
-
- if(FD_ISSET(sig_fd, &tmpfds))
- if(signal_handle())
- return_value = 1;
-
- if(FD_ISSET(serial_fd, &tmpfds)) {
- bool old_state = state;
- return_value = process_serial(&serial_buffer, serial_fd, led_pipe_fd, &state);
- if(return_value)
- break;
- if(state) {
- if(!old_state) {
- log_printf(WARNING, "heartbeat returned");
- send_string(cmd_fd, "heartbeat 1\n");
- }
- time = 0;
- }
- }
-
- if(FD_ISSET(cmd_fd, &tmpfds)) {
- u_int8_t buf[100];
- int ret = recv(cmd_fd, buf, 100, 0);
- if(!ret)
- return_value = 3;
- if(ret == -1 && errno == EAGAIN)
- return_value = 0;
- else if(ret < 0)
- return_value = ret;
- }
- }
-
- signal_stop();
- return return_value;
-}
-
-int led_process(int pipe_fd, int led_fd)
-{
- struct timeval timeout;
- char buf;
- int ret;
-
- log_printf(INFO, "led_process: starting up");
- for(;;) {
- ret = read(pipe_fd, &buf, 1);
- if(ret == -1 && errno == EAGAIN)
- continue;
- else if(!ret || ret < 0) {
- log_printf(ERROR, "led_process: read returned with error: %s", strerror(errno));
- break;
- }
-
- buf = '1';
- ret = write(led_fd, &buf, 1);
- if(ret == -1 && errno != EAGAIN) {
- log_printf(ERROR, "led_process: write returned with error: %s", strerror(errno));
- break;
- }
-
- timeout.tv_sec = 0;
- timeout.tv_usec = 100000;
- ret = select(0, NULL, NULL, NULL, &timeout);
- if(ret == -1 && errno != EINTR) {
- log_printf(ERROR, "led_process: select returned with error: %s", strerror(errno));
- break;
- }
-
- buf = '0';
- ret = write(led_fd, &buf, 1);
- if(ret == -1 && errno != EAGAIN) {
- log_printf(ERROR, "led_process: write returned with error: %s", strerror(errno));
- break;
- }
- }
- log_printf(INFO, "led_process: stopped");
- return -1;
-}
-
-int start_led_process(options_t* opt)
-{
- int pipefd[2];
- int led_fd;
- pid_t cpid;
-
- led_fd = open(opt->led_filename_, O_WRONLY);
- if(led_fd < 0) {
- log_printf(ERROR, "led_process: open() failed: %s", strerror(errno));
- return -2;
- }
-
- if (pipe(pipefd) == -1) {
- log_printf(ERROR, "led_process: pipe() failed: %s", strerror(errno));
- close(led_fd);
- return -2;
- }
-
- cpid = fork();
- if (cpid == -1) {
- log_printf(ERROR, "led_process: fork() failed: %s", strerror(errno));
- close(pipefd[0]);
- close(pipefd[1]);
- close(led_fd);
- return -2;
- }
-
- if (cpid == 0) {
- close(pipefd[1]);
- return led_process(pipefd[0], led_fd);
- }
-
- close(pipefd[0]);
- close(led_fd);
- return pipefd[1];
-}
-
-int main(int argc, char* argv[])
-{
- log_init();
-
- options_t opt;
- int ret = options_parse(&opt, argc, argv);
- if(ret) {
- if(ret > 0) {
- fprintf(stderr, "syntax error near: %s\n\n", argv[ret]);
- }
- if(ret == -2) {
- fprintf(stderr, "memory error on options_parse, exiting\n");
- }
- if(ret == -5) {
- fprintf(stderr, "syntax error: invalid baudrate\n");
- }
-
- if(ret != -2)
- options_print_usage();
-
- options_clear(&opt);
- log_close();
- exit(ret);
- }
- string_list_element_t* tmp = opt.log_targets_.first_;
- if(!tmp) {
- log_add_target("syslog:3,heartbeatclient,daemon");
- }
- else {
- while(tmp) {
- ret = log_add_target(tmp->string_);
- if(ret) {
- switch(ret) {
- case -2: fprintf(stderr, "memory error on log_add_target, exitting\n"); break;
- case -3: fprintf(stderr, "unknown log target: '%s', exitting\n", tmp->string_); break;
- case -4: fprintf(stderr, "this log target is only allowed once: '%s', exitting\n", tmp->string_); break;
- default: fprintf(stderr, "syntax error near: '%s', exitting\n", tmp->string_); break;
- }
-
- options_clear(&opt);
- log_close();
- exit(ret);
- }
- tmp = tmp->next_;
- }
- }
- log_printf(NOTICE, "just started...");
- if(options_parse_post(&opt)) {
- options_clear(&opt);
- log_close();
- exit(-1);
- }
-
- priv_info_t priv;
- if(opt.username_)
- if(priv_init(&priv, opt.username_, opt.groupname_)) {
- options_clear(&opt);
- log_close();
- exit(-1);
- }
-
- FILE* pid_file = NULL;
- if(opt.pid_file_) {
- pid_file = fopen(opt.pid_file_, "w");
- if(!pid_file) {
- log_printf(WARNING, "unable to open pid file: %s", strerror(errno));
- }
- }
-
- if(opt.chroot_dir_)
- if(do_chroot(opt.chroot_dir_)) {
- options_clear(&opt);
- log_close();
- exit(-1);
- }
- if(opt.username_)
- if(priv_drop(&priv)) {
- options_clear(&opt);
- log_close();
- exit(-1);
- }
-
- if(opt.daemonize_) {
- pid_t oldpid = getpid();
- daemonize();
- log_printf(INFO, "running in background now (old pid: %d)", oldpid);
- }
-
- if(pid_file) {
- pid_t pid = getpid();
- fprintf(pid_file, "%d", pid);
- fclose(pid_file);
- }
-
- int led_pipe_fd = -1;
- if(opt.led_filename_) {
- log_printf(NOTICE, "starting led blink process");
- led_pipe_fd = start_led_process(&opt);
- if(led_pipe_fd == -1) {
- options_clear(&opt);
- log_close();
- exit(0);
- }
- if(led_pipe_fd < -1) {
- options_clear(&opt);
- log_close();
- exit(-1);
- }
- }
-
- int cmd_fd = 0;
- int serial_fd = 0;
- for(;;) {
- cmd_fd = connect_command_socket(opt.command_sock_);
- if(cmd_fd < 0)
- ret = 3;
- else {
- serial_fd = open(opt.serial_dev_, O_RDWR | O_NOCTTY);
- if(serial_fd < 0) {
- log_printf(ERROR, "open(%s): %s", opt.serial_dev_, strerror(errno));
- ret = 2;
- }
- else {
- ret = setup_tty(serial_fd, opt.baudrate_);
- if(ret)
- ret = 2;
- else
- ret = main_loop(serial_fd, cmd_fd, led_pipe_fd, &opt);
- }
- }
-
- if(ret == 2 || ret == 3) {
- if(ret == 2)
- log_printf(ERROR, "%s error, trying to reopen in 5 seconds..", opt.serial_dev_);
- if(ret == 3)
- log_printf(ERROR, "socket error, trying to reconnect in 5 seconds..");
-
- if(cmd_fd > 0)
- close(cmd_fd);
- if(serial_fd > 0)
- close(serial_fd);
- sleep(5);
- }
- else
- break;
- }
-
- if(cmd_fd > 0)
- close(cmd_fd);
- if(serial_fd > 0)
- close(serial_fd);
-
- if(!ret)
- log_printf(NOTICE, "normal shutdown");
- else if(ret < 0)
- log_printf(NOTICE, "shutdown after error (code %d)", ret);
- else
- log_printf(NOTICE, "shutdown after signal");
-
- options_clear(&opt);
- log_close();
-
- return ret;
-}
diff --git a/src/key_value_storage.c b/src/key_value_storage.c
deleted file mode 100644
index 31f48d9..0000000
--- a/src/key_value_storage.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "key_value_storage.h"
-
-void key_value_storage_init(key_value_storage_t* stor)
-{
- if(!stor)
- return;
-
- string_list_init(&(stor->keys_));
- string_list_init(&(stor->values_));
-}
-
-void key_value_storage_clear(key_value_storage_t* stor)
-{
- if(!stor)
- return;
-
- string_list_clear(&(stor->keys_));
- string_list_clear(&(stor->values_));
-}
-
-int key_value_storage_add(key_value_storage_t* stor, const char* key, const char* value)
-{
- if(!stor || !key || !value)
- return -1;
-
- int ret = string_list_add(&(stor->keys_), key);
- if(ret!=0)
- return ret;
-
- ret = string_list_add(&(stor->values_), value);
- if(ret!=0)
- return ret;
-
- return 0;
-}
-
-char* key_value_storage_find(key_value_storage_t* stor, const char* key)
-{
- if(!stor || !key)
- return NULL;
-
- string_list_element_t* k = stor->keys_.first_;
- string_list_element_t* v = stor->values_.first_;
- while(v && k) {
- if(!strcmp(k->string_, key))
- return v->string_;
-
- k = k->next_;
- v = v->next_;
- }
-
- return NULL;
-}
-
-void key_value_storage_print(key_value_storage_t* stor, const char* head, const char* sep, const char* tail)
-{
- if(!stor)
- return;
-
- string_list_element_t* k = stor->keys_.first_;
- string_list_element_t* v = stor->values_.first_;
- while(v && k) {
- printf("%s%s%s%s%s", head, k->string_, sep, v->string_, tail);
- k = k->next_;
- v = v->next_;
- }
- printf("\n");
-}
diff --git a/src/key_value_storage.h b/src/key_value_storage.h
deleted file mode 100644
index 1a58a60..0000000
--- a/src/key_value_storage.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef RHCTL_key_value_storage_h_INCLUDED
-#define RHCTL_key_value_storage_h_INCLUDED
-
-#include "string_list.h"
-
-struct key_value_storage_struct {
- string_list_t keys_;
- string_list_t values_;
-};
-typedef struct key_value_storage_struct key_value_storage_t;
-
-void key_value_storage_init(key_value_storage_t* stor);
-void key_value_storage_clear(key_value_storage_t* stor);
-int key_value_storage_add(key_value_storage_t* stor, const char* key, const char* value);
-char* key_value_storage_find(key_value_storage_t* stor, const char* key);
-
-void key_value_storage_print(key_value_storage_t* stor, const char* head, const char* sep, const char* tail);
-
-
-#endif
diff --git a/src/l_cmd.c b/src/l_cmd.c
deleted file mode 100644
index 374535e..0000000
--- a/src/l_cmd.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <lua.h>
-#include <lauxlib.h>
-
-#include <unistd.h>
-#include <sys/socket.h>
-#include <errno.h>
-
-#include "datatypes.h"
-
-#include "l_cmd.h"
-
-#include "options.h"
-#include "command_queue.h"
-#include "client_list.h"
-#include "log.h"
-#include "utils.h"
-
-int cmd_fd;
-read_buffer_t cmd_buffer;
-
-static int l_cmd_getfd(lua_State *L)
-{
- if(!lua_istable(L, -1))
- luaL_error(L, "can't retreive signal fd");
-
- lua_pushliteral(L, "fd");
- lua_gettable(L, -2);
- return 1;
-}
-
-static int l_cmd_dirty(lua_State *L)
-{
- lua_pushboolean(L, 0);
- return 1;
-}
-
-static int l_cmd_init(lua_State *L)
-{
- lua_newtable(L);
- lua_pushliteral(L, "fd");
- lua_pushinteger(L, cmd_fd);
- lua_settable(L, -3);
- lua_pushliteral(L, "getfd");
- lua_pushcfunction(L, l_cmd_getfd);
- lua_settable(L, -3);
- lua_pushliteral(L, "dirty");
- lua_pushcfunction(L, l_cmd_dirty);
- lua_settable(L, -3);
- return 1;
-}
-
-// gets called by nonblock_recvline for every complete message
-static int cmd_recv_data(lua_State* L)
-{
- int ret = 0;
- for(;;) {
- ret = recv(cmd_fd, &cmd_buffer.buf[cmd_buffer.offset], 1, 0);
- if(!ret)
- return 2;
- if(ret == -1 && errno == EAGAIN)
- return 0;
- else if(ret < 0)
- break;
-
- if(cmd_buffer.buf[cmd_buffer.offset] == '\n') {
- cmd_buffer.buf[cmd_buffer.offset] = 0;
-
- lua_pushstring(L, (char *)(cmd_buffer.buf));
-
- ret = lua_pcall(L, 1, 1, 0);
- if(ret) {
- const char* err_str = luaL_checkstring(L, -1);
- switch(ret) {
- case LUA_ERRRUN: log_printf(ERROR, "lua_pcall(cmd_callback) runtime error: %s", err_str); break;
- case LUA_ERRMEM: log_printf(ERROR, "lua_pcall(cmd_callback) malloc error: %s", err_str); break;
- case LUA_ERRERR: log_printf(ERROR, "lua_pcall(cmd_callback) error at error handler function: %s", err_str); break;
- }
- return -1;
- }
-
- ret = lua_tointeger(L, 1);
- cmd_buffer.offset = 0;
- break;
- }
-
- cmd_buffer.offset++;
- if(cmd_buffer.offset >= sizeof(cmd_buffer.buf)) {
- log_printf(DEBUG, "string too long cmd_fd");
- cmd_buffer.offset = 0;
- return 0;
- }
- }
-
- return ret;
-}
-
-static int l_cmd_recv_data(lua_State* L)
-{
- int ret = cmd_recv_data(L);
- lua_pushinteger(L, ret);
- return 1;
-}
-
-static int l_cmd_send_string(lua_State* L)
-{
- int ret = send_string(cmd_fd, luaL_checkstring(L,1));
- if (ret > 0)
- do {
- ret = write(cmd_fd, "\n", 1);
- } while(!ret || (ret == -1 && errno == EINTR));
-
- if(ret > 0)
- ret = 0;
-
- lua_pushinteger(L, ret);
- return 1;
-}
-
-static const struct luaL_Reg cmd_funcs [] = {
- { "init", l_cmd_init },
- { "recv_data", l_cmd_recv_data },
- { "send_string", l_cmd_send_string },
- { NULL, NULL }
-};
-
-LUALIB_API int luaopen_cmd(lua_State *L)
-{
-#if LUA_VERSION_NUM > 501
- lua_newtable(L);
- luaL_setfuncs(L, cmd_funcs, 0);
- lua_pushvalue(L, -1);
- lua_setglobal(L, LUA_CMDLIBNAME);
-#else
- luaL_register(L, LUA_CMDLIBNAME, cmd_funcs);
-#endif
- return 1;
-}
diff --git a/src/l_cmd.h b/src/l_cmd.h
deleted file mode 100644
index a23f79a..0000000
--- a/src/l_cmd.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef RHCTL_l_cmd_h_INCLUDED
-#define RHCTL_l_cmd_h_INCLUDED
-
-#include <lua.h>
-
-extern int cmd_fd;
-
-#define LUA_CMDLIBNAME "cmd"
-LUALIB_API int luaopen_cmd(lua_State *L);
-
-#endif
diff --git a/src/l_log.c b/src/l_log.c
deleted file mode 100644
index 05111c3..0000000
--- a/src/l_log.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <lua.h>
-#include <lauxlib.h>
-
-#include <stdlib.h>
-
-#include "datatypes.h"
-#include "log.h"
-
-#include "l_log.h"
-
-static int l_log_init(lua_State *L)
-{
- log_init();
- return 0;
-}
-
-static int l_log_close(lua_State *L)
-{
- log_close();
- return 0;
-}
-
-static int l_log_add_target(lua_State *L)
-{
- int ret = log_add_target(luaL_checkstring(L,1));
- if(ret) {
- lua_pushboolean(L, 0);
- switch(ret) {
- case -2: lua_pushstring(L, "memory error at log_add_target"); break;
- case -3: lua_pushstring(L, "unknown log target"); break;
- case -4: lua_pushstring(L, "this log target is only allowed once"); break;
- default: lua_pushstring(L, "syntax error"); break;
- }
- return 2;
- }
-
- lua_pushboolean(L, 1);
- return 1;
-}
-
-static int l_log_printf(lua_State *L)
-{
- int numargs = lua_gettop(L);
- if(numargs < 2)
- return luaL_error(L, "log.printf too few arguments");
-
- if(numargs > 2) {
- lua_getglobal(L, "string");
- lua_pushliteral(L, "format");
- lua_gettable(L, -2);
- lua_insert(L, 2);
- lua_remove(L, -1);
- lua_call(L, numargs - 1, 1);
- }
-
- log_prio_t prio = luaL_checkinteger(L,1);
- log_printf(prio, "%s", luaL_checkstring(L, 2));
- return 0;
-}
-
-static const struct luaL_Reg log_funcs [] = {
- { "init", l_log_init },
- { "close", l_log_close },
- { "add_target", l_log_add_target },
- { "printf", l_log_printf },
- { NULL, NULL }
-};
-
-
-LUALIB_API int luaopen_log(lua_State *L)
-{
-#if LUA_VERSION_NUM > 501
- lua_newtable(L);
- luaL_setfuncs(L, log_funcs, 0);
- lua_pushvalue(L, -1);
- lua_setglobal(L, LUA_LOGLIBNAME);
-#else
- luaL_register(L, LUA_LOGLIBNAME, log_funcs);
-#endif
- lua_pushliteral(L, "ERROR");
- lua_pushinteger(L, ERROR);
- lua_settable(L, -3);
- lua_pushliteral(L, "WARNING");
- lua_pushinteger(L, WARNING);
- lua_settable(L, -3);
- lua_pushliteral(L, "NOTICE");
- lua_pushinteger(L, NOTICE);
- lua_settable(L, -3);
- lua_pushliteral(L, "INFO");
- lua_pushinteger(L, INFO);
- lua_settable(L, -3);
- lua_pushliteral(L, "DEBUG");
- lua_pushinteger(L, DEBUG);
- lua_settable(L, -3);
- return 1;
-}
diff --git a/src/l_log.h b/src/l_log.h
deleted file mode 100644
index 169b591..0000000
--- a/src/l_log.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef RHCTL_l_log_h_INCLUDED
-#define RHCTL_l_log_h_INCLUDED
-
-#include <lua.h>
-
-#define LUA_LOGLIBNAME "log"
-LUALIB_API int luaopen_log(lua_State *L);
-
-#endif
diff --git a/src/l_sig_handler.c b/src/l_sig_handler.c
deleted file mode 100644
index f0616b8..0000000
--- a/src/l_sig_handler.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <lua.h>
-#include <lauxlib.h>
-
-#include "sig_handler.h"
-
-#include "l_sig_handler.h"
-
-static int l_signal_getfd(lua_State *L)
-{
- if(!lua_istable(L, -1))
- luaL_error(L, "can't retreive signal fd");
-
- lua_pushliteral(L, "fd");
- lua_gettable(L, -2);
- return 1;
-}
-
-static int l_signal_dirty(lua_State *L)
-{
- lua_pushboolean(L, 0);
- return 1;
-}
-
-static int l_signal_init(lua_State *L)
-{
- int sig_fd = signal_init();
- if(sig_fd < 0)
- luaL_error(L, "error at signal init");
-
- lua_newtable(L);
- lua_pushliteral(L, "fd");
- lua_pushinteger(L, sig_fd);
- lua_settable(L, -3);
- lua_pushliteral(L, "getfd");
- lua_pushcfunction(L, l_signal_getfd);
- lua_settable(L, -3);
- lua_pushliteral(L, "dirty");
- lua_pushcfunction(L, l_signal_dirty);
- lua_settable(L, -3);
- return 1;
-}
-
-static int l_signal_stop(lua_State *L)
-{
- signal_stop();
- return 0;
-}
-
-static int l_signal_handle(lua_State *L)
-{
- int ret = signal_handle();
- lua_pushinteger(L, ret);
- return 1;
-}
-
-static const struct luaL_Reg signal_funcs [] = {
- { "init", l_signal_init },
- { "stop", l_signal_stop },
- { "handle", l_signal_handle },
- { NULL, NULL }
-};
-
-
-LUALIB_API int luaopen_signal(lua_State *L)
-{
-#if LUA_VERSION_NUM > 501
- lua_newtable(L);
- luaL_setfuncs(L, signal_funcs, 0);
- lua_pushvalue(L, -1);
- lua_setglobal(L, LUA_SIGNALLIBNAME);
-#else
- luaL_register(L, LUA_SIGNALLIBNAME, signal_funcs);
-#endif
- return 1;
-}
diff --git a/src/l_sig_handler.h b/src/l_sig_handler.h
deleted file mode 100644
index 310414a..0000000
--- a/src/l_sig_handler.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef RHCTL_l_signal_handler_h_INCLUDED
-#define RHCTL_l_signal_handler_h_INCLUDED
-
-#include <lua.h>
-
-#define LUA_SIGNALLIBNAME "signal"
-LUALIB_API int luaopen_signal(lua_State *L);
-
-#endif
diff --git a/src/log.c b/src/log.c
deleted file mode 100644
index 721d7c0..0000000
--- a/src/log.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "datatypes.h"
-
-#include <ctype.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#define SYSLOG_NAMES
-#include <syslog.h>
-
-#include "log.h"
-
-log_t stdlog;
-
-#include "log_targets.h"
-
-const char* log_prio_to_string(log_prio_t prio)
-{
- switch(prio) {
- case ERROR: return "ERROR";
- case WARNING: return "WARNING";
- case NOTICE: return "NOTICE";
- case INFO: return "INFO";
- case DEBUG: return "DEBUG";
- }
- return "UNKNOWN";
-}
-
-log_target_type_t log_target_parse_type(const char* conf)
-{
- if(!conf)
- return TARGET_UNKNOWN;
-
- if(!strncmp(conf, "syslog", 6)) return TARGET_SYSLOG;
- if(!strncmp(conf, "file", 4)) return TARGET_FILE;
- if(!strncmp(conf, "stdout", 6)) return TARGET_STDOUT;
- if(!strncmp(conf, "stderr", 6)) return TARGET_STDERR;
-
- return TARGET_UNKNOWN;
-}
-
-int log_targets_target_exists(log_targets_t* targets, log_target_type_t type)
-{
- if(!targets && !targets->first_)
- return 0;
-
- log_target_t* tmp = targets->first_;
- while(tmp) {
- if(tmp->type_ == type)
- return 1;
- tmp = tmp->next_;
- }
- return 0;
-}
-
-int log_targets_add(log_targets_t* targets, const char* conf)
-{
- if(!targets)
- return -1;
-
- log_target_t* new_target = NULL;
- int duplicates_allowed = 0;
- switch(log_target_parse_type(conf)) {
- case TARGET_SYSLOG: new_target = log_target_syslog_new(); break;
- case TARGET_FILE: new_target = log_target_file_new(); duplicates_allowed = 1; break;
- case TARGET_STDOUT: new_target = log_target_stdout_new(); break;
- case TARGET_STDERR: new_target = log_target_stderr_new(); break;
- default: return -3;
- }
- if(!new_target)
- return -2;
-
- if(!duplicates_allowed && log_targets_target_exists(targets, new_target->type_)) {
- free(new_target);
- return -4;
- }
-
- const char* prioptr = strchr(conf, ':');
- if(!prioptr || prioptr[1] == 0) {
- free(new_target);
- return -1;
- }
- prioptr++;
- if(!isdigit(prioptr[0]) || (prioptr[1] != 0 && prioptr[1] != ',')) {
- free(new_target);
- return -1;
- }
- new_target->max_prio_ = prioptr[0] - '0';
- if(new_target->max_prio_ > 0)
- new_target->enabled_ = 1;
-
- if(new_target->init != NULL) {
- const char* confptr = NULL;
- if(prioptr[1] != 0)
- confptr = prioptr+2;
-
- int ret = (*new_target->init)(new_target, confptr);
- if(ret) {
- free(new_target);
- return ret;
- }
- }
-
- if(new_target->open != NULL)
- (*new_target->open)(new_target);
-
-
- if(!targets->first_) {
- targets->first_ = new_target;
- }
- else {
- log_target_t* tmp = targets->first_;
- while(tmp->next_)
- tmp = tmp->next_;
-
- tmp->next_ = new_target;
- }
- return 0;
-}
-
-void log_targets_log(log_targets_t* targets, log_prio_t prio, const char* msg)
-{
- if(!targets)
- return;
-
- log_target_t* tmp = targets->first_;
- while(tmp) {
- if(tmp->log != NULL && tmp->enabled_ && tmp->max_prio_ >= prio)
- (*tmp->log)(tmp, prio, msg);
-
- tmp = tmp->next_;
- }
-}
-
-void log_targets_clear(log_targets_t* targets)
-{
- if(!targets)
- return;
-
- while(targets->first_) {
- log_target_t* tmp = targets->first_;
- targets->first_ = tmp->next_;
- if(tmp->close != NULL)
- (*tmp->close)(tmp);
- if(tmp->clear != NULL)
- (*tmp->clear)(tmp);
- free(tmp);
- }
-}
-
-
-void log_init()
-{
- stdlog.max_prio_ = 0;
- stdlog.targets_.first_ = NULL;
-}
-
-void log_close()
-{
- log_targets_clear(&stdlog.targets_);
-}
-
-void update_max_prio()
-{
- log_target_t* tmp = stdlog.targets_.first_;
- while(tmp) {
- if(tmp->enabled_ && tmp->max_prio_ > stdlog.max_prio_)
- stdlog.max_prio_ = tmp->max_prio_;
-
- tmp = tmp->next_;
- }
-}
-
-int log_add_target(const char* conf)
-{
- if(!conf)
- return -1;
-
- int ret = log_targets_add(&stdlog.targets_, conf);
- if(!ret) update_max_prio();
- return ret;
-}
-
-void log_printf(log_prio_t prio, const char* fmt, ...)
-{
- if(stdlog.max_prio_ < prio)
- return;
-
- static char msg[MSG_LENGTH_MAX];
- va_list args;
-
- va_start(args, fmt);
- vsnprintf(msg, MSG_LENGTH_MAX, fmt, args);
- va_end(args);
-
- log_targets_log(&stdlog.targets_, prio, msg);
-}
-
-void log_print_hex_dump(log_prio_t prio, const u_int8_t* buf, u_int32_t len)
-{
- if(stdlog.max_prio_ < prio)
- return;
-
- static char msg[MSG_LENGTH_MAX];
-
- if(!buf) {
- snprintf(msg, MSG_LENGTH_MAX, "(NULL)");
- }
- else {
- u_int32_t i;
- int offset = snprintf(msg, MSG_LENGTH_MAX, "dump(%d): ", len);
- if(offset < 0)
- return;
- char* ptr = &msg[offset];
-
- for(i=0; i < len; i++) {
- if(((i+1)*3) >= (MSG_LENGTH_MAX - offset))
- break;
- snprintf(ptr, 3, "%02X ", buf[i]);
- ptr+=3;
- }
- }
- log_targets_log(&stdlog.targets_, prio, msg);
-}
diff --git a/src/log.h b/src/log.h
deleted file mode 100644
index 872e1ee..0000000
--- a/src/log.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef RHCTL_log_h_INCLUDED
-#define RHCTL_log_h_INCLUDED
-
-#define MSG_LENGTH_MAX 150
-
-enum log_prio_enum { ERROR = 1, WARNING = 2, NOTICE = 3,
- INFO = 4, DEBUG = 5 };
-typedef enum log_prio_enum log_prio_t;
-
-const char* log_prio_to_string(log_prio_t prio);
-
-enum log_target_type_enum { TARGET_SYSLOG , TARGET_STDOUT, TARGET_STDERR, TARGET_FILE , TARGET_UNKNOWN };
-typedef enum log_target_type_enum log_target_type_t;
-
-struct log_target_struct {
- log_target_type_t type_;
- int (*init)(struct log_target_struct* self, const char* conf);
- void (*open)(struct log_target_struct* self);
- void (*log)(struct log_target_struct* self, log_prio_t prio, const char* msg);
- void (*close)(struct log_target_struct* self);
- void (*clear)(struct log_target_struct* self);
- int opened_;
- int enabled_;
- log_prio_t max_prio_;
- void* param_;
- struct log_target_struct* next_;
-};
-typedef struct log_target_struct log_target_t;
-
-
-struct log_targets_struct {
- log_target_t* first_;
-};
-typedef struct log_targets_struct log_targets_t;
-
-int log_targets_target_exists(log_targets_t* targets, log_target_type_t type);
-int log_targets_add(log_targets_t* targets, const char* conf);
-void log_targets_log(log_targets_t* targets, log_prio_t prio, const char* msg);
-void log_targets_clear(log_targets_t* targets);
-
-
-struct log_struct {
- log_prio_t max_prio_;
- log_targets_t targets_;
-};
-typedef struct log_struct log_t;
-
-void log_init();
-void log_close();
-void update_max_prio();
-int log_add_target(const char* conf);
-void log_printf(log_prio_t prio, const char* fmt, ...);
-void log_print_hex_dump(log_prio_t prio, const u_int8_t* buf, u_int32_t len);
-
-#endif
diff --git a/src/log_targets.h b/src/log_targets.h
deleted file mode 100644
index d0a85b1..0000000
--- a/src/log_targets.h
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef RHCTL_log_targets_h_INCLUDED
-#define RHCTL_log_targets_h_INCLUDED
-
-#include <time.h>
-
-static char* get_time_formatted()
-{
- char* time_string;
- time_t t = time(NULL);
- if(t < 0)
- time_string = "<time read error>";
- else {
- time_string = ctime(&t);
- if(!time_string)
- time_string = "<time format error>";
- else {
- char* newline = strchr(time_string, '\n');
- if(newline)
- newline[0] = 0;
- }
- }
- return time_string;
-}
-
-enum syslog_facility_enum { USER = LOG_USER, MAIL = LOG_MAIL,
- DAEMON = LOG_DAEMON, AUTH = LOG_AUTH,
- SYSLOG = LOG_SYSLOG, LPR = LOG_LPR,
- NEWS = LOG_NEWS, UUCP = LOG_UUCP,
- CRON = LOG_CRON, AUTHPRIV = LOG_AUTHPRIV,
- FTP = LOG_FTP, LOCAL0 = LOG_LOCAL0,
- LOCAL1 = LOG_LOCAL1, LOCAL2 = LOG_LOCAL2,
- LOCAL3 = LOG_LOCAL3, LOCAL4 = LOG_LOCAL4,
- LOCAL5 = LOG_LOCAL5, LOCAL6 = LOG_LOCAL6,
- LOCAL7 = LOG_LOCAL7 };
-typedef enum syslog_facility_enum syslog_facility_t;
-
-struct log_target_syslog_param_struct {
- char* logname_;
- syslog_facility_t facility_;
-};
-typedef struct log_target_syslog_param_struct log_target_syslog_param_t;
-
-int log_target_syslog_init(log_target_t* self, const char* conf)
-{
- if(!self || (conf && conf[0] == 0))
- return -1;
-
- self->param_ = malloc(sizeof(log_target_syslog_param_t));
- if(!self->param_)
- return -2;
-
- char* logname;
- const char* end = NULL;
- if(!conf)
- logname = strdup("uanytun");
- else {
- end = strchr(conf, ',');
- if(end) {
- size_t len = (size_t)(end - conf);
- if(!len) {
- free(self->param_);
- return -1;
- }
- logname = malloc(len+1);
- if(logname) {
- strncpy(logname, conf, len);
- logname[len] = 0;
- }
- }
- else
- logname = strdup(conf);
- }
-
- if(!logname) {
- free(self->param_);
- return -2;
- }
- ((log_target_syslog_param_t*)(self->param_))->logname_ = logname;
-
- if(!end) {
- ((log_target_syslog_param_t*)(self->param_))->facility_ = DAEMON;
- return 0;
- }
-
- if(end[1] == 0 || end[1] == ',') {
- free(logname);
- free(self->param_);
- return -1;
- }
-
- const char* start = end + 1;
- end = strchr(start, ',');
- int i;
- for(i=0;;++i) {
- if(facilitynames[i].c_name == NULL) {
- free(logname);
- free(self->param_);
- return -1;
- }
-
- if(( end && !strncmp(start, facilitynames[i].c_name, (size_t)(end - start)) && facilitynames[i].c_name[(size_t)(end-start)] == 0) ||
- (!end && !strcmp(start, facilitynames[i].c_name))) {
- ((log_target_syslog_param_t*)(self->param_))->facility_ = facilitynames[i].c_val;
- break;
- }
- }
-
- return 0;
-}
-
-void log_target_syslog_open(log_target_t* self)
-{
- if(!self || !self->param_)
- return;
-
- openlog(((log_target_syslog_param_t*)(self->param_))->logname_, LOG_PID, ((log_target_syslog_param_t*)(self->param_))->facility_);
- self->opened_ = 1;
-}
-
-void log_target_syslog_log(log_target_t* self, log_prio_t prio, const char* msg)
-{
- if(!self || !self->param_ || !self->opened_)
- return;
-
- syslog((prio + 2) | ((log_target_syslog_param_t*)(self->param_))->facility_, "%s", msg);
-}
-
-void log_target_syslog_close(log_target_t* self)
-{
- closelog();
- self->opened_ = 0;
-}
-
-void log_target_syslog_clear(log_target_t* self)
-{
- if(!self || !self->param_)
- return;
-
- if(((log_target_syslog_param_t*)(self->param_))->logname_)
- free(((log_target_syslog_param_t*)(self->param_))->logname_);
-
- free(self->param_);
-}
-
-log_target_t* log_target_syslog_new()
-{
- log_target_t* tmp = malloc(sizeof(log_target_t));
- if(!tmp)
- return NULL;
-
- tmp->type_ = TARGET_SYSLOG;
- tmp->init = &log_target_syslog_init;
- tmp->open = &log_target_syslog_open;
- tmp->log = &log_target_syslog_log;
- tmp->close = &log_target_syslog_close;
- tmp->clear = &log_target_syslog_clear;
- tmp->opened_ = 0;
- tmp->enabled_ = 0;
- tmp->max_prio_ = NOTICE;
- tmp->param_ = NULL;
- tmp->next_ = NULL;
-
- return tmp;
-}
-
-
-struct log_target_file_param_struct {
- char* logfilename_;
- FILE* file_;
-};
-typedef struct log_target_file_param_struct log_target_file_param_t;
-
-int log_target_file_init(log_target_t* self, const char* conf)
-{
- if(!self || (conf && conf[0] == 0))
- return -1;
-
- self->param_ = malloc(sizeof(log_target_file_param_t));
- if(!self->param_)
- return -2;
-
- char* logfilename;
- if(!conf)
- logfilename = strdup("uanytun.log");
- else {
- const char* end = strchr(conf, ',');
- if(end) {
- size_t len = (size_t)(end - conf);
- if(!len) {
- free(self->param_);
- return -1;
- }
- logfilename = malloc(len+1);
- if(logfilename) {
- strncpy(logfilename, conf, len);
- logfilename[len] = 0;
- }
- }
- else
- logfilename = strdup(conf);
- }
-
- if(!logfilename) {
- free(self->param_);
- return -2;
- }
- ((log_target_file_param_t*)(self->param_))->logfilename_ = logfilename;
- ((log_target_file_param_t*)(self->param_))->file_ = NULL;
-
- return 0;
-}
-
-void log_target_file_open(log_target_t* self)
-{
- if(!self || !self->param_)
- return;
-
- ((log_target_file_param_t*)(self->param_))->file_ = fopen(((log_target_file_param_t*)(self->param_))->logfilename_, "w");
- if(((log_target_file_param_t*)(self->param_))->file_)
- self->opened_ = 1;
-}
-
-void log_target_file_log(log_target_t* self, log_prio_t prio, const char* msg)
-{
- if(!self || !self->param_ || !self->opened_)
- return;
-
- fprintf(((log_target_file_param_t*)(self->param_))->file_, "%s %s: %s\n", get_time_formatted(), log_prio_to_string(prio), msg);
- fflush(((log_target_file_param_t*)(self->param_))->file_);
-}
-
-void log_target_file_close(log_target_t* self)
-{
- if(!self || !self->param_)
- return;
-
- fclose(((log_target_file_param_t*)(self->param_))->file_);
- self->opened_ = 0;
-}
-
-void log_target_file_clear(log_target_t* self)
-{
- if(!self || !self->param_)
- return;
-
- if(((log_target_file_param_t*)(self->param_))->logfilename_)
- free(((log_target_file_param_t*)(self->param_))->logfilename_);
-
- free(self->param_);
-}
-
-
-log_target_t* log_target_file_new()
-{
- log_target_t* tmp = malloc(sizeof(log_target_t));
- if(!tmp)
- return NULL;
-
- tmp->type_ = TARGET_FILE;
- tmp->init = &log_target_file_init;
- tmp->open = &log_target_file_open;
- tmp->log = &log_target_file_log;
- tmp->close = &log_target_file_close;
- tmp->clear = &log_target_file_clear;
- tmp->opened_ = 0;
- tmp->enabled_ = 0;
- tmp->max_prio_ = NOTICE;
- tmp->param_ = NULL;
- tmp->next_ = NULL;
-
- return tmp;
-}
-
-
-void log_target_stdout_log(log_target_t* self, log_prio_t prio, const char* msg)
-{
- printf("%s %s: %s\n", get_time_formatted(), log_prio_to_string(prio), msg);
-}
-
-log_target_t* log_target_stdout_new()
-{
- log_target_t* tmp = malloc(sizeof(log_target_t));
- if(!tmp)
- return NULL;
-
- tmp->type_ = TARGET_STDOUT;
- tmp->init = NULL;
- tmp->open = NULL;
- tmp->log = &log_target_stdout_log;
- tmp->close = NULL;
- tmp->clear = NULL;
- tmp->opened_ = 0;
- tmp->enabled_ = 0;
- tmp->max_prio_ = NOTICE;
- tmp->param_ = NULL;
- tmp->next_ = NULL;
-
- return tmp;
-}
-
-
-void log_target_stderr_log(log_target_t* self, log_prio_t prio, const char* msg)
-{
- fprintf(stderr, "%s %s: %s\n", get_time_formatted(), log_prio_to_string(prio), msg);
-}
-
-log_target_t* log_target_stderr_new()
-{
- log_target_t* tmp = malloc(sizeof(log_target_t));
- if(!tmp)
- return NULL;
-
- tmp->type_ = TARGET_STDERR;
- tmp->init = NULL;
- tmp->open = NULL;
- tmp->log = &log_target_stderr_log;
- tmp->close = NULL;
- tmp->clear = NULL;
- tmp->opened_ = 0;
- tmp->enabled_ = 0;
- tmp->max_prio_ = NOTICE;
- tmp->param_ = NULL;
- tmp->next_ = NULL;
-
- return tmp;
-}
-
-#endif
diff --git a/src/luaclient.c b/src/luaclient.c
deleted file mode 100644
index 104de52..0000000
--- a/src/luaclient.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "datatypes.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <lua.h>
-#include <lualib.h>
-#include <lauxlib.h>
-
-#include "l_log.h"
-#include "l_sig_handler.h"
-#include "l_cmd.h"
-
-#include "log.h"
-#include "options.h"
-
-#include "daemon.h"
-#include "utils.h"
-
-
-#define LUA_MAIN_LOOP_FUNC "main_loop"
-
-#if LUA_VERSION_NUM > 501
-static const luaL_Reg luaclient_lualibs[] = {
- {"_G", luaopen_base},
- {LUA_LOADLIBNAME, luaopen_package},
- {LUA_TABLIBNAME, luaopen_table},
- {LUA_STRLIBNAME, luaopen_string},
- {LUA_MATHLIBNAME, luaopen_math},
- {LUA_IOLIBNAME, luaopen_io},
- {LUA_OSLIBNAME, luaopen_os},
- {LUA_BITLIBNAME, luaopen_bit32},
- {LUA_LOGLIBNAME, luaopen_log},
- {LUA_SIGNALLIBNAME, luaopen_signal},
- {LUA_CMDLIBNAME, luaopen_cmd},
- {NULL, NULL}
-};
-#else
-static const luaL_Reg luaclient_lualibs[] = {
- {"", luaopen_base},
- {LUA_LOADLIBNAME, luaopen_package},
- {LUA_TABLIBNAME, luaopen_table},
- {LUA_STRLIBNAME, luaopen_string},
- {LUA_MATHLIBNAME, luaopen_math},
- {LUA_IOLIBNAME, luaopen_io},
- {LUA_OSLIBNAME, luaopen_os},
- {LUA_LOGLIBNAME, luaopen_log},
- {LUA_SIGNALLIBNAME, luaopen_signal},
- {LUA_CMDLIBNAME, luaopen_cmd},
- {NULL, NULL}
-};
-#endif
-
-int init_main_loop(lua_State *L, const char* filename)
-{
- const luaL_Reg *lib = luaclient_lualibs;
-
-#if LUA_VERSION_NUM > 501
- for (; lib->func; lib++) {
- luaL_requiref(L, lib->name, lib->func, 1);
- lua_pop(L, 1);
- }
-#else
- for (; lib->func; lib++) {
- lua_pushcfunction(L, lib->func);
- lua_pushstring(L, lib->name);
- lua_call(L, 1, 0);
- }
-#endif
-
- int ret = luaL_loadfile(L, filename);
- if(ret) {
- const char* err_str = luaL_checkstring(L, -1);
- switch(ret) {
- case LUA_ERRSYNTAX: log_printf(ERROR, "luaL_loadfile(%s) syntax error: %s", filename, err_str); break;
- case LUA_ERRMEM: log_printf(ERROR, "luaL_loadfile(%s) malloc error: %s", filename, err_str); break;
- case LUA_ERRFILE: log_printf(ERROR, "luaL_loadfile(%s) file access error: %s", filename, err_str); break;
- default: log_printf(ERROR, "luaL_loadfile(%s) unknown error: %s", filename, err_str); break;
- }
- return -1;
- }
-
- ret = lua_pcall(L, 0, 0, 0);
- if(ret) {
- const char* err_str = luaL_checkstring(L, -1);
- switch(ret) {
- case LUA_ERRRUN: log_printf(ERROR, "lua_pcall() runtime error: %s", err_str); break;
- case LUA_ERRMEM: log_printf(ERROR, "lua_pcall() malloc error: %s", err_str); break;
- case LUA_ERRERR: log_printf(ERROR, "lua_pcall() error at error handler function: %s", err_str); break;
- }
- return -1;
- }
-
- return 0;
-}
-
-int call_main_loop(lua_State* L, int cmd_fd, options_t* opt)
-{
- lua_getglobal(L, LUA_MAIN_LOOP_FUNC);
- if(!lua_isfunction(L, -1)) {
- log_printf(ERROR, "there is no function '%s' inside the loaded file", LUA_MAIN_LOOP_FUNC);
- return -1;
- };
-
- options_lua_push(opt, L);
-
- int ret = lua_pcall(L, 1, LUA_MULTRET, 0);
- if(ret) {
- const char* err_str = luaL_checkstring(L, -1);
- switch(ret) {
- case LUA_ERRRUN: log_printf(ERROR, "lua_pcall(%s) runtime error: %s", LUA_MAIN_LOOP_FUNC, err_str); break;
- case LUA_ERRMEM: log_printf(ERROR, "lua_pcall(%s) malloc error: %s", LUA_MAIN_LOOP_FUNC, err_str); break;
- case LUA_ERRERR: log_printf(ERROR, "lua_pcall(%s) error at error handler function: %s", LUA_MAIN_LOOP_FUNC, err_str); break;
- }
- return -1;
- }
-
- int n = lua_gettop(L);
- log_printf(DEBUG, "%s returned %d values", LUA_MAIN_LOOP_FUNC, n);
- int i;
- for (i = 1; i <= n; i++)
- log_printf(DEBUG, "return value [%d] = '%s'", i, luaL_checkstring(L, i));
-
- ret = lua_tointeger(L, 1);
- return ret;
-}
-
-int main_loop(int cmd_fd, options_t* opt)
-{
- lua_State *L;
- L = luaL_newstate();
- if(!L) {
- log_printf(ERROR, "error creating lua state");
- return -1;
- }
-
- int ret = init_main_loop(L, opt->lua_file_);
- if(!ret)
- ret = call_main_loop(L, cmd_fd, opt);
-
- lua_close(L);
- return ret;
-}
-
-int main(int argc, char* argv[])
-{
- log_init();
-
- options_t opt;
- int ret = options_parse(&opt, argc, argv);
- if(ret) {
- if(ret > 0) {
- fprintf(stderr, "syntax error near: %s\n\n", argv[ret]);
- }
- if(ret == -2) {
- fprintf(stderr, "memory error on options_parse, exiting\n");
- }
-
- if(ret != -2)
- options_print_usage();
-
- options_clear(&opt);
- log_close();
- exit(ret);
- }
- string_list_element_t* tmp = opt.log_targets_.first_;
- if(!tmp) {
- log_add_target("syslog:3,luaclient,daemon");
- }
- else {
- while(tmp) {
- ret = log_add_target(tmp->string_);
- if(ret) {
- switch(ret) {
- case -2: fprintf(stderr, "memory error on log_add_target, exitting\n"); break;
- case -3: fprintf(stderr, "unknown log target: '%s', exitting\n", tmp->string_); break;
- case -4: fprintf(stderr, "this log target is only allowed once: '%s', exitting\n", tmp->string_); break;
- default: fprintf(stderr, "syntax error near: '%s', exitting\n", tmp->string_); break;
- }
-
- options_clear(&opt);
- log_close();
- exit(ret);
- }
- tmp = tmp->next_;
- }
- }
- log_printf(NOTICE, "just started...");
- if(options_parse_post(&opt)) {
- options_clear(&opt);
- log_close();
- exit(-1);
- }
-
- priv_info_t priv;
- if(opt.username_)
- if(priv_init(&priv, opt.username_, opt.groupname_)) {
- options_clear(&opt);
- log_close();
- exit(-1);
- }
-
- FILE* pid_file = NULL;
- if(opt.pid_file_) {
- pid_file = fopen(opt.pid_file_, "w");
- if(!pid_file) {
- log_printf(WARNING, "unable to open pid file: %s", strerror(errno));
- }
- }
-
- if(opt.chroot_dir_)
- if(do_chroot(opt.chroot_dir_)) {
- options_clear(&opt);
- log_close();
- exit(-1);
- }
- if(opt.username_)
- if(priv_drop(&priv)) {
- options_clear(&opt);
- log_close();
- exit(-1);
- }
-
- if(opt.daemonize_) {
- pid_t oldpid = getpid();
- daemonize();
- log_printf(INFO, "running in background now (old pid: %d)", oldpid);
- }
-
- if(pid_file) {
- pid_t pid = getpid();
- fprintf(pid_file, "%d", pid);
- fclose(pid_file);
- }
-
- for(;;) {
- // extern global variable defined in l_cmd.c
- cmd_fd = connect_command_socket(opt.command_sock_);
- if(cmd_fd < 0)
- ret = 2;
- else {
- ret = main_loop(cmd_fd, &opt);
- }
-
- if(ret == 2) {
- log_printf(ERROR, "socket error, trying to reconnect in 5 seconds..");
-
- if(cmd_fd > 0)
- close(cmd_fd);
- sleep(5);
- }
- else
- break;
- }
-
- if(cmd_fd > 0)
- close(cmd_fd);
-
- if(!ret)
- log_printf(NOTICE, "normal shutdown");
- else if(ret < 0)
- log_printf(NOTICE, "shutdown after error (code %d)", ret);
- else
- log_printf(NOTICE, "shutdown after signal");
-
- options_clear(&opt);
- log_close();
-
- return ret;
-}
diff --git a/src/mode-tcpserver.lua b/src/mode-tcpserver.lua
deleted file mode 100644
index 7f0d217..0000000
--- a/src/mode-tcpserver.lua
+++ /dev/null
@@ -1,175 +0,0 @@
---
--- rhctl
---
--- Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
---
--- This file is part of rhctl.
---
--- rhctl 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
--- any later version.
---
--- rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
---
-
-package.path = package.path .. ';/usr/share/rhctl/?.lua'
-
-socket = require("socket")
-
-current_mode = nil
-
-function init_server(host, port)
- local server = assert(socket.tcp())
-
- assert(server:setoption('reuseaddr', true))
- assert(server:bind(host, port))
- assert(server:listen(5))
-
- log.printf(log.DEBUG, "listening on " .. host .. ":" .. port)
-
- return server
-end
-
-local clients = {}
-
-function add_client(hdl)
- log.printf(log.DEBUG, "new client(" .. hdl:getfd() .. ") from " .. hdl:getpeername())
- local client = {}
- if current_mode then
- client.buffer = current_mode .. "\n"
- else
- client.buffer = ""
- end
- client.hdl = hdl
- client.getfd = function() return hdl:getfd() end
- client.dirty = function() return hdl:dirty() end
- table.insert(clients, client)
-end
-
-function remove_client(c)
- local idx = -1
- for n, client in ipairs(clients) do
- if client.getfd() == c.getfd() then
- idx = n
- break
- end
- end
-
- if idx > 0 then
- log.printf(log.DEBUG, "removing client(" .. c.getfd() .. ")")
- c.hdl:close()
- table.remove(clients, idx)
- end
-end
-
-function cleanup_clients()
- for _, client in ipairs(clients) do
- client.hdl:close()
- end
-end
-
-function clients_get_writeables()
- local fds = {}
-
- for _, client in ipairs(clients) do
- if client.buffer ~= "" then
- table.insert(fds, client)
- end
- end
-
- return fds
-end
-
-function clients_senddata(data)
- for _, client in ipairs(clients) do
- client.buffer = client.buffer .. data .. "\n"
- end
-end
-
-function process_cmd(message)
- log.printf(log.DEBUG, "received message: '%s'", message)
-
- local new_mode = nil
- local exps = { "Current Mode: (%a+)", "new Mode: (%a+)" }
- for _, exp in ipairs(exps) do
- new_mode = string.match(message, exp)
- if(new_mode) then
- new_mode = string.lower(new_mode)
- break
- end
- end
-
- if(new_mode and new_mode ~= current_mode) then
- clients_senddata(new_mode)
- current_mode = new_mode
- end
-
- return 0
-end
-
-function main_loop(opt)
- log.printf(log.NOTICE, "main_loop started")
- local sig = signal.init()
- local cmdfd = cmd.init()
-
- local server = init_server("*", "2345")
-
- cmd.send_string("listen mode");
- cmd.send_string("status");
-
- local return_value = 0
- while return_value == 0 do
- local readable, writeable, err = socket.select({ sig , cmdfd , server , unpack(clients) }, clients_get_writeables())
- if(err) then
- log.printf(log.ERROR, "select returned with error: %s", err)
- return_value = -1
- else
- for _, input in ipairs(readable) do
- if input == sig then
- return_value = signal.handle()
- if(return_value == 1) then break end
- elseif input == cmdfd then
- return_value = cmd.recv_data(process_cmd)
- if(return_value ~= 0) then break end
- elseif input == server then
- local client = server:accept()
- if(client == nil) then
- return_value =-3
- break
- else
- add_client(client)
- end
- else
- if input.hdl then
- -- receive is insanely stupid, therefore we must always read one byte only
- local _, err = input.hdl:receive(1)
- if err then
- remove_client(input)
- end
- end
- end
- end
- for _, output in ipairs(writeable) do
- local ret = output.hdl:send(output.buffer)
- if(ret == nil) then
- remove_client(output)
- else
- output.buffer = string.sub(output.buffer, ret+1)
- end
- end
- end
- end
-
- server:close()
- cleanup_clients()
-
- signal.stop()
- return return_value
-end
diff --git a/src/mode-watch.lua b/src/mode-watch.lua
deleted file mode 100644
index d90c86f..0000000
--- a/src/mode-watch.lua
+++ /dev/null
@@ -1,119 +0,0 @@
---
--- rhctl
---
--- Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
---
--- This file is part of rhctl.
---
--- rhctl 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
--- any later version.
---
--- rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
---
-
-package.path = package.path .. ';/usr/share/rhctl/?.lua'
-
-socket = require("socket")
-utils = require("utils")
-
-function set_master_led()
- os.execute("/sbin/led.sh set master")
- os.execute("/sbin/led.sh clear standby")
-end
-
-function set_standby_led()
- os.execute("/sbin/led.sh clear master")
- os.execute("/sbin/led.sh set standby")
-end
-
-function clear_leds()
- os.execute("/sbin/led.sh clear master")
- os.execute("/sbin/led.sh clear standby")
-end
-
-current_mode = nil
-
-function process_cmd(message)
- log.printf(log.DEBUG, "received message: '%s'", message)
-
- local new_mode = nil
- local exps = { "Current Mode: (%a+)", "new Mode: (%a+)" }
- for _, exp in ipairs(exps) do
- new_mode = string.match(message, exp)
- if(new_mode) then
- new_mode = string.lower(new_mode)
- if(new_mode == "master") then
- set_master_led()
- break
- else
- if(new_mode == "standby") then
- set_standby_led()
- break
- end
- end
- end
- end
-
- if(new_mode and new_mode ~= current_mode) then
- log.printf(log.NOTICE, "mode is now " .. new_mode)
- if(current_mode == nil) then
- utils.send_mail("logs@helsinki.at", "[RHCTL] (re)started mode is now " .. new_mode,
- "RHCTL just (re)started current mode is " .. new_mode)
- else
- utils.send_mail("logs@helsinki.at", "[RHCTL] mode changed to " .. new_mode,
- "RHCTL just switched from " .. current_mode .. " to " .. new_mode)
- end
- current_mode = new_mode
- end
-
- return 0
-end
-
-function main_loop(opt)
- log.printf(log.NOTICE, "main_loop started")
- local sig = signal.init()
- local cmdfd = cmd.init()
-
- cmd.send_string("listen mode");
- cmd.send_string("status");
-
- clear_leds()
-
- local return_value = 0
- while return_value == 0 do
- local readable, _, err = socket.select({ sig , cmdfd }, nil)
- if(err) then
- log.printf(log.ERROR, "select returned with error: %s", err)
- return_value = -1
- else
- for _, input in ipairs(readable) do
- if(input == sig) then
- return_value = signal.handle()
- if(return_value == 1) then break end
- else
- if(input == cmdfd) then
- return_value = cmd.recv_data(process_cmd)
- if(return_value ~= 0) then break end
- else
- log.printf(log.ERROR, "select returned invalid handle??")
- return_value = -1
- break;
- end
- end
- end
- end
- end
-
- clear_leds()
-
- signal.stop()
- return return_value
-end
diff --git a/src/options.c b/src/options.c
deleted file mode 100644
index bff561e..0000000
--- a/src/options.c
+++ /dev/null
@@ -1,555 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "datatypes.h"
-
-#include "options.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include "log.h"
-
-#define PARSE_BOOL_PARAM(SHORT, LONG, VALUE) \
- else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
- VALUE = 1;
-
-#define PARSE_INVERSE_BOOL_PARAM(SHORT, LONG, VALUE) \
- else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
- VALUE = 0;
-
-#define PARSE_INT_PARAM(SHORT, LONG, VALUE) \
- else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
- { \
- if(argc < 1) \
- return i; \
- VALUE = atoi(argv[i+1]); \
- argc--; \
- i++; \
- }
-
-#define PARSE_STRING_PARAM(SHORT, LONG, VALUE) \
- else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
- { \
- if(argc < 1 || argv[i+1][0] == '-') \
- return i; \
- if(VALUE) free(VALUE); \
- VALUE = strdup(argv[i+1]); \
- if(!VALUE) \
- return -2; \
- argc--; \
- i++; \
- }
-
-#define PARSE_STRING_PARAM_SEC(SHORT, LONG, VALUE) \
- else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
- { \
- if(argc < 1 || argv[i+1][0] == '-') \
- return i; \
- if(VALUE) free(VALUE); \
- VALUE = strdup(argv[i+1]); \
- if(!VALUE) \
- return -2; \
- size_t j; \
- for(j=0; j < strlen(argv[i+1]); ++j) \
- argv[i+1][j] = '#'; \
- argc--; \
- i++; \
- }
-
-#define PARSE_HEXSTRING_PARAM_SEC(SHORT, LONG, VALUE) \
- else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
- { \
- if(argc < 1 || argv[i+1][0] == '-') \
- return i; \
- int ret; \
- ret = options_parse_hex_string(argv[i+1], &VALUE); \
- if(ret > 0) \
- return i+1; \
- else if(ret < 0) \
- return ret; \
- size_t j; \
- for(j=0; j < strlen(argv[i+1]); ++j) \
- argv[i+1][j] = '#'; \
- argc--; \
- i++; \
- }
-
-#define PARSE_STRING_LIST(SHORT, LONG, LIST) \
- else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
- { \
- if(argc < 1 || argv[i+1][0] == '-') \
- return i; \
- int ret = string_list_add(&LIST, argv[i+1]); \
- if(ret == -2) \
- return ret; \
- else if(ret) \
- return i+1; \
- argc--; \
- i++; \
- }
-
-int options_parse_hex_string(const char* hex, buffer_t* buffer)
-{
- if(!hex || !buffer)
- return -1;
-
- u_int32_t hex_len = strlen(hex);
- if(hex_len%2)
- return 1;
-
- if(buffer->buf_)
- free(buffer->buf_);
-
- buffer->length_ = hex_len/2;
- buffer->buf_ = malloc(buffer->length_);
- if(!buffer->buf_) {
- buffer->length_ = 0;
- return -2;
- }
-
- const char* ptr = hex;
- int i;
- for(i=0;i<buffer->length_;++i) {
- u_int32_t tmp;
- sscanf(ptr, "%2X", &tmp);
- buffer->buf_[i] = (u_int8_t)tmp;
- ptr += 2;
- }
-
- return 0;
-}
-
-
-
-int options_parse(options_t* opt, int argc, char* argv[])
-{
- if(!opt)
- return -1;
-
- options_default(opt);
-
- if(opt->progname_)
- free(opt->progname_);
- opt->progname_ = strdup(argv[0]);
- if(!opt->progname_)
- return -2;
-
- argc--;
-
- char* mode = NULL;
- char* channel = NULL;
- char* baudrate = NULL;
-
- int i;
- for(i=1; argc > 0; ++i)
- {
- char* str = argv[i];
- argc--;
-
- if(!strcmp(str,"-h") || !strcmp(str,"--help"))
- return -1;
-#ifndef OPT_STDIOCLIENT
- PARSE_INVERSE_BOOL_PARAM("-D","--nodaemonize", opt->daemonize_)
- PARSE_STRING_PARAM("-u","--username", opt->username_)
- PARSE_STRING_PARAM("-g","--groupname", opt->groupname_)
- PARSE_STRING_PARAM("-C","--chroot", opt->chroot_dir_)
- PARSE_STRING_PARAM("-P","--write-pid", opt->pid_file_)
-#endif
- PARSE_STRING_LIST("-L","--log", opt->log_targets_)
- PARSE_STRING_PARAM("-s","--command-sock", opt->command_sock_)
-#ifndef OPT_STDIOCLIENT
- PARSE_STRING_PARAM("-b","--baudrate", baudrate)
-#endif
-#ifdef OPT_SWITCHCTL
- PARSE_STRING_PARAM("-f","--config", opt->conf_file_)
- PARSE_STRING_PARAM("-d","--device", opt->switch_dev_)
- PARSE_STRING_PARAM("-m","--mode", mode)
- PARSE_STRING_PARAM("-c","--channel", channel)
-#endif
-#ifdef OPT_SERIALCLIENT
- PARSE_STRING_PARAM("-d","--device", opt->serial_dev_)
- PARSE_STRING_PARAM("-t","--type", opt->type_)
-#endif
-#ifdef OPT_HEARTBEATCLIENT
- PARSE_STRING_PARAM("-d","--device", opt->serial_dev_)
- PARSE_INT_PARAM("-t","--timeout", opt->timeout_)
- PARSE_STRING_PARAM("-l","--led", opt->led_filename_)
-#endif
-#ifdef OPT_LUACLIENT
- PARSE_STRING_PARAM("-f","--lua-file", opt->lua_file_)
-#endif
- else
- return i;
- }
-
- if(mode) {
- if(!strcmp(mode, "master"))
- opt->mode_ = MODE_MASTER;
- else if(!strcmp(mode, "standby"))
- opt->mode_ = MODE_STANDBY;
- else {
- free(mode);
- return -3;
- }
- free(mode);
- }
-
- if(channel) {
- if(!strcmp(channel, "main")) {
- opt->channel_master_ = CHAN_MAIN;
- opt->channel_standby_ = CHAN_MAIN;
- }
- else if(!strcmp(channel, "music")) {
- opt->channel_master_ = CHAN_MUSIC;
- opt->channel_standby_ = CHAN_MUSIC;
- }
- else {
- free(channel);
- return -4;
- }
- free(channel);
- }
-
- if(baudrate) {
- int b = atoi(baudrate);
- free(baudrate);
- switch(b) {
- case 1200: opt->baudrate_ = B1200; break;
- case 2400: opt->baudrate_ = B2400; break;
- case 4800: opt->baudrate_ = B4800; break;
- case 9600: opt->baudrate_ = B9600; break;
- case 19200: opt->baudrate_ = B19200; break;
- case 38400: opt->baudrate_ = B38400; break;
- case 57600: opt->baudrate_ = B57600; break;
- case 115200: opt->baudrate_ = B115200; break;
- default: return -5;
- }
- }
-
- return 0;
-}
-
-int options_parse_post(options_t* opt)
-{
- if(!opt)
- return -1;
-// nothing to do
-
-#ifdef OPT_SWITCHCTL
- FILE* conf_file = fopen(opt->conf_file_, "r");
- if(conf_file) {
- char buf[100];
- while(fgets(buf, 100, conf_file) != NULL) {
- char* tmp, *key, *value;
- for(tmp = buf;*tmp == ' '; ++tmp);
- if(*(key = tmp) == 0) continue;
- for(;*tmp != ' ' && *tmp != 0;++tmp);
- if(*tmp == 0) continue;
- *tmp=0;
- ++tmp;
- for(;*tmp == ' ';++tmp);
- if(*(value = tmp) == 0) continue;
- for(;*tmp != ' ' && *tmp != 0 && *tmp != '\n';++tmp);
- *tmp = 0;
-
- if(key_value_storage_add(&opt->alias_table_, key, value))
- return -2;
- }
- fclose(conf_file);
- }
- else {
- log_printf(ERROR,"unable to open conf file (%s): %s", opt->conf_file_, strerror(errno));
- return -1;
- }
-#endif
-
- return 0;
-}
-
-void options_default(options_t* opt)
-{
- if(!opt)
- return;
-
-#ifdef OPT_SWITCHCTL
- opt->progname_ = strdup("switchctl");
-#endif
-#ifdef OPT_SERIALCLIENT
- opt->progname_ = strdup("serialclient");
-#endif
-#ifdef OPT_STDIOCLIENT
- opt->progname_ = strdup("stdioclient");
-#endif
-#ifdef OPT_HEARTBEATCLIENT
- opt->progname_ = strdup("heartbeatclient");
-#endif
-#ifdef OPT_LUACLIENT
- opt->progname_ = strdup("luaclient");
-#endif
-
-/* common */
- opt->daemonize_ = 1;
- opt->username_ = NULL;
- opt->groupname_ = NULL;
- opt->chroot_dir_ = NULL;
- opt->pid_file_ = NULL;
- string_list_init(&opt->log_targets_);
-
- opt->command_sock_ = strdup("/var/run/rhctl/switchctl.sock");
- opt->baudrate_ = B19200;
-
-/* switchctl */
- opt->mode_ = MODE_MASTER;
- opt->channel_master_ = CHAN_MAIN;
- opt->channel_standby_ = CHAN_MAIN;
- opt->conf_file_ = strdup("/etc/rhctl/switchctl.conf");
- opt->switch_dev_ = strdup("/dev/audioswitch");
- key_value_storage_init(&opt->alias_table_);
-
-/* serialclient and heartbeatclient */
- opt->serial_dev_ = strdup("/dev/ttyUSB0");
-
-/* serialclient only */
- opt->type_ = NULL;
-
-/* heartbeatclient only */
- opt->timeout_ = 15;
- opt->led_filename_ = NULL;
-
-/* luaclient only */
- opt->lua_file_ = strdup("/usr/share/rhctl/mode-leds.lua");
-}
-
-#ifdef OPT_LUACLIENT
-void options_lua_push_string(lua_State* L, const int tidx, const char* key, const char* value)
-{
- lua_pushstring(L, key);
- lua_pushstring(L, value);
- lua_settable(L, tidx);
-}
-
-void options_lua_push_int(lua_State* L, const int tidx, const char* key, const u_int32_t value)
-{
- lua_pushstring(L, key);
- lua_pushinteger(L, value);
- lua_settable(L, tidx);
-}
-
-void options_lua_push_boolean(lua_State* L, const int tidx, const char* key, const u_int32_t value)
-{
- lua_pushstring(L, key);
- lua_pushboolean(L, value);
- lua_settable(L, tidx);
-}
-
-void options_lua_push_string_list(lua_State* L, const int tidx, string_list_t* lst)
-{
- if(!lst)
- return;
-
- string_list_element_t* tmp = lst->first_;
- if(tmp) {
- lua_pushstring(L, "log_targets");
- lua_newtable(L);
- int i = 1;
- while(tmp) {
- lua_pushinteger(L, i++);
- lua_pushstring(L, tmp->string_);
- lua_settable(L, -3);
- tmp = tmp->next_;
- }
- lua_settable(L, tidx);
- }
-}
-
-void options_lua_push(options_t* opt, lua_State* L)
-{
- lua_newtable(L);
-
- options_lua_push_string(L, -3, "progname", opt->progname_);
- options_lua_push_boolean(L, -3, "daemonize", opt->daemonize_);
- options_lua_push_string(L, -3, "username", opt->username_);
- options_lua_push_string(L, -3, "groupname", opt->groupname_);
- options_lua_push_string(L, -3, "chroot_dir", opt->chroot_dir_);
- options_lua_push_string(L, -3, "pid_file", opt->pid_file_);
- options_lua_push_string_list(L, -3, &(opt->log_targets_));
- options_lua_push_string(L, -3, "command_sock", opt->command_sock_);
- options_lua_push_string(L, -3, "lua_file", opt->lua_file_);
-}
-#endif
-
-void options_clear(options_t* opt)
-{
- if(!opt)
- return;
-
-/* common */
- if(opt->progname_)
- free(opt->progname_);
- if(opt->username_)
- free(opt->username_);
- if(opt->groupname_)
- free(opt->groupname_);
- if(opt->chroot_dir_)
- free(opt->chroot_dir_);
- if(opt->pid_file_)
- free(opt->pid_file_);
- string_list_clear(&opt->log_targets_);
-
- if(opt->command_sock_)
- free(opt->command_sock_);
-
-/* switchctl */
- if(opt->conf_file_)
- free(opt->conf_file_);
- if(opt->switch_dev_)
- free(opt->switch_dev_);
- key_value_storage_clear(&opt->alias_table_);
-
-/* serialclient and heartbeatclient */
- if(opt->serial_dev_)
- free(opt->serial_dev_);
-
-/* serialclient only */
- if(opt->type_)
- free(opt->type_);
-
-/* heartbeatcleint only */
- if(opt->led_filename_)
- free(opt->led_filename_);
-
-/* luaclient only */
- if(opt->lua_file_)
- free(opt->lua_file_);
-}
-
-void options_print_usage()
-{
- printf("USAGE:\n");
-#ifdef OPT_SWITCHCTL
- printf("switchctl\n");
-#endif
-#ifdef OPT_SERIALCLIENT
- printf("serialclient\n");
-#endif
-#ifdef OPT_STDIOCLIENT
- printf("serialclient\n");
-#endif
-#ifdef OPT_HEARTBEATCLIENT
- printf("heartbeatclient\n");
-#endif
- printf(" [-h|--help] prints this...\n");
-#ifndef OPT_STDIOCLIENT
- printf(" [-D|--nodaemonize] don't run in background\n");
- printf(" [-u|--username] <username> change to this user\n");
- printf(" [-g|--groupname] <groupname> change to this group\n");
- printf(" [-C|--chroot] <path> chroot to this directory\n");
- printf(" [-P|--write-pid] <path> write pid to this file\n");
-#endif
- printf(" [-L|--log] <target>:<level>[,<param1>[,<param2>..]]\n");
- printf(" add a log target, can be invoked several times\n");
- printf(" [-s|--command-sock] <unix sock> the command socket e.g. /var/run/rhctl/switchctl.sock\n");
-#ifndef OPT_STDIOCLIENT
- printf(" [-b|--baudrate] <baudrate> the baudrate of the tty to use e.g. 19200\n");
-#endif
-#ifdef OPT_SWITCHCTL
- printf(" [-d|--device] <tty> the tty the audio switch is connected to e.g. /dev/audioswitch\n");
- printf(" [-f|--config] <file> the configuration file e.g. /etc/rhctl/switchctl.conf\n");
- printf(" [-m|--mode] <mode> the initial mode to use e.g. master\n");
- printf(" [-c|--channel] <channel> the initial channel to use e.g. main\n");
-#endif
-#ifdef OPT_SERIALCLIENT
- printf(" [-d|--device] <tty> the tty to connect to e.g. /dev/ttyUSB0\n");
- printf(" [-t|--type] <type> use this client type\n");
-#endif
-#ifdef OPT_HEARTBEATCLIENT
- printf(" [-d|--device] <tty> the tty to connect to e.g. /dev/ttyUSB0\n");
- printf(" [-t|--timeout] <timeout> heartbeat timeout in tenths of a second e.g. 15 -> 1.5s\n");
- printf(" [-l|--led] <led filename> sysfs filename of led device to blink\n");
-#endif
-#ifdef OPT_LUACLIENT
- printf(" [-f|--lua-file] <file> the configuration file e.g. /usr/share/rhctl/mode-leds.lua\n");
-#endif
-}
-
-void options_print(options_t* opt)
-{
- if(!opt)
- return;
-
- printf("progname: '%s'\n", opt->progname_);
-#ifndef OPT_STDIOCLIENT
- printf("daemonize: %d\n", opt->daemonize_);
- printf("username: '%s'\n", opt->username_);
- printf("groupname: '%s'\n", opt->groupname_);
- printf("chroot_dir: '%s'\n", opt->chroot_dir_);
- printf("pid_file: '%s'\n", opt->pid_file_);
-#endif
- printf("log_targets: \n");
- string_list_print(&opt->log_targets_, " '", "'\n");
-
- printf("command_sock: '%s'\n", opt->command_sock_);
-
-#ifndef OPT_STDIOCLIENT
- char* br;
- switch(opt->baudrate_) {
- case B1200: br = "1200"; break;
- case B2400: br = "2400"; break;
- case B4800: br = "4800"; break;
- case B9600: br = "9600"; break;
- case B19200: br = "19200"; break;
- case B38400: br = "38400"; break;
- case B57600: br = "57600"; break;
- case B115200: br = "115200"; break;
- default: br = "invalid"; break;
- }
- printf("baudrate: '%s'\n", br);
-#endif
-
-#ifdef OPT_SWITCHCTL
- printf("mode: '%s'\n", opt->mode_ == MODE_MASTER ? "master" : "standby");
- printf("channel_master: '%s'\n", opt->channel_master_ == CHAN_MAIN ? "main" : "music");
- printf("channel_standby: '%s'\n", opt->channel_standby_ == CHAN_MAIN ? "main" : "music");
- printf("conf_file: '%s'\n", opt->conf_file_);
- printf("switch_dev: '%s'\n", opt->switch_dev_);
- printf("alias_table: \n");
- key_value_storage_print(&opt->alias_table_, " '", "' -> '", "'\n");
-#endif
-
-#ifdef OPT_SERIALCLIENT
- printf("serial_dev: '%s'\n", opt->serial_dev_);
- printf("type: '%s'\n", opt->type_);
-#endif
-
-#ifdef OPT_HEARTBEATCLIENT
- printf("serial_dev: '%s'\n", opt->serial_dev_);
- printf("timeout: %d\n", opt->timeout_);
- printf("led_filename: '%s'\n", opt->led_filename_);
-#endif
-
-#ifdef OPT_LUACLIENT
- printf("lua_file: '%s'\n", opt->lua_file_);
-#endif
-}
diff --git a/src/options.h b/src/options.h
deleted file mode 100644
index df13ebe..0000000
--- a/src/options.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef RHCTL_options_h_INCLUDED
-#define RHCTL_options_h_INCLUDED
-
-#include <lua.h>
-
-#include "string_list.h"
-#include "key_value_storage.h"
-#include <termios.h>
-
-enum mode_enum { MODE_MASTER, MODE_STANDBY };
-typedef enum mode_enum switchctl_mode_t;
-
-enum channel_enum { CHAN_MAIN, CHAN_MUSIC };
-typedef enum channel_enum switchctl_channel_t;
-
-struct options_struct {
-/* common */
- char* progname_;
- int daemonize_;
- char* username_;
- char* groupname_;
- char* chroot_dir_;
- char* pid_file_;
- string_list_t log_targets_;
-
- char* command_sock_;
- speed_t baudrate_;
-
-/* switchctl */
- switchctl_mode_t mode_;
- switchctl_channel_t channel_master_;
- switchctl_channel_t channel_standby_;
- char* conf_file_;
- char* switch_dev_;
- key_value_storage_t alias_table_;
-
-/* serialclient and heartbeatclient */
- char* serial_dev_;
-
-/* serialclient only */
- char* type_;
-
-/* heartbeatclient only */
- u_int32_t timeout_;
- char* led_filename_;
-
-/* luaclient only */
- char* lua_file_;
-};
-typedef struct options_struct options_t;
-
-int options_parse_hex_string(const char* hex, buffer_t* buffer);
-
-int options_parse(options_t* opt, int argc, char* argv[]);
-int options_parse_post(options_t* opt);
-void options_default(options_t* opt);
-void options_lua_push_string(lua_State* L, const int tidx, const char* key, const char* value);
-void options_lua_push_int(lua_State* L, const int tidx, const char* key, const u_int32_t value);
-void options_lua_push_boolean(lua_State* L, const int tidx, const char* key, const u_int32_t value);
-void options_lua_push_string_list(lua_State* L, const int tidx, string_list_t* lst);
-void options_lua_push(options_t* opt, lua_State* L);
-void options_clear(options_t* opt);
-void options_print_usage();
-void options_print(options_t* opt);
-
-#endif
diff --git a/src/rhctl/main.go b/src/rhctl/main.go
new file mode 100644
index 0000000..430c287
--- /dev/null
+++ b/src/rhctl/main.go
@@ -0,0 +1,103 @@
+//
+// rhctl
+//
+// Copyright (C) 2009-2016 Christian Pointner <equinox@helsinki.at>
+//
+// This file is part of rhctl.
+//
+// rhctl 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
+// any later version.
+//
+// rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
+//
+
+package main
+
+import (
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "os"
+ "os/signal"
+ "sync"
+)
+
+var (
+ rhl = log.New(os.Stderr, "[rhctl]\t", log.LstdFlags)
+ rhdl = log.New(ioutil.Discard, "[rhctl-dbg]\t", log.LstdFlags)
+)
+
+func init() {
+ if _, exists := os.LookupEnv("RHCTL_DEBUG"); exists {
+ rhdl.SetOutput(os.Stderr)
+ }
+}
+
+type envStringValue string
+
+func newEnvStringValue(key, dflt string) *envStringValue {
+ if envval, exists := os.LookupEnv(key); exists {
+ return (*envStringValue)(&envval)
+ } else {
+ return (*envStringValue)(&dflt)
+ }
+}
+
+func (s *envStringValue) Set(val string) error {
+ *s = envStringValue(val)
+ return nil
+}
+
+func (s *envStringValue) Get() interface{} { return string(*s) }
+
+func (s *envStringValue) String() string { return fmt.Sprintf("%s", *s) }
+
+func main() {
+ webAddr := newEnvStringValue("RHCTL_WEB_ADDR", "localhost:4080")
+ flag.Var(webAddr, "web-addr", "addr:port to listen on (environment: RHCTL_WEB_ADDR)")
+ help := flag.Bool("help", false, "show usage")
+
+ flag.Parse()
+ if *help {
+ flag.Usage()
+ return
+ }
+
+ var wg sync.WaitGroup
+
+ if webAddr.Get().(string) != "" {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ rhl.Println("starting web-api:", webAddr.Get().(string))
+ //StartControlWeb(webAddr.Get().(string))
+ rhl.Println("web-api finished")
+ }()
+ }
+
+ alldone := make(chan bool)
+ go func() {
+ defer func() { alldone <- true }()
+ wg.Wait()
+ }()
+
+ c := make(chan os.Signal, 1)
+ signal.Notify(c, os.Interrupt)
+
+ select {
+ case <-c:
+ rhl.Println("received interrupt, shutdown")
+ return
+ case <-alldone:
+ return
+ }
+}
diff --git a/src/serialclient.c b/src/serialclient.c
deleted file mode 100644
index caafbbb..0000000
--- a/src/serialclient.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "datatypes.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include "log.h"
-#include "sig_handler.h"
-#include "options.h"
-
-#include "daemon.h"
-#include "utils.h"
-
-int process_cmd(const char* cmd, int fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt)
-{
- return 0;
-}
-
-int process_data(int src_fd, int dest_fd)
-{
- char* buffer[100];
- int ret = read(src_fd, buffer, 100);
- if(!ret)
- return 2;
- if(ret == -1 && errno == EAGAIN)
- return 0;
- if(ret < 0)
- return ret;
-
- log_printf(DEBUG, "read %d bytes from fd (%d)", ret, src_fd);
-
- int len = ret;
- int offset = 0;
- for(;;) {
- ret = write(dest_fd, &buffer[offset], len - offset);
- if(ret < 0) {
- if(errno != EINTR)
- return ret;
-
- ret = 0;
- }
-
- offset += ret;
- if(offset >= len)
- break;
- }
- log_printf(DEBUG, "wrote %d bytes to fd (%d)", offset, dest_fd);
- return 0;
-}
-
-int main_loop(int serial_fd, int cmd_fd, options_t* opt)
-{
- log_printf(NOTICE, "entering main loop");
-
- fd_set readfds, tmpfds;
- FD_ZERO(&readfds);
- FD_SET(serial_fd, &readfds);
- FD_SET(cmd_fd, &readfds);
- int max_fd = serial_fd > cmd_fd ? serial_fd : cmd_fd;
-
- int sig_fd = signal_init();
- if(sig_fd < 0)
- return -1;
- FD_SET(sig_fd, &readfds);
- max_fd = (max_fd < sig_fd) ? sig_fd : max_fd;
-
- int return_value = 0;
- if(opt->type_) {
- char* tmp;
- int len = asprintf(&tmp, "type %s\n", opt->type_);
- if(len < 0) {
- log_printf(ERROR, "memory error at init");
- return_value = -2;
- }
- else {
- return_value = send_string(cmd_fd, tmp);
- free(tmp);
- if(return_value <= 0) {
- log_printf(ERROR, "error setting client type");
- return_value = -1;
- }
- else {
- log_printf(NOTICE, "connecting as type '%s'", opt->type_);
- return_value = 0;
- }
- }
- }
-
- while(!return_value) {
- memcpy(&tmpfds, &readfds, sizeof(tmpfds));
-
- int ret = select(max_fd+1, &tmpfds, NULL, NULL, NULL);
- if(ret == -1 && errno != EINTR) {
- log_printf(ERROR, "select returned with error: %s", strerror(errno));
- return_value = -1;
- break;
- }
- if(ret == -1 || !ret)
- continue;
-
- if(FD_ISSET(sig_fd, &tmpfds))
- if(signal_handle())
- return_value = 1;
-
- if(FD_ISSET(serial_fd, &tmpfds))
- return_value = process_data(serial_fd, cmd_fd);
-
- if(FD_ISSET(cmd_fd, &tmpfds)) {
- return_value = process_data(cmd_fd, serial_fd);
- if(return_value == 2) return_value = 3;
- }
- }
-
- signal_stop();
- return return_value;
-}
-
-int main(int argc, char* argv[])
-{
- log_init();
-
- options_t opt;
- int ret = options_parse(&opt, argc, argv);
- if(ret) {
- if(ret > 0) {
- fprintf(stderr, "syntax error near: %s\n\n", argv[ret]);
- }
- if(ret == -2) {
- fprintf(stderr, "memory error on options_parse, exiting\n");
- }
- if(ret == -5) {
- fprintf(stderr, "syntax error: invalid baudrate\n");
- }
-
- if(ret != -2)
- options_print_usage();
-
- options_clear(&opt);
- log_close();
- exit(ret);
- }
- string_list_element_t* tmp = opt.log_targets_.first_;
- if(!tmp) {
- log_add_target("syslog:3,serialclient,daemon");
- }
- else {
- while(tmp) {
- ret = log_add_target(tmp->string_);
- if(ret) {
- switch(ret) {
- case -2: fprintf(stderr, "memory error on log_add_target, exitting\n"); break;
- case -3: fprintf(stderr, "unknown log target: '%s', exitting\n", tmp->string_); break;
- case -4: fprintf(stderr, "this log target is only allowed once: '%s', exitting\n", tmp->string_); break;
- default: fprintf(stderr, "syntax error near: '%s', exitting\n", tmp->string_); break;
- }
-
- options_clear(&opt);
- log_close();
- exit(ret);
- }
- tmp = tmp->next_;
- }
- }
- log_printf(NOTICE, "just started...");
- if(options_parse_post(&opt)) {
- options_clear(&opt);
- log_close();
- exit(-1);
- }
-
- priv_info_t priv;
- if(opt.username_)
- if(priv_init(&priv, opt.username_, opt.groupname_)) {
- options_clear(&opt);
- log_close();
- exit(-1);
- }
-
- FILE* pid_file = NULL;
- if(opt.pid_file_) {
- pid_file = fopen(opt.pid_file_, "w");
- if(!pid_file) {
- log_printf(WARNING, "unable to open pid file: %s", strerror(errno));
- }
- }
-
- if(opt.chroot_dir_)
- if(do_chroot(opt.chroot_dir_)) {
- options_clear(&opt);
- log_close();
- exit(-1);
- }
- if(opt.username_)
- if(priv_drop(&priv)) {
- options_clear(&opt);
- log_close();
- exit(-1);
- }
-
- if(opt.daemonize_) {
- pid_t oldpid = getpid();
- daemonize();
- log_printf(INFO, "running in background now (old pid: %d)", oldpid);
- }
-
- if(pid_file) {
- pid_t pid = getpid();
- fprintf(pid_file, "%d", pid);
- fclose(pid_file);
- }
-
- int cmd_fd = 0;
- int serial_fd = 0;
- for(;;) {
- cmd_fd = connect_command_socket(opt.command_sock_);
- if(cmd_fd < 0)
- ret = 3;
- else {
- serial_fd = open(opt.serial_dev_, O_RDWR | O_NOCTTY);
- if(serial_fd < 0) {
- log_printf(ERROR, "open(%s): %s", opt.serial_dev_, strerror(errno));
- ret = 2;
- }
- else {
- ret = setup_tty(serial_fd, opt.baudrate_);
- if(ret)
- ret = 2;
- else
- ret = main_loop(serial_fd, cmd_fd, &opt);
- }
- }
-
- if(ret == 2 || ret == 3) {
- if(ret == 2)
- log_printf(ERROR, "%s error, trying to reopen in 5 seconds..", opt.serial_dev_);
- if(ret == 3)
- log_printf(ERROR, "socket error, trying to reconnect in 5 seconds..");
-
- if(cmd_fd > 0)
- close(cmd_fd);
- if(serial_fd > 0)
- close(serial_fd);
- sleep(5);
- }
- else
- break;
- }
-
- if(cmd_fd > 0)
- close(cmd_fd);
- if(serial_fd > 0)
- close(serial_fd);
-
- if(!ret)
- log_printf(NOTICE, "normal shutdown");
- else if(ret < 0)
- log_printf(NOTICE, "shutdown after error (code %d)", ret);
- else
- log_printf(NOTICE, "shutdown after signal");
-
- options_clear(&opt);
- log_close();
-
- return ret;
-}
diff --git a/src/sig_handler.c b/src/sig_handler.c
deleted file mode 100644
index f9043a1..0000000
--- a/src/sig_handler.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "datatypes.h"
-
-#include "log.h"
-#include "sig_handler.h"
-
-#include <signal.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-
-static int sig_pipe_fds[2];
-int reset_flag;
-
-static void sig_handler(int sig)
-{
- sigset_t set;
- int ret = read(sig_pipe_fds[0], &set, sizeof(sigset_t));
- if(ret != sizeof(sigset_t))
- sigemptyset(&set);
-
- sigaddset(&set, sig);
- ret = write(sig_pipe_fds[1], &set, sizeof(sigset_t));
-}
-
-
-int signal_init()
-{
- if(pipe(sig_pipe_fds)) {
- log_printf(ERROR, "signal handling init failed (pipe error: %s)", strerror(errno));
- return -1;
- }
-
- int i;
- for(i=0; i<2; ++i) {
- int fd_flags = fcntl(sig_pipe_fds[i], F_GETFL);
- if(fd_flags == -1) {
- log_printf(ERROR, "signal handling init failed (pipe fd[%d] read flags error: %s)", i, strerror(errno));
- return -1;
- }
- if(fcntl(sig_pipe_fds[i], F_SETFL, fd_flags | O_NONBLOCK) == -1){
- log_printf(ERROR, "signal handling init failed (pipe fd[%d] write flags error: %s)", i, strerror(errno));
- return -1;
- }
- }
-
- struct sigaction act, ign;
- act.sa_handler = sig_handler;
- sigfillset(&act.sa_mask);
- act.sa_flags = 0;
- ign.sa_handler = SIG_IGN;
- sigfillset(&ign.sa_mask);
- ign.sa_flags = 0;
-
- if((sigaction(SIGINT, &act, NULL) < 0) ||
- (sigaction(SIGQUIT, &act, NULL) < 0) ||
- (sigaction(SIGTERM, &act, NULL) < 0) ||
- (sigaction(SIGHUP, &act, NULL) < 0) ||
- (sigaction(SIGUSR1, &act, NULL) < 0) ||
- (sigaction(SIGUSR2, &act, NULL) < 0) ||
- (sigaction(SIGCHLD, &ign, NULL) < 0) ||
- (sigaction(SIGPIPE, &ign, NULL) < 0)) {
-
- log_printf(ERROR, "signal handling init failed (sigaction error: %s)", strerror(errno));
- close(sig_pipe_fds[0]);
- close(sig_pipe_fds[1]);
- }
-
- return sig_pipe_fds[0];
-}
-
-int signal_handle()
-{
- sigset_t set, oldset, tmpset;
-
- sigemptyset(&tmpset);
- sigaddset(&tmpset, SIGINT);
- sigaddset(&tmpset, SIGQUIT);
- sigaddset(&tmpset, SIGTERM);
- sigaddset(&tmpset, SIGHUP);
- sigaddset(&tmpset, SIGUSR1);
- sigaddset(&tmpset, SIGUSR2);
- sigprocmask(SIG_BLOCK, &tmpset, &oldset);
-
- int ret = read(sig_pipe_fds[0], &set, sizeof(sigset_t));
- if(ret != sizeof(sigset_t))
- sigemptyset(&set);
-
- int return_value = 0;
- int sig;
- for(sig=1; sig < NSIG; ++sig) {
- if(sigismember(&set, sig)) {
- switch(sig) {
- case SIGINT: log_printf(NOTICE, "SIG-Int caught, exitting"); return_value = 1; break;
- case SIGQUIT: log_printf(NOTICE, "SIG-Quit caught, exitting"); return_value = 1; break;
- case SIGTERM: log_printf(NOTICE, "SIG-Term caught, exitting"); return_value = 1; break;
- case SIGHUP: log_printf(NOTICE, "SIG-Hup caught"); reset_flag = 1; break;
- case SIGUSR1: log_printf(NOTICE, "SIG-Usr1 caught"); break;
- case SIGUSR2: log_printf(NOTICE, "SIG-Usr2 caught"); break;
- default: log_printf(WARNING, "unknown signal %d caught, ignoring", sig); break;
- }
- sigdelset(&set, sig);
- }
- }
-
- sigprocmask(SIG_SETMASK, &oldset, NULL);
- return return_value;
-}
-
-void signal_stop()
-{
- struct sigaction act;
- act.sa_handler = SIG_DFL;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0;
-
- sigaction(SIGINT, &act, NULL);
- sigaction(SIGQUIT, &act, NULL);
- sigaction(SIGTERM, &act, NULL);
- sigaction(SIGHUP, &act, NULL);
- sigaction(SIGUSR1, &act, NULL);
- sigaction(SIGUSR2, &act, NULL);
- sigaction(SIGPIPE, &act, NULL);
- sigaction(SIGCHLD, &act, NULL);
-
- close(sig_pipe_fds[0]);
- close(sig_pipe_fds[1]);
-}
diff --git a/src/sig_handler.h b/src/sig_handler.h
deleted file mode 100644
index a923418..0000000
--- a/src/sig_handler.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef RHCTL_sig_handler_h_INCLUDED
-#define RHCTL_sig_handler_h_INCLUDED
-
-extern int reset_flag;
-
-int signal_init();
-int signal_handle();
-void signal_stop();
-
-#endif
diff --git a/src/silence-watch.lua b/src/silence-watch.lua
deleted file mode 100644
index aa7354d..0000000
--- a/src/silence-watch.lua
+++ /dev/null
@@ -1,87 +0,0 @@
---
--- rhctl
---
--- Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
---
--- This file is part of rhctl.
---
--- rhctl 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
--- any later version.
---
--- rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
---
-
-package.path = package.path .. ';/usr/share/rhctl/?.lua'
-
-socket = require("socket")
-utils = require("utils")
-
-current_state = nil
-
-function process_cmd(message)
- log.printf(log.DEBUG, "received message: '%s'", message)
-
- silence_state = string.match(message, "S0S,(%d)")
-
- if(silence_state and silence_state ~= current_state) then
- if(silence_state == "0") then
- log.printf(log.NOTICE, "seen some noise")
- utils.send_mail("silence@helsinki.at", "[RHCTL] sees some noise",
- "There is some noise at output 1 of the audioswitch\nCurrent State is: " .. message)
- else
- if (silence_state == "1") then
- log.printf(log.NOTICE, "silence detected")
- utils.send_mail("silence@helsinki.at", "[RHCTL] silence detected ",
- "Silence detected at output 1 of the audioswitch, make some noise!!\nCurrent State is: " .. message)
- end
- end
- current_state = silence_state
- end
-
- return 0
-end
-
-function main_loop(opt)
- log.printf(log.NOTICE, "main_loop started")
- local sig = signal.init()
- local cmdfd = cmd.init()
-
- cmd.send_string("listen silence");
- cmd.send_string("switch *0SS");
-
- local return_value = 0
- while return_value == 0 do
- local readable, _, err = socket.select({ sig , cmdfd }, nil)
- if(err) then
- log.printf(log.ERROR, "select returned with error: %s", err)
- return_value = -1
- else
- for _, input in ipairs(readable) do
- if(input == sig) then
- return_value = signal.handle()
- if(return_value == 1) then break end
- else
- if(input == cmdfd) then
- return_value = cmd.recv_data(process_cmd)
- if(return_value ~= 0) then break end
- else
- log.printf(log.ERROR, "select returned invalid handle??")
- return_value = -1
- break;
- end
- end
- end
- end
- end
-
- signal.stop()
- return return_value
-end
diff --git a/src/stdioclient.c b/src/stdioclient.c
deleted file mode 100644
index a8bcad1..0000000
--- a/src/stdioclient.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "datatypes.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include "log.h"
-#include "sig_handler.h"
-#include "options.h"
-
-#include "daemon.h"
-#include "utils.h"
-
-int process_cmd(const char* cmd, int fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt)
-{
- return 0;
-}
-
-int process_data(int src_fd, int dest_fd)
-{
- char* buffer[100];
- int ret = read(src_fd, buffer, 100);
- if(!ret)
- return 2;
- if(ret == -1 && errno == EAGAIN)
- return 0;
- if(ret < 0)
- return ret;
-
- log_printf(DEBUG, "read %d bytes from fd (%d)", ret, src_fd);
-
- int len = ret;
- int offset = 0;
- for(;;) {
- ret = write(dest_fd, &buffer[offset], len - offset);
- if(ret < 0) {
-
- if(errno != EINTR)
- return ret;
-
- ret = 0;
- }
-
- offset += ret;
- if(offset+1 >= len)
- break;
- }
- return 0;
-}
-
-int main_loop(int cmd_fd, options_t* opt)
-{
- log_printf(NOTICE, "entering main loop");
-
- fd_set readfds, tmpfds;
- FD_ZERO(&readfds);
- FD_SET(0, &readfds);
- FD_SET(cmd_fd, &readfds);
- int max_fd = cmd_fd;
-
- int sig_fd = signal_init();
- if(sig_fd < 0)
- return -1;
- FD_SET(sig_fd, &readfds);
- max_fd = (max_fd < sig_fd) ? sig_fd : max_fd;
-
- int return_value = 0;
-
- while(!return_value) {
- memcpy(&tmpfds, &readfds, sizeof(tmpfds));
-
- int ret = select(max_fd+1, &tmpfds, NULL, NULL, NULL);
- if(ret == -1 && errno != EINTR) {
- log_printf(ERROR, "select returned with error: %s", strerror(errno));
- return_value = -1;
- break;
- }
- if(ret == -1 || !ret)
- continue;
-
- if(FD_ISSET(sig_fd, &tmpfds))
- if(signal_handle())
- return_value = 1;
-
- if(FD_ISSET(0, &tmpfds))
- return_value = process_data(0, cmd_fd);
-
- if(FD_ISSET(cmd_fd, &tmpfds))
- return_value = process_data(cmd_fd, 1);
- }
-
- signal_stop();
- return return_value;
-}
-
-int main(int argc, char* argv[])
-{
- log_init();
-
- options_t opt;
- int ret = options_parse(&opt, argc, argv);
- if(ret) {
- if(ret > 0) {
- fprintf(stderr, "syntax error near: %s\n\n", argv[ret]);
- }
- if(ret == -2) {
- fprintf(stderr, "memory error on options_parse, exiting\n");
- }
-
- if(ret != -2)
- options_print_usage();
-
- options_clear(&opt);
- log_close();
- exit(ret);
- }
- string_list_element_t* tmp = opt.log_targets_.first_;
- if(!tmp) {
- log_add_target("stderr:2");
- }
- else {
- while(tmp) {
- ret = log_add_target(tmp->string_);
- if(ret) {
- switch(ret) {
- case -2: fprintf(stderr, "memory error on log_add_target, exitting\n"); break;
- case -3: fprintf(stderr, "unknown log target: '%s', exitting\n", tmp->string_); break;
- case -4: fprintf(stderr, "this log target is only allowed once: '%s', exitting\n", tmp->string_); break;
- default: fprintf(stderr, "syntax error near: '%s', exitting\n", tmp->string_); break;
- }
-
- options_clear(&opt);
- log_close();
- exit(ret);
- }
- tmp = tmp->next_;
- }
- }
- log_printf(NOTICE, "just started...");
- if(options_parse_post(&opt)) {
- options_clear(&opt);
- log_close();
- exit(-1);
- }
-
- int cmd_fd = connect_command_socket(opt.command_sock_);
- if(cmd_fd < 0) {
- options_clear(&opt);
- log_close();
- exit(-1);
- }
-
- ret = main_loop( cmd_fd, &opt);
-
- close(cmd_fd);
-
- if(!ret)
- log_printf(NOTICE, "normal shutdown");
- else if(ret < 0)
- log_printf(NOTICE, "shutdown after error (code %d)", ret);
- else
- log_printf(NOTICE, "shutdown after signal");
-
- options_clear(&opt);
- log_close();
-
- return ret;
-}
diff --git a/src/string_list.c b/src/string_list.c
deleted file mode 100644
index 870048b..0000000
--- a/src/string_list.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "string_list.h"
-
-void string_list_init(string_list_t* list)
-{
- if(!list)
- return;
-
- list->first_ = NULL;
-}
-
-void string_list_clear(string_list_t* list)
-{
- if(!list)
- return;
-
- while(list->first_) {
- string_list_element_t* tmp;
- tmp = list->first_;
- list->first_ = tmp->next_;
- if(tmp->string_)
- free(tmp->string_);
- free(tmp);
- }
-}
-
-int string_list_add(string_list_t* list, const char* string)
-{
- if(!list)
- return -1;
-
- if(!list->first_) {
- list->first_ = malloc(sizeof(string_list_element_t));
- if(!list->first_)
- return -2;
-
- list->first_->next_ = 0;
- list->first_->string_ = strdup(string);
- if(!list->first_->string_) {
- free(list->first_);
- list->first_ = NULL;
- return -2;
- }
- }
- else {
- string_list_element_t* tmp = list->first_;
- while(tmp->next_)
- tmp = tmp->next_;
-
- tmp->next_ = malloc(sizeof(string_list_element_t));
- if(!tmp->next_)
- return -2;
-
- tmp->next_->next_ = 0;
- tmp->next_->string_ = strdup(string);
- if(!tmp->next_->string_) {
- free(tmp->next_);
- tmp->next_ = NULL;
- return -2;
- }
- }
- return 0;
-}
-
-void string_list_print(string_list_t* list, const char* head, const char* tail)
-{
- if(!list)
- return;
-
- string_list_element_t* tmp = list->first_;
- while(tmp) {
- printf("%s%s%s", head, tmp->string_, tail);
- tmp = tmp->next_;
- }
-}
diff --git a/src/string_list.h b/src/string_list.h
deleted file mode 100644
index 6e415f9..0000000
--- a/src/string_list.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef RHCTL_string_list_h_INCLUDED
-#define RHCTL_string_list_h_INCLUDED
-
-struct string_list_element_struct {
- char* string_;
- struct string_list_element_struct* next_;
-};
-typedef struct string_list_element_struct string_list_element_t;
-
-struct string_list_struct {
- string_list_element_t* first_;
-};
-typedef struct string_list_struct string_list_t;
-
-void string_list_init(string_list_t* list);
-void string_list_clear(string_list_t* list);
-int string_list_add(string_list_t* list, const char* string);
-
-void string_list_print(string_list_t* list, const char* head, const char* tail);
-
-#endif
diff --git a/src/switchctl.c b/src/switchctl.c
deleted file mode 100644
index 4be2313..0000000
--- a/src/switchctl.c
+++ /dev/null
@@ -1,1211 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "datatypes.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include "log.h"
-#include "sig_handler.h"
-#include "options.h"
-
-#include "command_queue.h"
-#include "client_list.h"
-#include "key_value_storage.h"
-
-#include "daemon.h"
-#include "utils.h"
-
-struct state_struct {
- switchctl_mode_t mode_;
- switchctl_channel_t channel_master_;
- switchctl_channel_t channel_standby_;
- bool hb_state_master_;
- bool hb_state_standby_;
-};
-typedef struct state_struct state_t;
-
-state_t state_;
-
-int send_command(int switch_fd, cmd_t* cmd)
-{
- if(!cmd)
- return -1;
-
- char* c = NULL;
- switch(cmd->cmd) {
- case SWITCH:
- case CHANNEL: c = cmd->param; break;
- case STATUS: c = "*0SL"; break;
- default: break;
- }
-
- if(c == NULL)
- return 0;
-
- int ret = send_string(switch_fd, c);
- if(ret > 0) {
- cmd_sent(cmd);
- return 0;
- }
-
- return ret;
-}
-
-int send_response(int fd, const char* response)
-{
- if(!response)
- return -1;
-
- if(fd < 0)
- return 0;
-
- int ret = send_string(fd, response);
- do {
- ret = write(fd, "\n", 1);
- } while(!ret || (ret == -1 && errno == EINTR));
-
- if(ret > 0)
- return 0;
-
- return ret;
-}
-
-void send_usage(int fd)
-{
- if(fd < 0)
- return;
-
- send_response(fd, "Usage: ");
- send_response(fd, " help prints this");
- send_response(fd, " quit close connection");
- send_response(fd, " type set client type, one of: master, standby, hb_master, hb_standby");
- send_response(fd, " channel switch to channel main or music");
- send_response(fd, " client type master and standby only");
- send_response(fd, " mode switch to mode master or standby (add -forced to override heartbeat control)");
- send_response(fd, " heartbeat update heartbeat status for master or standby");
- send_response(fd, " status get actual status from switch");
- send_response(fd, " health get health info");
- send_response(fd, " listen register for events, no parameter for all");
- send_response(fd, " one of: request, mode, status, health, gpi, oc, relay, silence, none");
- send_response(fd, " log add line to daemons log file");
- send_response(fd, " switch send raw commands to the switch");
-}
-
-int process_cmd_request(const char* cmd, cmd_id_t cmd_id, const char* param, int fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt)
-{
- client_t* c = client_find(client_lst, fd);
- if(!c) {
- log_printf(WARNING, "ignoring request from unknown client");
- send_response(fd, "EEE: switch: client not found in client list?!");
- return 0;
- }
-
- char* cmd_param = NULL;
- if(cmd_id == SWITCH) {
- if((state_.mode_ == MODE_MASTER && c->type == STANDBY )||
- (state_.mode_ == MODE_STANDBY && c->type == MASTER ))
- {
- log_printf(INFO, "silently ignoring request from inactive system (%s)", c->type == MASTER ? "master" : "standby");
- return 0;
- }
-
- if(!param) {
- log_printf(INFO, "ignoring switch command without parameter");
- send_response(fd, "EEE: switch: missing parameter");
- return 0;
- }
-
- if(param[0] == '*') {
- cmd_param = strdup(param);
- }
- else {
- const char* ch_name = NULL;
- char* ch_nr = NULL;
- if(!strncmp(param, "up ", 3)) {
- cmd_param = strdup("*0FUii");
- ch_name = &(param[3]);
- ch_nr = &(cmd_param[4]);
- }
- else if(!strncmp(param, "down ", 5)) {
- cmd_param = strdup("*0FDii");
- ch_name = &(param[5]);
- ch_nr = &(cmd_param[4]);
- }
- else if(!strncmp(param, "select ", 7)) {
- cmd_param = strdup("*0ii1");
- ch_name = &(param[7]);
- ch_nr = &(cmd_param[2]);
- }
- else if(!strncmp(param, "add ", 4)) {
- cmd_param = strdup("*0ii3");
- ch_name = &(param[4]);
- ch_nr = &(cmd_param[2]);
- }
- else if(!strncmp(param, "rm ", 3)) {
- cmd_param = strdup("*0ii5");
- ch_name = &(param[3]);
- ch_nr = &(cmd_param[2]);
- }
- else if(!strncmp(param, "mute ", 5)) {
- cmd_param = strdup("*0iiM1");
- ch_name = &(param[5]);
- ch_nr = &(cmd_param[2]);
- }
- else if(!strncmp(param, "select2 ", 8)) {
- cmd_param = strdup("*0ii2");
- ch_name = &(param[8]);
- ch_nr = &(cmd_param[2]);
- }
- else if(!strncmp(param, "add2 ", 5)) {
- cmd_param = strdup("*0ii4");
- ch_name = &(param[5]);
- ch_nr = &(cmd_param[2]);
- }
- else if(!strncmp(param, "rm2 ", 4)) {
- cmd_param = strdup("*0ii6");
- ch_name = &(param[4]);
- ch_nr = &(cmd_param[2]);
- }
- else if(!strncmp(param, "mute2 ", 6)) {
- cmd_param = strdup("*0iiM2");
- ch_name = &(param[6]);
- ch_nr = &(cmd_param[2]);
- }
- else {
- log_printf(INFO, "ignoring invalid switch command: '%s'", param);
- send_response(fd, "EEE: switch: invalid command");
- return 0;
- }
- char* ch_tmp = key_value_storage_find(&opt->alias_table_, ch_name);
- if(!ch_tmp || ch_tmp[0] == 0 || ch_tmp[1] == 0 || ch_tmp[2] != 0) {
- log_printf(ERROR, "invalid channel name or number: %s", ch_name);
- send_response(fd, "EEE: switch: invalid channel name or number");
- free(cmd_param);
- return 0;
- }
-
- ch_nr[0] = ch_tmp[0];
- ch_nr[1] = ch_tmp[1];
- }
- log_printf(DEBUG, "enqueing command to switch: '%s' (request was: '%s')", cmd_param, param);
- }
-
- int ret = cmd_push(cmd_q, fd, cmd_id, cmd_param);
- if(cmd_param)
- free(cmd_param);
- if(ret)
- return ret;
-
- if(cmd_id == STATUS) {
- char buf[3][30];
- snprintf(buf[0], 30, "Current Mode: %s", state_.mode_ == MODE_MASTER ? "Master" : "Standby");
- send_response(fd, buf[0]);
- snprintf(buf[1], 30, "Master Channel: %s", state_.channel_master_ == CHAN_MAIN ? "Main" : "Music");
- send_response(fd, buf[1]);
- snprintf(buf[2], 30, "Standby Channel: %s", state_.channel_standby_ == CHAN_MAIN ? "Main" : "Music");
- send_response(fd, buf[2]);
- client_t* client;
- int listener_cnt = 0;
- for(client = client_lst; client; client = client->next)
- if(client->status_listener && client->fd != fd) {
- send_response(client->fd, buf[0]);
- send_response(client->fd, buf[1]);
- send_response(client->fd, buf[2]);
- listener_cnt++;
- }
- log_printf(DEBUG, "sent status to %d additional listeners", listener_cnt);
- }
-
- log_printf(NOTICE, "command: %s", cmd);
-
- return 0;
-}
-
-int crossfade(const char* ch_from, const char* ch_to, int fd, cmd_t **cmd_q, options_t* opt)
-{
- char* cmd_param = strdup("*0FDii*0FUii");
-
- char* ch_nr_from = key_value_storage_find(&opt->alias_table_, ch_from);
- if(!ch_nr_from || ch_nr_from[0] == 0 || ch_nr_from[1] == 0 || ch_nr_from[2] != 0) {
- log_printf(ERROR, "invalid channel name or number: %s", ch_from);
- send_response(fd, "EEE: channel: invalid channel name or number");
- free(cmd_param);
- return 1;
- }
-
- char* ch_nr_to = key_value_storage_find(&opt->alias_table_, ch_to);
- if(!ch_nr_to || ch_nr_to[0] == 0 || ch_nr_to[1] == 0 || ch_nr_to[2] != 0) {
- log_printf(ERROR, "invalid channel name or number: %s", ch_to);
- send_response(fd, "EEE: channel: invalid channel name or number");
- free(cmd_param);
- return 1;
- }
-
- cmd_param[4] = ch_nr_from[0];
- cmd_param[5] = ch_nr_from[1];
- cmd_param[10] = ch_nr_to[0];
- cmd_param[11] = ch_nr_to[1];
-
- log_printf(DEBUG, "enqueing command to switch: '%s'", cmd_param);
- int ret = cmd_push(cmd_q, fd, CHANNEL, cmd_param);
- free(cmd_param);
-
- return ret;
-}
-
-int process_cmd_channel(const char* cmd, const char* param, int fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt)
-{
- client_t* c = client_find(client_lst, fd);
- if(!c) {
- log_printf(WARNING, "ignoring request from unknown client");
- send_response(fd, "EEE: channel: client not found in client list?!");
- return 0;
- }
-
- if(c->type != MASTER && c->type != STANDBY) {
- log_printf(WARNING, "ignoring request from client of wrong type");
- send_response(fd, "EEE: channel: client type doesn't fit");
- return 0;
- }
-
- if(!param) {
- log_printf(INFO, "ignoring channel command without parameter");
- send_response(fd, "EEE: channel: missing parameter");
- return 0;
- }
-
- switchctl_channel_t old_channel;
- if(c->type == MASTER)
- old_channel = state_.channel_master_;
- else
- old_channel = state_.channel_standby_;
-
- char* ch_from = NULL;
- char* ch_to = NULL;
- if(!strcmp(param, "main")) {
- if(state_.mode_ == MODE_MASTER) {
- ch_from = "master_music";
- ch_to = "master_main";
- }
- else {
- ch_from = "standby_music";
- ch_to = "standby_main";
- }
- if(c->type == MASTER)
- state_.channel_master_ = CHAN_MAIN;
- else
- state_.channel_standby_ = CHAN_MAIN;
- }
- else if(!strcmp(param, "music")) {
- if(state_.mode_ == MODE_MASTER) {
- ch_from = "master_main";
- ch_to = "master_music";
- }
- else {
- ch_from = "standby_main";
- ch_to = "standby_music";
- }
- if(c->type == MASTER)
- state_.channel_master_ = CHAN_MUSIC;
- else
- state_.channel_standby_ = CHAN_MUSIC;
- }
-
- if((state_.mode_ == MODE_MASTER && c->type == STANDBY )||
- (state_.mode_ == MODE_STANDBY && c->type == MASTER ))
- {
- log_printf(INFO, "no crossfade for inactive system (%s), just updated channel info", c->type == MASTER ? "master" : "standby");
- return 0;
- }
-
- int ret = crossfade(ch_from, ch_to, fd, cmd_q, opt);
- if(ret) {
- if(c->type == MASTER)
- state_.channel_master_ = old_channel;
- else
- state_.channel_standby_ = old_channel;
-
- if(ret > 0)
- return 0;
-
- return ret;
- }
-
- log_printf(NOTICE, "command: %s", cmd);
-
- return 0;
-}
-
-int change_mode(switchctl_mode_t old_mode, int fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt)
-{
- char* ch_from = NULL;
- if(old_mode == MODE_MASTER && state_.channel_master_ == CHAN_MAIN)
- ch_from = "master_main";
- else if(old_mode == MODE_MASTER && state_.channel_master_ == CHAN_MUSIC)
- ch_from = "master_music";
- else if(old_mode == MODE_STANDBY && state_.channel_standby_ == CHAN_MAIN)
- ch_from = "standby_main";
- else if(old_mode == MODE_STANDBY && state_.channel_standby_ == CHAN_MUSIC)
- ch_from = "standby_music";
- else {
- state_.mode_ = old_mode;
- log_printf(ERROR, "EEE: mode: old config is illegal?!");
- return 0;
- }
-
- char* ch_to = NULL;
- if(state_.mode_ == MODE_MASTER && state_.channel_master_ == CHAN_MAIN)
- ch_to = "master_main";
- else if(state_.mode_ == MODE_MASTER && state_.channel_master_ == CHAN_MUSIC)
- ch_to = "master_music";
- else if(state_.mode_ == MODE_STANDBY && state_.channel_standby_ == CHAN_MAIN)
- ch_to = "standby_main";
- else if(state_.mode_ == MODE_STANDBY && state_.channel_standby_ == CHAN_MUSIC)
- ch_to = "standby_music";
- else {
- state_.mode_ = old_mode;
- log_printf(ERROR, "EEE: mode: current config is illegal?!");
- return 0;
- }
-
- int ret = crossfade(ch_from, ch_to, fd, cmd_q, opt);
- if(ret) {
- state_.mode_ = old_mode;
- if(ret > 0)
- return 0;
-
- return ret;
- }
-
- char* mode_str;
- int len = asprintf(&mode_str, "new Mode: %s", state_.mode_ == MODE_MASTER ? "master" : "standby");
- if(len > 0) {
- log_printf(NOTICE, "%s", mode_str);
- client_t* client;
- int listener_cnt = 0;
- for(client = client_lst; client; client = client->next)
- if(client->mode_listener && client->fd != fd) {
- send_response(client->fd, mode_str);
- listener_cnt++;
- }
- free(mode_str);
- log_printf(DEBUG, "sent new mode to %d additional listeners", listener_cnt);
- }
-
- return 0;
-}
-
-int process_cmd_mode(const char* param, int fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt)
-{
- switchctl_mode_t old_mode = state_.mode_;
-
- if(param) {
- if(!strncmp(param, "master-forced", 13))
- state_.mode_ = MODE_MASTER;
- else if(!strncmp(param, "master", 6)) {
- if(!state_.hb_state_master_) {
- log_printf(DEBUG, "mode switch to master denied because missing heartbeat", param);
- send_response(fd, "EEE: mode: no heartbeat, use 'mode master-forced' to override");
- return 0;
- }
- state_.mode_ = MODE_MASTER;
- }
- else if(!strncmp(param, "standby-forced", 14))
- state_.mode_ = MODE_STANDBY;
- else if(!strncmp(param, "standby", 7)) {
- if(!state_.hb_state_standby_) {
- log_printf(DEBUG, "mode switch to standby denied because missing heartbeat", param);
- send_response(fd, "EEE: mode: no heartbeat, use 'mode standby-forced' to override");
- return 0;
- }
- state_.mode_ = MODE_STANDBY;
- }
- else {
- log_printf(DEBUG, "unkown mode '%s'", param);
- send_response(fd, "EEE: mode: unknown mode");
- return 0;
- }
-
- // swap master with standby channels only when mode has changed
- if(old_mode != state_.mode_)
- return change_mode(old_mode, fd, cmd_q, client_lst, opt);
- }
- else {
- log_printf(ERROR, "unable to set mode: empty parameter");
- send_response(fd, "EEE: mode: missing parameter");
- }
-
- return 0;
-}
-
-int send_health_status(int fd, client_t* client_lst)
-{
- bool mc, sc, hmc, hsc;
- mc = sc = hmc = hsc = 0;
-
- client_t* client;
- for(client = client_lst; client; client = client->next) {
- switch(client->type) {
- case MASTER: mc=1; break;
- case STANDBY: sc=1; break;
- case HB_MASTER: hmc=1; break;
- case HB_STANDBY: hsc=1; break;
- default: break;
- }
- }
-
- char buf[5][50];
- snprintf(buf[0], 50, "Health: %s", (mc && sc && hmc && hsc && state_.hb_state_master_ && state_.hb_state_standby_) ? "ok" : "error");
- snprintf(buf[1], 50, "Master: %s", (mc) ? "connected" : "offline");
- snprintf(buf[2], 50, "Standby: %s", (sc) ? "connected" : "offline");
- snprintf(buf[3], 50, "Hearbeat Master: %s, %s", (hmc) ? "connected" : "offline", (state_.hb_state_master_) ? "present" : "timeout");
- snprintf(buf[4], 50, "Hearbeat Standby: %s, %s", (hsc) ? "connected" : "offline", (state_.hb_state_standby_) ? "present" : "timeout");
-
- if(fd >= 0) {
- send_response(fd, buf[0]);
- send_response(fd, buf[1]);
- send_response(fd, buf[2]);
- send_response(fd, buf[3]);
- send_response(fd, buf[4]);
- }
-
- int listener_cnt = 0;
- for(client = client_lst; client; client = client->next)
- if(client->health_listener && client->fd != fd) {
- send_response(client->fd, buf[0]);
- send_response(client->fd, buf[1]);
- send_response(client->fd, buf[2]);
- send_response(client->fd, buf[3]);
- send_response(client->fd, buf[4]);
- listener_cnt++;
- }
- log_printf(DEBUG, "sent health info to %d additional listeners", listener_cnt);
- return 0;
-}
-
-int update_health_status(int fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt)
-{
- bool hmc, hsc;
- hmc = hsc = 0;
-
- client_t* client;
- for(client = client_lst; client; client = client->next) {
- switch(client->type) {
- case HB_MASTER: hmc=1; break;
- case HB_STANDBY: hsc=1; break;
- default: break;
- }
- }
-
- if(!hmc) state_.hb_state_master_ = 0;
- if(!hsc) state_.hb_state_standby_ = 0;
-
- switchctl_mode_t old_mode = state_.mode_;
- if(state_.mode_ == MODE_MASTER) {
- if(!state_.hb_state_master_) {
- if(state_.hb_state_standby_) {
- state_.mode_ = MODE_STANDBY;
- return change_mode(old_mode, fd, cmd_q, client_lst, opt);
- }
- }
- } else {
- if(!state_.hb_state_standby_) {
- if(state_.hb_state_master_) {
- state_.mode_ = MODE_MASTER;
- return change_mode(old_mode, fd, cmd_q, client_lst, opt);
- }
- }
- }
-
- send_health_status(fd, client_lst);
-
- return 0;
-}
-
-void process_cmd_type(const char* param, int fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt)
-{
- bool mc, sc, hmc, hsc;
- mc = sc = hmc = hsc = 0;
-
- client_t* client;
- for(client = client_lst; client; client = client->next) {
- switch(client->type) {
- case MASTER: mc=1; break;
- case STANDBY: sc=1; break;
- case HB_MASTER: hmc=1; break;
- case HB_STANDBY: hsc=1; break;
- default: break;
- }
- }
-
- if(param) {
- client_t* client = client_find(client_lst, fd);
- if(client) {
- if(client->type == DEFAULT) {
- if(!strncmp(param, "master", 6)) {
- if(mc) {
- log_printf(DEBUG, "client of type '%s' already connected", param);
- send_response(fd, "EEE: type: already connected");
- return;
- }
- client->type = MASTER;
- client->gpi_listener = 1;
- }
- else if(!strncmp(param, "standby", 7)) {
- if(sc) {
- log_printf(DEBUG, "client of type '%s' already connected", param);
- send_response(fd, "EEE: type: already connected");
- return;
- }
- client->type = STANDBY;
- client->gpi_listener = 1;
- }
- else if(!strncmp(param, "hb_master", 9)) {
- if(hmc) {
- log_printf(DEBUG, "client of type '%s' already connected", param);
- send_response(fd, "EEE: type: already connected");
- return;
- }
- client->type = HB_MASTER;
- }
- else if(!strncmp(param, "hb_standby", 10)) {
- if(hsc) {
- log_printf(DEBUG, "client of type '%s' already connected", param);
- send_response(fd, "EEE: type: already connected");
- return;
- }
- client->type = HB_STANDBY;
- }
- else {
- log_printf(DEBUG, "unkown client type '%s'", param);
- send_response(fd, "EEE: type: unknown client type");
- return;
- }
- log_printf(DEBUG, "client %d type set to %s", fd, param);
- update_health_status(-1, cmd_q, client_lst, opt);
- }
- else {
- log_printf(ERROR, "unable to set client type for %d: type already set to %s", fd, client_type_tostring(client->type));
- send_response(fd, "EEE: type: type already set");
- }
- }
- else {
- log_printf(ERROR, "unable to set client type for %d: client not found", fd);
- send_response(fd, "EEE: type: client not found in client list?!");
- }
- }
- else {
- log_printf(ERROR, "unable to set client type for %d: empty parameter", fd);
- send_response(fd, "EEE: type: missing parameter");
- }
-}
-
-int process_cmd_heartbeat(const char* param, int fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt)
-{
- if(param) {
- client_t* client = client_find(client_lst, fd);
- if(client) {
- switch(client->type) {
- case HB_MASTER: {
- state_.hb_state_master_ = (param[0] == '1') ? TRUE : FALSE;
- break;
- }
- case HB_STANDBY: {
- state_.hb_state_standby_ = (param[0] == '1') ? TRUE : FALSE;
- break;
- }
- default: {
- log_printf(ERROR, "unable to update heartbeat status: wrong client type");
- send_response(fd, "EEE: heartbeat: wrong client type");
- break;
- }
- }
- update_health_status(-1, cmd_q, client_lst, opt);
- }
- else {
- log_printf(ERROR, "unable to update heartbeat status: client not found");
- send_response(fd, "EEE: heartbeat: client not found in client list?!");
- }
- }
- else {
- log_printf(ERROR, "unable to update heartbeat status: empty parameter");
- send_response(fd, "EEE: heartbeat: missing parameter");
- }
- return 0;
-}
-
-int process_cmd_health(const char* param, int fd, client_t* client_lst)
-{
- return send_health_status(fd, client_lst);
-}
-
-void process_cmd_listen(const char* param, int fd, client_t* client_lst)
-{
- client_t* listener = client_find(client_lst, fd);
- if(listener) {
- if(!param) {
- listener->request_listener = 1;
- listener->mode_listener = 1;
- listener->status_listener = 1;
- listener->gpi_listener = 1;
- listener->oc_listener = 1;
- listener->relay_listener = 1;
- listener->silence_listener = 1;
- listener->health_listener = 1;
- }
- else {
- if(!strncmp(param, "request", 7))
- listener->request_listener = 1;
- else if(!strncmp(param, "mode", 6))
- listener->mode_listener = 1;
- else if(!strncmp(param, "status", 6))
- listener->status_listener = 1;
- else if(!strncmp(param, "gpi", 3))
- listener->gpi_listener = 1;
- else if(!strncmp(param, "oc", 2))
- listener->oc_listener = 1;
- else if(!strncmp(param, "relay", 5))
- listener->relay_listener = 1;
- else if(!strncmp(param, "silence", 7))
- listener->silence_listener = 1;
- else if(!strncmp(param, "health", 6))
- listener->health_listener = 1;
- else if(!strncmp(param, "none", 4)) {
- listener->request_listener = 0;
- listener->mode_listener = 0;
- listener->status_listener = 0;
- listener->gpi_listener = 0;
- listener->oc_listener = 0;
- listener->relay_listener = 0;
- listener->silence_listener = 0;
- listener->health_listener = 0;
- }
- else {
- log_printf(DEBUG, "unkown listener type '%s'", param);
- send_response(fd, "EEE: listen: unkown type");
- return;
- }
- }
- log_printf(DEBUG, "listener %d requests %s messages", fd, param ? param:"all");
- }
- else {
- log_printf(ERROR, "unable to add listener %d", fd);
- send_response(fd, "EEE: listen: client not found in client list?!");
- }
-}
-
-int process_cmd(const char* cmd, int fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt)
-{
- log_printf(DEBUG, "processing command from %d", fd);
-
- if(!cmd_q || !cmd)
- return -1;
-
- cmd_id_t cmd_id;
- if(!strncmp(cmd, "switch", 6))
- cmd_id = SWITCH;
- else if(!strncmp(cmd, "channel", 7))
- cmd_id = CHANNEL;
- else if(!strncmp(cmd, "type", 4))
- cmd_id = TYPE;
- else if(!strncmp(cmd, "mode", 4))
- cmd_id = MODE;
- else if(!strncmp(cmd, "heartbeat", 5))
- cmd_id = HEARTBEAT;
- else if(!strncmp(cmd, "status", 6))
- cmd_id = STATUS;
- else if(!strncmp(cmd, "health", 6))
- cmd_id = HEALTH;
- else if(!strncmp(cmd, "log", 3))
- cmd_id = LOG;
- else if(!strncmp(cmd, "listen", 6))
- cmd_id = LISTEN;
- else if(!strncmp(cmd, "quit", 4))
- return 2;
- else {
- if(!strncmp(cmd, "help", 4)) {
- send_usage(fd);
- } else {
- log_printf(WARNING, "unknown command '%s'", cmd);
- send_response(fd, "EEE: unknown command");
- }
- return 0;
- }
- char* param = strchr(cmd, ' ');
- if(param)
- param++;
-
- if(cmd_id == SWITCH || cmd_id == CHANNEL || cmd_id == MODE) {
- char* resp;
- int len = asprintf(&resp, "Request: %s", cmd);
- if(len > 0) {
- char* linefeed = strchr(resp, '\n');
- if(linefeed) linefeed[0] = 0;
- client_t* client;
- int listener_cnt = 0;
- for(client = client_lst; client; client = client->next)
- if(client->request_listener && client->fd != fd) {
- send_response(client->fd, resp);
- listener_cnt++;
- }
- free(resp);
- log_printf(DEBUG, "sent request to %d additional listeners", listener_cnt);
- }
-// else silently ignore memory alloc error
- }
-
- switch(cmd_id) {
- case SWITCH:
- case STATUS: {
- int ret = process_cmd_request(cmd, cmd_id, param, fd, cmd_q, client_lst, opt);
- if(ret)
- return ret;
- break;
- }
- case CHANNEL: {
- int ret = process_cmd_channel(cmd, param, fd, cmd_q, client_lst, opt);
- if(ret)
- return ret;
- break;
- }
- case TYPE: process_cmd_type(param, fd, cmd_q, client_lst, opt); break;
- case MODE: {
- int ret = process_cmd_mode(param, fd, cmd_q, client_lst, opt);
- if(ret)
- return ret;
- break;
- }
- case HEARTBEAT: {
- int ret = process_cmd_heartbeat(param, fd, cmd_q, client_lst, opt);
- if(ret)
- return ret;
- break;
- }
- case HEALTH: {
- int ret = process_cmd_health(param, fd, client_lst);
- if(ret)
- return ret;
- break;
- }
- case LOG: {
- if(param && param[0])
- log_printf(NOTICE, "ext msg: %s", param);
- else
- log_printf(DEBUG, "ignoring empty ext log message");
- break;
- }
- case LISTEN: process_cmd_listen(param, fd, client_lst); break;
- }
-
- return 0;
-}
-
-int nonblock_recvline(read_buffer_t* buffer, int fd, cmd_t** cmd_q, client_t* client_lst, options_t* opt)
-{
- int ret = 0;
- for(;;) {
- ret = recv(fd, &buffer->buf[buffer->offset], 1, 0);
- if(!ret)
- return 2;
- if(ret == -1 && errno == EAGAIN)
- return 0;
- else if(ret < 0)
- break;
-
- if(buffer->buf[buffer->offset] == '\n') {
- buffer->buf[buffer->offset] = 0;
- ret = process_cmd((char *)(buffer->buf), fd, cmd_q, client_lst, opt);
- buffer->offset = 0;
- break;
- }
-
- buffer->offset++;
- if(buffer->offset >= sizeof(buffer->buf)) {
- log_printf(DEBUG, "string too long (fd=%d)", fd);
- buffer->offset = 0;
- return 0;
- }
- }
-
- return ret;
-}
-
-#define SEND_TO_LISTENER(STRING, LEN, FLAG) \
- if(!strncmp((char *)(buffer->buf), STRING, LEN)) { \
- client_t* client; \
- int listener_cnt = 0; \
- for(client = client_lst; client; client = client->next) \
- if(client->FLAG && client->fd != cmd_fd) { \
- send_response(client->fd, (char *)(buffer->buf)); \
- listener_cnt++; \
- } \
- log_printf(DEBUG, "sent message to %d additional listeners", listener_cnt); \
- } \
-
-int process_switch(read_buffer_t* buffer, int switch_fd, cmd_t **cmd_q, client_t* client_lst)
-{
- int ret = 0;
- struct timeval tv;
- fd_set fds;
- FD_ZERO(&fds);
- FD_SET(switch_fd, &fds);
-
- for(;;) {
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- ret = select(switch_fd+1, &fds, NULL, NULL, &tv);
- if(!ret)
- return 0;
- else if(ret < 0)
- return ret;
-
- ret = read(switch_fd, &buffer->buf[buffer->offset], 1);
- if(!ret)
- return 2;
- if(ret == -1 && errno == EAGAIN)
- return 0;
- else if(ret < 0)
- break;
-
- if(buffer->buf[buffer->offset] == '\n') {
- buffer->buf[buffer->offset] = 0;
-
- if(buffer->offset > 0 && buffer->buf[buffer->offset-1] == '\r')
- buffer->buf[buffer->offset-1] = 0;
-
- if(strlen((char *)(buffer->buf))) {
- log_printf(NOTICE, "switch-firmware: '%s'", (char *)(buffer->buf));
-
- int cmd_fd = -1;
- if(cmd_q && (*cmd_q)) {
- cmd_fd = (*cmd_q)->fd;
- send_response(cmd_fd, (char *)(buffer->buf));
- }
-
- SEND_TO_LISTENER("S0L", 3, status_listener);
- SEND_TO_LISTENER("S0P", 3, gpi_listener);
- SEND_TO_LISTENER("S0O", 3, oc_listener);
- SEND_TO_LISTENER("S0R", 3, relay_listener);
- SEND_TO_LISTENER("S0S", 3, silence_listener);
-
- if((!strncmp((char *)(buffer->buf), "RRR", 3)) ||
- (!strncmp((char *)(buffer->buf), "EEE", 3)))
- cmd_pop(cmd_q);
- }
-
- buffer->offset = 0;
- return 0;
- }
-
- buffer->offset++;
- if(buffer->offset >= sizeof(buffer->buf)) {
- log_printf(DEBUG, "string too long (fd=%d)", switch_fd);
- buffer->offset = 0;
- return 0;
- }
- }
-
- return ret;
-}
-
-int main_loop(int switch_fd, int cmd_listen_fd, options_t* opt)
-{
- log_printf(NOTICE, "entering main loop");
-
- fd_set readfds, tmpfds;
- FD_ZERO(&readfds);
- FD_SET(switch_fd, &readfds);
- FD_SET(cmd_listen_fd, &readfds);
- int max_fd = switch_fd > cmd_listen_fd ? switch_fd : cmd_listen_fd;
- cmd_t* cmd_q = NULL;
- client_t* client_lst = NULL;
-
- read_buffer_t switch_buffer;
- switch_buffer.offset = 0;
-
- int sig_fd = signal_init();
- if(sig_fd < 0)
- return -1;
- FD_SET(sig_fd, &readfds);
- max_fd = (max_fd < sig_fd) ? sig_fd : max_fd;
-
- int return_value = 0;
-
- char* channel = "unknown";
- if(state_.mode_ == MODE_MASTER && state_.channel_master_ == CHAN_MAIN) channel = "master_main";
- else if(state_.mode_ == MODE_MASTER && state_.channel_master_ == CHAN_MUSIC) channel = "master_music";
- else if(state_.mode_ == MODE_STANDBY && state_.channel_standby_ == CHAN_MAIN) channel = "standby_main";
- else if(state_.mode_ == MODE_STANDBY && state_.channel_standby_ == CHAN_MUSIC) channel = "standby_music";
-
- char* cmd_param = strdup("*0M1*0ii1");
- char* ch_nr = key_value_storage_find(&opt->alias_table_, channel);
- if(!ch_nr || ch_nr[0] == 0 || ch_nr[1] == 0 || ch_nr[2] != 0) {
- log_printf(ERROR, "invalid channel name or number: %s", channel);
- free(cmd_param);
- return_value = -1;
- }
- else {
- cmd_param[6] = ch_nr[0];
- cmd_param[7] = ch_nr[1];
- return_value = cmd_push(&cmd_q, -1, SWITCH, cmd_param);
- free(cmd_param);
- send_command(switch_fd, cmd_q);
- }
-
- struct timeval timeout;
- while(!return_value) {
- memcpy(&tmpfds, &readfds, sizeof(tmpfds));
-
- timeout.tv_sec = 0;
- timeout.tv_usec = 200000;
- int ret = select(max_fd+1, &tmpfds, NULL, NULL, &timeout);
- if(ret == -1 && errno != EINTR) {
- log_printf(ERROR, "select returned with error: %s", strerror(errno));
- return_value = -1;
- break;
- }
- if(ret == -1)
- continue;
- if(!ret) {
- if(cmd_q && cmd_has_expired(*cmd_q)) {
- log_printf(ERROR, "last command expired");
- cmd_pop(&cmd_q);
- }
- else
- continue;
- }
-
- if(FD_ISSET(sig_fd, &tmpfds)) {
- if(signal_handle()) {
- return_value = 1;
- break;
- }
- }
-
- if(FD_ISSET(switch_fd, &tmpfds)) {
- return_value = process_switch(&switch_buffer, switch_fd, &cmd_q, client_lst);
- if(return_value)
- break;
- }
-
- if(FD_ISSET(cmd_listen_fd, &tmpfds)) {
- int new_fd = accept(cmd_listen_fd, NULL, NULL);
- if(new_fd < 0) {
- log_printf(ERROR, "accept returned with error: %s", strerror(errno));
- return_value = -1;
- break;
- }
- log_printf(DEBUG, "new command connection (fd=%d)", new_fd);
- FD_SET(new_fd, &readfds);
- max_fd = (max_fd < new_fd) ? new_fd : max_fd;
- fcntl(new_fd, F_SETFL, O_NONBLOCK);
- client_add(&client_lst, new_fd);
- }
-
- client_t* lst = client_lst;
- while(lst) {
- if(FD_ISSET(lst->fd, &tmpfds)) {
- return_value = nonblock_recvline(&(lst->buffer), lst->fd, &cmd_q, client_lst, opt);
- if(return_value == 2) {
- log_printf(DEBUG, "removing closed command connection (fd=%d)", lst->fd);
- client_t* deletee = lst;
- lst = lst->next;
- FD_CLR(deletee->fd, &readfds);
- client_remove(&client_lst, deletee->fd);
- update_health_status(-1, &cmd_q, client_lst, opt);
- return_value = 0;
- continue;
- }
- if(return_value)
- break;
-
- }
- if(lst)
- lst = lst->next;
- }
-
- if(cmd_q && !cmd_q->sent)
- send_command(switch_fd, cmd_q);
- }
-
- cmd_clear(&cmd_q);
- client_clear(&client_lst);
- signal_stop();
- return return_value;
-}
-
-int main(int argc, char* argv[])
-{
- log_init();
-
- options_t opt;
- int ret = options_parse(&opt, argc, argv);
- if(ret) {
- if(ret > 0) {
- fprintf(stderr, "syntax error near: %s\n\n", argv[ret]);
- }
- if(ret == -2) {
- fprintf(stderr, "memory error on options_parse, exiting\n");
- }
- if(ret == -3) {
- fprintf(stderr, "syntax error: mode name must be either master or standby\n");
- }
- if(ret == -4) {
- fprintf(stderr, "syntax error: channel name must be either main or music\n");
- }
- if(ret == -5) {
- fprintf(stderr, "syntax error: invalid baudrate\n");
- }
-
- if(ret != -2)
- options_print_usage();
-
- options_clear(&opt);
- log_close();
- exit(ret);
- }
- string_list_element_t* tmp = opt.log_targets_.first_;
- if(!tmp) {
- log_add_target("syslog:3,switchctl,daemon");
- }
- else {
- while(tmp) {
- ret = log_add_target(tmp->string_);
- if(ret) {
- switch(ret) {
- case -2: fprintf(stderr, "memory error on log_add_target, exitting\n"); break;
- case -3: fprintf(stderr, "unknown log target: '%s', exitting\n", tmp->string_); break;
- case -4: fprintf(stderr, "this log target is only allowed once: '%s', exitting\n", tmp->string_); break;
- default: fprintf(stderr, "syntax error near: '%s', exitting\n", tmp->string_); break;
- }
-
- options_clear(&opt);
- log_close();
- exit(ret);
- }
- tmp = tmp->next_;
- }
- }
- log_printf(NOTICE, "just started...");
- if(options_parse_post(&opt)) {
- options_clear(&opt);
- log_close();
- exit(-1);
- }
-
- priv_info_t priv;
- if(opt.username_)
- if(priv_init(&priv, opt.username_, opt.groupname_)) {
- options_clear(&opt);
- log_close();
- exit(-1);
- }
-
- FILE* pid_file = NULL;
- if(opt.pid_file_) {
- pid_file = fopen(opt.pid_file_, "w");
- if(!pid_file) {
- log_printf(WARNING, "unable to open pid file: %s", strerror(errno));
- }
- }
-
- if(opt.chroot_dir_)
- if(do_chroot(opt.chroot_dir_)) {
- options_clear(&opt);
- log_close();
- exit(-1);
- }
- if(opt.username_)
- if(priv_drop(&priv)) {
- options_clear(&opt);
- log_close();
- exit(-1);
- }
-
- if(opt.daemonize_) {
- pid_t oldpid = getpid();
- daemonize();
- log_printf(INFO, "running in background now (old pid: %d)", oldpid);
- }
-
- if(pid_file) {
- pid_t pid = getpid();
- fprintf(pid_file, "%d", pid);
- fclose(pid_file);
- }
-
- int cmd_listen_fd = init_command_socket(opt.command_sock_);
- if(cmd_listen_fd < 0) {
- options_clear(&opt);
- log_close();
- exit(-1);
- }
-
- state_.mode_ = opt.mode_;
- state_.channel_master_ = opt.channel_master_;
- state_.channel_standby_ = opt.channel_standby_;
- state_.hb_state_master_ = FALSE;
- state_.hb_state_standby_ = FALSE;
-
- int switch_fd = 0;
- for(;;) {
- switch_fd = open(opt.switch_dev_, O_RDWR | O_NOCTTY);
- if(switch_fd < 0) {
- log_printf(ERROR, "open(%s): %s", opt.switch_dev_, strerror(errno));
- ret = 2;
- } else {
- ret = setup_tty(switch_fd, opt.baudrate_);
- if(ret)
- ret = 2;
- else
- ret = main_loop(switch_fd, cmd_listen_fd, &opt);
- }
-
- if(ret == 2) {
- log_printf(ERROR, "%s error, trying to reopen in 5 seconds..", opt.switch_dev_);
- if(switch_fd > 0)
- close(switch_fd);
- sleep(5);
- }
- else
- break;
- }
-
- close(cmd_listen_fd);
- if(switch_fd > 0)
- close(switch_fd);
-
- if(!ret)
- log_printf(NOTICE, "normal shutdown");
- else if(ret < 0)
- log_printf(NOTICE, "shutdown after error (code %d)", ret);
- else
- log_printf(NOTICE, "shutdown after signal");
-
- options_clear(&opt);
- log_close();
-
- return ret;
-}
diff --git a/src/utils.c b/src/utils.c
deleted file mode 100644
index 99a609b..0000000
--- a/src/utils.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "datatypes.h"
-
-#include <sys/un.h>
-#include <termios.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include "log.h"
-
-#include "utils.h"
-
-int init_command_socket(const char* path)
-{
- int fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if(fd < 0) {
- log_printf(ERROR, "unable to open socket: %s", strerror(errno));
- return -1;
- }
-
- struct sockaddr_un local;
- local.sun_family = AF_UNIX;
- if(sizeof(local.sun_path) <= strlen(path)) {
- log_printf(ERROR, "socket path is to long (max %d)", sizeof(local.sun_path)-1);
- return -1;
- }
- strcpy(local.sun_path, path);
- unlink(local.sun_path);
- int len = SUN_LEN(&local);
- int ret = bind(fd, (struct sockaddr*)&local, len);
- if(ret) {
- log_printf(ERROR, "unable to bind to '%s': %s", local.sun_path, strerror(errno));
- return -1;
- }
-
- ret = listen(fd, 4);
- if(ret) {
- log_printf(ERROR, "unable to listen on command socket: %s", local.sun_path, strerror(errno));
- return -1;
- }
-
- log_printf(INFO, "now listening on %s for incoming commands", path);
-
- return fd;
-}
-
-int connect_command_socket(const char* path)
-{
- int fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if(fd < 0) {
- log_printf(ERROR, "unable to open socket: %s", strerror(errno));
- return -1;
- }
-
- struct sockaddr_un remote;
- remote.sun_family = AF_UNIX;
- if(sizeof(remote.sun_path) <= strlen(path)) {
- log_printf(ERROR, "socket path is to long (max %d)", sizeof(remote.sun_path)-1);
- return -1;
- }
- strcpy(remote.sun_path, path);
- int len = SUN_LEN(&remote);
- int ret = connect(fd, (struct sockaddr*)&remote, len);
- if(ret) {
- log_printf(ERROR, "unable to connect to '%s': %s", remote.sun_path, strerror(errno));
- return -1;
- }
-
- return fd;
-}
-
-int send_string(int fd, const char* string)
-{
- int len = strlen(string);
- int offset = 0;
- int ret;
- for(;;) {
- ret = write(fd, &string[offset], len - offset);
- if(ret < 0) {
- if(errno != EINTR)
- return ret;
-
- ret = 0;
- }
-
- offset += ret;
- if(offset+1 >= len)
- break;
- }
- return ret;
-}
-
-int setup_tty(int fd, speed_t speed)
-{
- struct termios tmio;
-
- int ret = tcgetattr(fd, &tmio);
- if(ret) {
- log_printf(ERROR, "Error on tcgetattr(): %s", strerror(errno));
- return ret;
- }
-
- tmio.c_iflag &= ~(INLCR | ICRNL | IGNCR | IXON | IXOFF);
- tmio.c_oflag &= ~(ONLCR | OCRNL | ONOCR | ONLRET);
- tmio.c_cflag |= CS8 | CLOCAL | CREAD;
- tmio.c_cflag &= ~(CSTOPB | PARENB);
- tmio.c_lflag &= ~(ICANON | ECHO);
- tmio.c_cc[VTIME] = 0;
- tmio.c_cc[VMIN] = 1;
-
- ret = cfsetospeed(&tmio, speed);
- if(ret) {
- log_printf(ERROR, "Error on cfsetospeed(): %s", strerror(errno));
- return ret;
- }
-
- ret = cfsetispeed(&tmio, speed);
- if(ret) {
- log_printf(ERROR, "Error on cfsetispeed(): %s", strerror(errno));
- return ret;
- }
-
- ret = tcsetattr(fd, TCSANOW, &tmio);
- if(ret) {
- log_printf(ERROR, "Error on tcsetattr(): %s", strerror(errno));
- return ret;
- }
-
- ret = tcflush(fd, TCIFLUSH);
- if(ret) {
- log_printf(ERROR, "Error on tcflush(): %s", strerror(errno));
- return ret;
- }
-
- fd_set fds;
- struct timeval tv;
- FD_ZERO(&fds);
- FD_SET(fd, &fds);
- tv.tv_sec = 0;
- tv.tv_usec = 50000;
- for(;;) {
- ret = select(fd+1, &fds, NULL, NULL, &tv);
- if(ret > 0) {
- char buffer[100];
- ret = read(fd, buffer, sizeof(buffer));
- }
- else
- break;
- }
-
- return 0;
-}
diff --git a/src/utils.h b/src/utils.h
deleted file mode 100644
index 5b86b90..0000000
--- a/src/utils.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * rhctl
- *
- * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
- *
- * This file is part of rhctl.
- *
- * rhctl 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
- * any later version.
- *
- * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef RHCTL_utils_h_INCLUDED
-#define RHCTL_utils_h_INCLUDED
-
-#include "command_queue.h"
-#include "client_list.h"
-#include "options.h"
-#include <termios.h>
-
-int init_command_socket(const char* path);
-int connect_command_socket(const char* path);
-int send_string(int fd, const char* string);
-int setup_tty(int fd, speed_t speed);
-
-#endif
diff --git a/src/utils.lua b/src/utils.lua
deleted file mode 100644
index 0fb7377..0000000
--- a/src/utils.lua
+++ /dev/null
@@ -1,35 +0,0 @@
---
--- rhctl
---
--- Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at>
---
--- This file is part of rhctl.
---
--- rhctl 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
--- any later version.
---
--- rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
---
-
-local utils = {}
-
-function utils.send_mail(address, subject, bodytext)
- local fp = assert(io.popen("/usr/bin/msmtp " .. address, "w"))
-
- fp:write("Subject: " .. subject .. "\n")
- fp:write("To: " .. address .. "\n")
- fp:write("\n")
- fp:write(bodytext)
- fp:write("\n")
- fp:close()
-end
-
-return utils