summaryrefslogtreecommitdiff
path: root/src/heartbeatclient.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/heartbeatclient.c')
-rw-r--r--src/heartbeatclient.c428
1 files changed, 0 insertions, 428 deletions
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;
-}