summaryrefslogtreecommitdiff
path: root/support/dktools/rshdown.ctr
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2020-10-12 03:04:00 +0000
committerNorbert Preining <norbert@preining.info>2020-10-12 03:04:00 +0000
commit0ce40abb18ec02ec6fd6bcc5f21612c88daa7578 (patch)
tree416289fe1448873fd8ca33051f50ad85bffa8aaa /support/dktools/rshdown.ctr
parentfdb18507cd80dc17f5a5256153d34668b4f4e61c (diff)
CTAN sync 202010120303
Diffstat (limited to 'support/dktools/rshdown.ctr')
-rw-r--r--support/dktools/rshdown.ctr2408
1 files changed, 0 insertions, 2408 deletions
diff --git a/support/dktools/rshdown.ctr b/support/dktools/rshdown.ctr
deleted file mode 100644
index b6c4c0f4a8..0000000000
--- a/support/dktools/rshdown.ctr
+++ /dev/null
@@ -1,2408 +0,0 @@
-%% options
-
-copyright owner = Dirk Krause
-copyright year = 2016-xxxx
-SPDX-License-Identifier: BSD-3-Clause
-
-
-%% module
-
-/*
- rshdown -s [-n _number_] [-l _port_] [-b] _address_ _port_ _file_
- rshdown [-c _configfile_]
-
- Either send shutdown packages (-s option used)
- or run as daemon in background (no -s option)
- and wait for shutdown packages.
-
- Sending:
-
- -n _number_ Number of packages to send
-
- -l _port_ Local port number to use
- Default: Same as remote port
-
- -b Flag: Destination address is a broadcast address
-
- _address_ Destination address (hostname or IP address)
-
- _port_ Port number on destination host
-
- _file_ File containing data to send
-
- Daemon:
-
- -c _configfile_ Configuration file.
-
-*/
-
-
-#include "dk4conf.h"
-#include "dk4types.h"
-
-
-#include <stdio.h>
-
-#if DK4_HAVE_UNISTD_H
-#ifndef UNISTD_H_INCLUDED
-#include <unistd.h>
-#define UNISTD_H_INCLUDED 1
-#endif
-#endif
-
-#if DK4_HAVE_STDLIB_H
-#ifndef STDLIB_H_INCLUDED
-#include <stdlib.h>
-#define STDLIB_H_INCLUDED 1
-#endif
-#endif
-
-#if (DK4_CHAR_SIZE == 1) \
- && (DK4_HAVE_SIGACTION || DK4_HAVE_SIGSET) \
- && (DK4_HAVE_SETSID || DK4_HAVE_SETPGRP)
-
-#if DK4_HAVE_MATH_H
-#ifndef MATH_H_INCLUDED
-#if DK4_ON_WINDOWS
-#ifndef _USE_MATH_DEFINES
-#define _USE_MATH_DEFINES 1
-#endif
-#endif
-#include <math.h>
-#define MATH_H_INCLUDED 1
-#endif
-#endif
-
-#if DK4_HAVE_IO_H
-#ifndef IO_H_INCLUDED
-#include <io.h>
-#define IO_H_INCLUDED 1
-#endif
-#endif
-
-#if DK4_HAVE_FCNTL_H
-#ifndef FCNTL_H_INCLUDED
-#include <fcntl.h>
-#define FCNTL_H_INCLUDED 1
-#endif
-#endif
-
-#if DK4_HAVE_STRING_H
-#ifndef STRING_H_INCLUDED
-#include <string.h>
-#define STRING_H_INCLUDED 1
-#endif
-#endif
-
-#if DK4_HAVE_SYS_TYPES_H
-#ifndef SYS_TYPES_H_INCLUDED
-#include <sys/types.h>
-#define SYS_TYPES_H_INCLUDED 1
-#endif
-#endif
-
-#if DK4_HAVE_SIGNAL_H
-#ifndef SIGNAL_H_INCLUDED
-#include <signal.h>
-#define SIGNAL_H_INCLUDED 1
-#endif
-#endif
-
-#if DK4_HAVE_SYSLOG_H
-#ifndef SYSLOG_H_INCLUDED
-#include <syslog.h>
-#define SYSLOG_H_INCLUDED 1
-#endif
-#endif
-
-#if DK4_HAVE_SYSEXITS_H
-#ifndef SYSEXITS_H_INCLUDED
-#include <sysexits.h>
-#define SYSEXITS_H_INCLUDED 1
-#endif
-#endif
-
-#include "dk4mem.h"
-#include "dk4memrs.h"
-#include "dk4opt.h"
-#include "dk4mai8dus.h"
-#include "dk4mai8dii.h"
-#include "dk4fopt.h"
-#include "dk4fopc8.h"
-#include "dk4isadm.h"
-#include "dk4sock.h"
-#include "dk4inst.h"
-#include "dk4str8.h"
-#include "dk4mpl.h"
-#include "dk4dmt.h"
-#include "dk4vers.h"
-#include "dk4unused.h"
-
-
-
-$!trace-include
-
-
-
-#ifndef RSHDOWN_BUFFER_SIZE
-/** Buffer size, should not exceed UDP packet size.
-*/
-#define RSHDOWN_BUFFER_SIZE 1460
-#endif
-
-
-
-/** Path name of data file.
-*/
-static char file_name[DK4_MAX_PATH];
-
-
-
-/** Send and receive buffer.
-*/
-static char b1[RSHDOWN_BUFFER_SIZE];
-
-
-/** Buffer for local secret from file in daemon.
-*/
-static char b2[sizeof(b1)];
-
-
-/** Command to execute on packet arrival.
-*/
-static char cmd[1024];
-
-
-/** Allowed sender peer as text.
-*/
-static char asender[1024];
-
-
-/** Options used by the program.
-*/
-static dk4_option_t options[] = {
-
- /* 0 Configuration file.
- */
- { { dkT('c'), dkT("config"), DK4_OPT_ARG_STRING }, { NULL }, 0 },
-
- /* 1 Send data.
- */
- { { dkT('s'), dkT("send"), DK4_OPT_ARG_NONE }, { NULL }, 0 },
-
- /* 2 Destination address is a broadcast address.
- */
- { { dkT('b'), dkT("broadcast"), DK4_OPT_ARG_NONE }, { NULL }, 0 },
-
- /* 3 Number of packets to send.
- */
- { { dkT('n'), dkT("number"), DK4_OPT_ARG_UNSIGNED}, { NULL }, 0 },
-
- /* 4 Local port number.
- */
- { { dkT('l'), dkT("local"), DK4_OPT_ARG_UNSIGNED}, { NULL }, 0},
-
- /* 5 Help.
- */
- { { dkT('\0'),dkT("help"), DK4_OPT_ARG_NONE}, { NULL }, 0},
-
- /* 6 Version.
- */
- { { dkT('\0'),dkT("version"), DK4_OPT_ARG_NONE}, { NULL }, 0},
-
- /* 7 License
- */
- { { dkT('\0'),dkT("license"), DK4_OPT_ARG_NONE}, { NULL }, 0}
-};
-
-
-
-/** Help text.
-*/
-static const char * const help_text[] = {
-$!text
-
-Remote shutdown sender and recipient
-
-rshdown [-c config]
-rshdown -s [-n number] [-l port] [-b] host port file
-
--c config Configuration file for recipient (daemon).
-
--s Send shutdown data packet.
--n number Send packet multiple times.
--l port Local port to use for sending.
--b Prepare socket for broadcast sending.
-host Remote host (recipient), host name or IP address.
- Option -b is required if you specify a broadcast
- address like 255.255.255.255 or 192.0.2.255 here.
-port Remote port.
-file File containing pre-shared secret (shutdown data).
-
---help Show this help text.
---version Show version number.
---license Show license information.
-
-$!end
-};
-
-
-
-/** License conditions text.
-*/
-static const char * const license_text[] = {
-$!text preprocessor
-
-This software uses code from the following projects, either directly or as
-a library:
-
-dktools Dirk Krause's tools and libraries.
- See http://sourceforge.net/p/dktools/wiki/Home/
- for more information.
-
-DK tools and libraries license
-==============================
-Copyright (c) 2015-2016, Dirk Krause
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the copyright holder nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
-$!end
-};
-
-
-
-/** Version information.
-*/
-static const char version_text[] = { DKT_VERSION_C8 };
-
-
-
-/** Default configuration file name.
-*/
-static const char def_conf_name[] = {
- DK4_INST_DIR_ETC "/rshdown/rshdown.conf"
-};
-
-
-
-/** PID file name.
-*/
-static const char pid_file_name[] = {
- DK4_INST_DIR_SYSTEMD_RUN "/rshdown/rshdown.pid"
-};
-
-
-
-/** Key names expected in configuration file.
-*/
-static const char * const key_names[] = {
-$!string-table
-#
-# 0
-#
-sender
-#
-# 1
-#
-sender port
-#
-# 2
-#
-receiver port
-#
-# 3
-#
-signal
-#
-# 4
-#
-command
-#
-# 5
-#
-file
-#
-# 6
-#
-debug
-#
-# 7
-#
-syslog facility
-$!end
-};
-
-
-
-/** Signal names.
-*/
-static const char * const signal_names[] = {
-$!string-table
-# 0 1
-sighup
-hup
-# 2 3
-sigint
-int
-# 4 5
-sigquit
-quit
-# 6 7
-sigill
-ill
-# 8 9
-sigtrap
-trap
-# 10 11
-sigabrt
-abrt
-# 12 13
-sigiot
-iot
-# 14 15
-sigbus
-bus
-# 16 17
-sigfpe
-fpe
-# 18 19
-sigkill
-kill
-# 20 21
-sigusr1
-usr1
-# 22 23
-sigsegv
-segv
-# 24 25
-sigusr2
-usr2
-# 26 27
-sigpipe
-pipe
-# 28 29
-sigalrm
-alrm
-# 30 31
-sigterm
-term
-# 32 33
-sigstkflt
-stkflt
-# 34 35 36 37
-sigcld
-cld
-sigchld
-chld
-# 38 39
-sigcont
-cont
-# 40 41
-sigstop
-stop
-# 42 43
-sigtstp
-tstp
-# 44 45
-sigttin
-ttin
-# 46 47
-sigttou
-ttou
-# 48 49
-sigurg
-urg
-# 50 51
-sigxcpu
-xcpu
-# 52 53
-sigxfsz
-xfsz
-# 54 55
-sigvtalrm
-vtalrm
-# 56 57
-sigprof
-prof
-# 58 59
-sigwinch
-winch
-# 60 61
-sigpoll
-poll
-# 62 63
-sigio
-io
-# 64 65
-sigpwr
-pwr
-# 66 67
-sigsys
-sys
-$!end
-};
-
-
-
-/** Syslog facility names.
-*/
-static const char * const syslog_facility_names[] = {
-$!string-table
-auth
-authpriv
-cron
-daemon
-ftp
-kern
-lpr
-mail
-news
-security
-syslog
-user
-uucp
-local0
-local1
-local2
-local3
-local4
-local5
-local6
-local7
-$!end
-};
-
-
-/** Texts used by the program, not localized.
-*/
-static const char * const rshdown_kw[] = {
-$!string-table
-#
-# 0 Program name
-#
-rshdown
-#
-# 1
-#
-:
-#
-# 2
-#
-ERROR: Failed to set broadcast mode on socket!\n
-#
-# 3
-#
-ERROR: Failed to bind local address!\n
-#
-# 4 5
-#
-ERROR: Failed to bind local address: "
-"!\n
-#
-# 6
-#
-ERROR: Failed to create socket!\n
-#
-# 7 8
-#
-ERROR: Failed to find address for: "
-"!\n
-#
-# 9
-#
-ERROR: Failed to bring socket subsystem up!\n
-#
-# 10
-#
-ERROR: 3 arguments required: host, port and file!\n
-#
-# 11 12
-#
-ERROR: Not a 16 bit unsigned integer: "
-"!\n
-#
-# 13
-#
-ERROR: Port number 0 is not allowed!\n
-#
-# 14 15
-#
-ERROR: Failed to open data file:\n"
-"!\n
-#
-# 16 17
-#
-ERROR: Failed to read data from file:\n"
-"!\n
-#
-# 18
-#
-ERROR: Failed to install signal handlers!\n
-#
-# 19
-#
-ERROR: Failed to restore signal handlers!\n
-#
-# 20
-#
-ERROR: Failed to create child process!\n
-#
-# 21
-#
-Failed to detach from terminal!
-#
-# 22
-#
-Failed to create child process!
-#
-# 23 24
-#
-Failed to install signal handlers!
-Failed to restore signal handlers!
-#
-# 25
-#
-Failed to bring socket subsystem up!
-#
-# 26
-#
-Failed to create UDP socket set!
-#
-# 27 28
-#
-ERROR: Local port number too large!\n
-ERROR: Local port number must not be 0!\n
-#
-# 29 30
-#
-Failed to set allowed peer: "
-"!
-#
-# 31 32
-#
-ERROR: Illegal signal name: "
-"!\n
-#
-# 33 34
-#
-ERROR: Sender name too long:\n
-"!\n
-#
-# 35
-#
-ERROR: Sender name defined multiple times!\n
-#
-# 36
-#
-ERROR: Signal number must be positive!\n
-#
-# 37 38
-#
-ERROR: Command too long:\n"
-"!\n
-#
-# 39
-#
-ERROR: Command defined multiple times!\n
-#
-# 40 41
-#
-ERROR: File name too long:\n"
-"!\n
-#
-# 42
-#
-ERROR: File name defined multiple times!\n
-#
-# 43
-#
-ERROR: Unknown key in configuration file!\n
-#
-# 44
-#
-ERROR: Missing value on configuration line!\n
-#
-# 45
-#
-ERROR: No local port specified!\n
-#
-# 46
-#
-ERROR: Signal number or command required!\n
-#
-# 47
-#
-ERROR: No data file specified!\n
-#
-# 48 49
-#
-ERROR: Illegal syslog facility: "
-"!\n
-#
-# 50
-#
-Service started.
-#
-# 51
-#
-Initiate shutdown.
-#
-# 52
-#
-Service finished.
-#
-# 53 54
-#
-Packet from "
-" discarded, wrong sender address!
-#
-# 55 56
-#
-Packet from "
-" discarded, wrong sender port!
-#
-# 57 58
-#
-Packet from "
-" discarded, size mismatch!
-#
-# 59 60
-#
-Packet from "
-" discarded, data mismatch!
-#
-# 61 62
-#
-Failed to execute command: "
-"!
-$!end
-};
-
-
-/** Information for daemon tool functions.
-*/
-static dk4dmt_t dmt;
-
-
-/** Number of options in the options array.
-*/
-static const size_t szoptions = sizeof(options)/sizeof(dk4_option_t);
-
-
-
-/** Number of bytes in buffer b1.
-*/
-static size_t szb1 = 0;
-
-
-
-/** Number of bytes in buffer b2.
-*/
-static size_t szb2 = 0;
-
-
-
-/** Exit status code.
-*/
-static int exval = EXIT_FAILURE;
-
-
-
-/** Options: Help (1), version (2), license (4).
-*/
-static int hvl = 0;
-
-
-
-/** Flag: Additional debug messages.
-*/
-static int debug = 0;
-
-
-
-#ifdef LOG_DAEMON
-/** Syslog facility.
-*/
-static int syslogf = LOG_AUTH;
-#else
-/** Syslog facility.
-*/
-static int syslogf = (3<<3);
-#endif
-
-
-
-/** Signal to send on arrival of shutdown data packet.
-*/
-static int signo =
-#ifdef SIGPWR
-SIGPWR
-#else
-#ifdef SIGTERM
-SIGTERM
-#else
-15
-#endif
-#endif
-;
-
-
-
-#ifdef SIGPIPE
-/** Indicator: SIGPIPE signal received.
-*/
-static
-DK4_VOLATILE
-dk4_sig_atomic_t sig_had_pipe = 0;
-#endif
-
-
-/** Indicator: SIGINT signal received.
-*/
-static
-DK4_VOLATILE
-dk4_sig_atomic_t sig_had_int = 0;
-
-
-/** Indicator: SIGTERM signal received.
-*/
-static
-DK4_VOLATILE
-dk4_sig_atomic_t sig_had_term = 0;
-
-
-
-/** Remote port.
-*/
-static unsigned short rp = 0U;
-
-
-
-/** Local port.
-*/
-static unsigned short lp = 0U;
-
-
-/** Pass pointer through.
- Use of this function is recommended by CERT C coding standard
- to avoid optimizing out.
- @param ptr Pointer to pass through.
- @return The ptr argument.
-*/
-static
-DK4_VOLATILE
-dk4_sig_atomic_t *
-sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
-{
- return ptr;
-}
-
-
-#ifdef SIGPIPE
-/** Handler for SIGPIPE signal.
- @param signo Signal number (always SIGPIPE, ignored).
-*/
-static
-void
-sig_handler_pipe(int DK4_ARG_UNUSED(signo) )
-{
- DK4_UNUSED_ARG(signo)
- *sig_pass_pointer(&sig_had_pipe) = 1;
-}
-#endif
-
-
-/** Handler for SIGINT signal.
- @param signo Signal number (always SIGINT, ignored).
-*/
-static
-void
-sig_handler_int(int DK4_ARG_UNUSED(signo) )
-{
- DK4_UNUSED_ARG(signo)
- *sig_pass_pointer(&sig_had_int) = 1;
-}
-
-
-/** Handler for SIGTERM signal.
- @param signo Signal number (always SIGTERM, ignored).
-*/
-static
-void
-sig_handler_term(int DK4_ARG_UNUSED(signo) )
-{
- DK4_UNUSED_ARG(signo)
- *sig_pass_pointer(&sig_had_term) = 1;
-}
-
-
-/** Read value from volatile atomic type.
- This function is necessary as some compilers mis-optimize
- direct access to volatile variables (at least if you believe
- one of the coding standards).
- @param ap Pointer to volatile atomic variable.
- @return Contents of the variable.
-*/
-static
-dk4_sig_atomic_t
-sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
-{
- return (*ap);
-}
-
-
-/** Check whether we can continue or must abort due to signal.
- @param dopipe Flag: Check for SIGPIPE too.
- @return 1 if we can continue, 0 otherwise.
-*/
-static
-int
-can_continue(void)
-{
- int back = 1;
- if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
- if (0 != sig_read_atomic(&sig_had_int)) { back = 0; }
- return back;
-}
-
-
-
-/** Write log message to stderr, 1 component.
- @param i Text index in rshdown_kw array.
-*/
-static
-void
-log_1(size_t i)
-{
- fputs(rshdown_kw[0], stderr);
- fputs(rshdown_kw[1], stderr);
- fputs(rshdown_kw[i], stderr);
- fflush(stderr);
-}
-
-
-
-/** Write syslog message, 1 component.
- @param i Index of text in rshdown_kw array.
-*/
-static
-void
-syslog_1(size_t i)
-{
-#if DK4_HAVE_SYSLOG
- openlog(rshdown_kw[0], LOG_PID, syslogf);
- syslog(LOG_ERR, "%s", rshdown_kw[i]);
- closelog();
-#endif
-}
-
-
-
-/** Write syslog message, 3 components.
- @param i1 Index of first component in rshdown_kw array.
- @param i2 Index of third component in rshdown_kw array.
- @param str Second component.
-*/
-static
-void
-syslog_3(size_t i1, size_t i2, const char *str)
-{
-#if DK4_HAVE_SYSLOG
- openlog(rshdown_kw[0], LOG_PID, syslogf);
- if (NULL != str) {
- syslog(LOG_ERR, "%s%s%s", rshdown_kw[i1], str, rshdown_kw[i2]);
- } else {
- syslog(LOG_ERR, "%s%s", rshdown_kw[i1], rshdown_kw[i2]);
- }
- closelog();
-#endif
-}
-
-
-
-/** Write an additional debug message to syslog.
- @param i1 Index of first component in rshdown_kw array.
- @param i2 Index of third component in rshdown_kw array.
- @param sa Socket address, second component.
-*/
-static
-void
-syslog_debug(size_t i1, size_t i2, dk4_sockaddr_storage_t *sa)
-{
-#if DK4_HAVE_SYSLOG
- char buf[128]; /* Buffer for text respresentation of address */
- int res; /* Operation result from conversion */
-
- if (0 != debug) {
- res = dk4socket_c8_sockaddr_to_text(buf, sizeof(buf), sa, NULL);
- openlog(rshdown_kw[0], LOG_PID, syslogf);
- if (DK4_SOCKET_RESULT_SUCCESS == res) {
- syslog(LOG_DEBUG, "%s%s%s", rshdown_kw[i1], buf, rshdown_kw[i2]);
- } else {
- syslog(LOG_DEBUG, "%s%s", rshdown_kw[i1], rshdown_kw[i2]);
- }
- closelog();
- }
-#endif
-}
-
-
-
-/** Write log message to stderr, 3 components.
- @param i1 Index of first component in rshdown_kw array.
- @param i2 Index of third component in rshdown_kw array.
- @param str Second component.
-*/
-static
-void
-log_3(size_t i1, size_t i2, const char *str)
-{
- fputs(rshdown_kw[0], stderr);
- fputs(rshdown_kw[1], stderr);
- fputs(rshdown_kw[i1], stderr);
- if (NULL != str) { fputs(str, stderr); }
- fputs(rshdown_kw[i2], stderr);
- fflush(stderr);
-}
-
-
-
-/** Send buffer over network.
- @param hn Remote host name or IP address as text.
- @param rp Remote port in host representation.
- @param lp Local port in host representation.
- @param sz Number of bytes in b1.
-*/
-static
-void
-send_network(const char *hn, size_t sz)
-{
- char adbuf[128]; /* Address as text */
- dk4_sockaddr_storage_t array[2]; /* Address pair */
- dk4_um_t num = (dk4_um_t)0UL;
- size_t szr = 0; /* Rem addr size */
- size_t szl = 0; /* Loc addr size */
- size_t lgt = 0; /* Length sent */
- dk4_socket_t sock = INVALID_SOCKET;
- int res = 0; /* Operation result */
- int ip4 = 0; /* IPv4 preferred */
- int af = AF_UNSPEC;
- int pf = PF_UNSPEC;
- $? "+ send_network"
- if (DK4_SOCKET_RESULT_SUCCESS == dk4socket_up(NULL)) {
- if (options[2].found) { ip4 = 1; } $? ". socket subsystem up"
- res = dk4socket_c8_udp_addresses_numeric(array, hn, rp, lp, ip4, NULL);
- if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". addresses ok"
- szr = dk4socket_address_size(array);
- szl = dk4socket_address_size(&(array[1]));
- af = dk4socket_address_family(&(array[1]));
- pf = dk4socket_pf_for_af(af);
- if ((0 < szr) && (0 < szl) && (AF_UNSPEC != af) && (PF_UNSPEC != pf)) {
- sock = dk4socket_open(pf, SOCK_DGRAM, 0, NULL);
- if (INVALID_SOCKET != sock) { $? ". socket ok"
- exval = EXIT_SUCCESS;
- (void)dk4socket_option_set_reuse(sock, 1, NULL);
- if (options[2].found) { $? ". prepare for broadcast"
- res = dk4socket_option_set_broadcast(sock,1,NULL);
- if (DK4_SOCKET_RESULT_SUCCESS != res) {
- /* ERROR: Failed to set broadcast mode */
- log_1(2);
- exval = EXIT_FAILURE; $? "! broadcast preparation"
- }
- }
- res = dk4socket_bind(
- sock, (struct sockaddr *)(&(array[1])), szl, NULL
- );
- if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". address bound"
- if (0 != options[3].found) { num = options[3].val.u; }
- if ((dk4_um_t)0UL == num) { num = (dk4_um_t)1UL; }
- while ((0 != can_continue()) && ((dk4_um_t)0UL < num--)) {
- lgt = sz; $? ". send attempt"
- res = dk4socket_sendto(
- sock, b1, &lgt, 0,
- (struct sockaddr *)(&(array[0])), szr,
- 0L, 0L, NULL
- );
- if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". sendto ok"
- if (lgt != sz) { exval = EXIT_FAILURE; }
- } else { $? "! sendto failed"
- exval = EXIT_FAILURE;
- }
- }
- } else { $? "! failed to bind local addr"
- /* ERROR: Failed to bind local address */
- res = dk4socket_c8_addr_port_to_text(
- adbuf, sizeof(adbuf),
- af, (struct sockaddr *)(&(array[1])), szl, NULL
- );
- if (DK4_SOCKET_RESULT_SUCCESS == res) {
- log_3(4, 5, adbuf);
- } else {
- log_1(3);
- }
- }
- (void)dk4socket_close(sock, NULL);
- } else { $? "! failed to open socket"
- /* ERROR: Failed to open socket */
- log_1(6);
- }
- } else { $? "! something wrong"
- if (0 == szr) { $? "! remote address size"
- log_3(7, 8, hn);
- }
- if (0 == szl) { $? "! local address size"
- log_3(7, 8, hn);
- }
- if (AF_UNSPEC == af) { $? "! address family"
- log_3(7, 8, hn);
- }
- if (PF_UNSPEC == pf) { $? "! protocol family"
- log_3(7, 8, hn);
- }
- }
- } else { $? "! addresses not found"
- /* ERROR: Failed to obtain addresses */
- log_3(7, 8, hn);
- }
- (void)dk4socket_down(NULL);
- } else { $? "! socket subsystem"
- /* ERROR: Failed to bring socket subsystem up */
- log_1(9);
- }
- $? "- send_network"
-}
-
-
-
-/** Send shutdown data packet.
- @param filenames Command line arguments array,
- 0=remote host, 1=remote port, 2=filename.
- @param szfilenames Number of elements in filenames array.
-*/
-static
-void
-sender_with_signals(const char * const *filenames, size_t szfilenames)
-{
- FILE *fipo = NULL; /* Data file */
- const char *ep = NULL; /* End of usefull data pointer */
- size_t lgt = 0; /* Number of bytes in buffer */
- int res = 0; /* Conversion or operation result */
- $? "+ sender_with_signals"
- if (3 == szfilenames) { $? ". szfilenames"
- res = dk4ma_input_c8_dec_ushort(&rp, filenames[1], &ep, 1, NULL);
- if (0 != res) { $? ". port number"
- if (0 != rp) { $? ". port number not 0"
- lp = rp;
- if (0 != options[4].found) { $? ". local port given"
- if ((dk4_um_t)0UL < options[4].val.u) { $? ". lp ok"
- if ((dk4_um_t)(USHRT_MAX) >= options[4].val.u) {
- lp = (unsigned short)(options[4].val.u); $? ". lp ok"
- } else { $? "! overflow"
- lp = 0;
- /* ERROR: Local port number exceeds 16 bit unsigned range */
- log_1(27);
- }
- } else { $? "! lp 0"
- lp = 0;
- /* ERROR: Local port number 0 is not allowed */
- log_1(28);
- }
- }
- if (0 != lp) { $? ". can run"
- fipo = dk4fopen_c8(filenames[2], "rb", DK4_FOPEN_SC_IS_REGULAR, NULL);
- if (NULL != fipo) { $? ". data file opened"
- lgt = fread(b1, 1, sizeof(b1), fipo);
- fclose(fipo);
- if (0 < lgt) { $? ". data from file"
- /* Send bytes over network */
- send_network(filenames[0], lgt);
- /* Overwrite memory containing data packet */
- if (0 == dk4mem_reset_secure(b1, sizeof(b1), NULL)) {
- exval = EXIT_FAILURE; $? "! reset mem failed"
- }
- } else { $? "! no data from file"
- /* ERROR: No data read from file */
- log_3(16, 17, filenames[2]);
- }
- } else { $? "! data file"
- /* ERROR: Failed to open data file */
- log_3(14, 15, filenames[2]);
- }
- } else { $? "! config"
- }
- } else { $? "! port number 0"
- /* ERROR: Remote port number 0 is not allowed */
- log_1(13);
- }
- } else { $? "! port number"
- /* ERROR: Not a 16 bit unsigned number */
- log_3(11, 12, filenames[1]);
- }
- } else { $? "! szfilenames"
- /* ERROR: Three arguments required - host, port and file */
- log_1(10);
- }
- $? "- sender_with_signals"
-}
-
-
-
-/** Send shutdown data packet.
- @param filenames Command line arguments array,
- 0=remote host, 1=remote port, 2=filename.
- @param szfilenames Number of elements in filenames array.
-*/
-static
-void
-sender(const char * const *filenames, size_t szfilenames)
-{
- $!trace-init rshdown.deb
- $? "+ sender"
-#ifdef DK4_HAVE_SIGACTION
-#ifdef SIGPIPE
- struct sigaction opipe;
- struct sigaction npipe;
-#endif
- struct sigaction oint;
- struct sigaction nint;
- struct sigaction oterm;
- struct sigaction nterm;
-#else
-#ifdef SIGPIPE
- dk4_sig_handler_t *opipe = NULL;
-#endif
- dk4_sig_handler_t *oterm = NULL;
- dk4_sig_handler_t *oint = NULL;
-#endif
-#ifdef DK4_HAVE_SIGACTION
-#ifdef SIGPIPE
- int spipe = 0;
-#endif
- int sint = 0;
- int sterm = 0;
- int s_f_i = 0;
- int s_f_r = 0;
-#endif
-
- /* Set signal handlers
- */
-#if DK4_HAVE_SIGACTION
-#ifdef SIGPIPE
- DK4_MEMRES(&npipe, sizeof(npipe));
- npipe.sa_handler = sig_handler_pipe;
- npipe.sa_flags = 0;
- if (0 != sigemptyset(&npipe.sa_mask)) {
- s_f_i = 1;
- goto finished;
- }
- if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
- s_f_i = 1;
- goto finished;
- }
- if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
- s_f_i = 1;
- goto finished;
- }
- spipe = 1;
-#endif
- DK4_MEMRES(&nterm, sizeof(nterm));
- nterm.sa_handler = sig_handler_term;
- nterm.sa_flags = 0;
- if (0 != sigemptyset(&nterm.sa_mask)) {
- s_f_i = 1;
- goto finished;
- }
- if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
- s_f_i = 1;
- goto finished;
- }
- if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
- s_f_i = 1;
- goto finished;
- }
- sterm = 1;
- DK4_MEMRES(&nint, sizeof(nint));
- nint.sa_handler = sig_handler_int;
- nint.sa_flags = 0;
- if (0 != sigemptyset(&nint.sa_mask)) {
- s_f_i = 1;
- goto finished;
- }
- if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
- s_f_i = 1;
- goto finished;
- }
- if (0 != sigaction(SIGINT, &nint, &oint)) {
- s_f_i = 1;
- goto finished;
- }
- sint = 1;
-#else
-#ifdef SIGPIPE
- opipe = sigset(SIGPIPE, sig_handler_pipe);
-#endif
- oint = sigset(SIGINT, sig_handler_int);
- oterm = sigset(SIGTERM, sig_handler_term);
-#endif
-
- /* Send the bytes.
- */
- sender_with_signals(filenames, szfilenames);
-
- finished:
-
- /* Restore signal handlers
- */
-#if DK4_HAVE_SIGACTION
- if (0 != s_f_i) {
- /* ERROR: Failed to install signal handlers */
- log_1(18);
- exval = EXIT_FAILURE;
- }
- if (0 != sint) {
- if (0 != sigaction(SIGINT, &oint, NULL)) {
- s_f_r = 1;
- }
- }
- if (0 != sterm) {
- if (0 != sigaction(SIGTERM, &oterm, NULL)) {
- s_f_r = 1;
- }
- }
-#ifdef SIGPIPE
- if (0 != spipe) {
- if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
- s_f_r = 1;
- }
- }
-#endif
- if (0 != s_f_r) {
- /* ERROR: Failed to restore signal handlers */
- log_1(19);
- exval = EXIT_FAILURE;
- }
-#else
- if (NULL != oterm) { sigset(SIGTERM, oterm); }
- if (NULL != oint ) { sigset(SIGINT, oint ); }
-#ifdef SIGPIPE
- if (NULL != opipe) { sigset(SIGPIPE, opipe); }
-#endif
-#endif
- $? "- sender"
- $!trace-end
-}
-
-
-
-/** Run service
-*/
-static
-void
-run_daemon_loop(void)
-{
- dk4_allowed_peer_t peer; /* Allowed remote address */
- dk4_sockaddr_storage_t sa; /* Generic socket address */
- fd_set rfds; /* Readable file descriptors */
- dk4_socket_set_t *sset = NULL; /* Set of sockets to read data from */
- struct sockaddr *soa = NULL; /* Minimum socket address */
- struct sockaddr_in *so4 = NULL; /* IPv4 socket address */
-#if DK4_HAVE_STRUCT_SOCKADDR_IN6
- struct sockaddr_in6 *so6 = NULL; /* IPv6 socket address */
-#endif
- size_t szsa = 0; /* Size of sa */
- size_t i = 0; /* Traverse socket set */
- dk4_socket_t smax = 0; /* Maximum socket fd number */
- int cc = 1; /* Flag: Can continue */
- int pused = 0; /* Flag: Peer used */
- int res = 0; /* Operation result */
- int ok = 0; /* Flag: Data packet matches file */
- unsigned short frp = 0; /* Found remote port */
- $? "+ run_daemon_loop"
- soa = (struct sockaddr *)(&sa);
- so4 = (struct sockaddr_in *)(&sa);
-#if DK4_HAVE_STRUCT_SOCKADDR_IN6
- so6 = (struct sockaddr_in6 *)(&sa);
-#endif
- if (DK4_SOCKET_RESULT_SUCCESS == dk4socket_up(NULL)) {
- $? ". socket subsystem"
- if (0 < strlen(asender)) { $? ". sender specified"
- res = dk4socket_c8_get_allowed_peer(&peer, asender, NULL);
- if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". peer found"
- pused = 1;
- } else { $? "! peer not found"
- cc = 0;
- /* SYSLOG ERROR: Invalid peer name */
- syslog_3(29, 30, asender);
- }
- }
- if (1 == cc) { $? ". no errors yet"
- sset = dk4socket_set_udp_directly(lp, 0, 0, NULL);
- if (NULL != sset) { $? ". socket set ok"
- /* SYSLOG: Started */
-#if DK4_HAVE_SYSLOG
- openlog(rshdown_kw[0], LOG_PID, syslogf);
- syslog(LOG_INFO, "%s", rshdown_kw[50]);
- closelog();
-#endif
- do {
- if (0 != can_continue()) {
- FD_ZERO(&rfds);
- smax = -1;
- for (i = 0; i < sset->szUsed; i++) {
- $? ". socket %d", (sset->pSockets)[i]
- FD_SET((sset->pSockets)[i],&rfds);
- if (smax < (sset->pSockets)[i]) { smax = (sset->pSockets)[i]; }
- }
- res = select((1+smax), &rfds, NULL, NULL, NULL);
- if (0 != can_continue()) {
- if (0 < res) { $? ". data available"
- for (i = 0; ((1 == cc) && (i < sset->szUsed)); i++) {
- $? ". checking %d", (sset->pSockets)[i]
- if (FD_ISSET((sset->pSockets)[i],&rfds)) {
- $? ". ready to read"
- DK4_MEMRES(&sa, sizeof(sa));
- szb2 = sizeof(b2);
- szsa = sizeof(sa);
- res = dk4socket_recvfrom(
- (sset->pSockets)[i], b2, &szb2, 0,
- (struct sockaddr *)(&sa), &szsa, 0L, 0L, NULL
- );
- if (0 != can_continue()) { $? ". can continue"
- if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". read"
- if (0 < szb2) { $? ". %u bytes received", (unsigned)szb2
- ok = 1;
- if (0 != pused) { $? ". check peer"
- res = dk4socket_allowed_peer_compare(&peer, &sa, 1);
- if (0 != res) { $? "! address mismatch"
- ok = 0;
- /* SYSLOG DEBUG: Address mismatch */
- syslog_debug(53, 54, &sa);
- }
- }
- if (0U != rp) { $? ". check port"
- frp = 0;
- switch (soa->sa_family) {
- case AF_INET : {
- frp = dk4socket_ntohs(so4->sin_port);
- } break;
-#if DK4_HAVE_STRUCT_SOCKADDR_IN6
- case AF_INET6 : {
- frp = dk4socket_ntohs(so6->sin6_port);
- } break;
-#endif
- }
- if (frp != rp) { $? "! port mismatch"
- ok = 0;
- /* SYSLOG DEBUG: Port mismatch */
- syslog_debug(55, 56, &sa);
- }
- }
- if (0 != ok) { $? ". peer/port ok"
- ok = 0;
- if (szb1 == szb2) { $? ". size match"
- if (0 == DK4_MEMCMP(b1,b2,szb1)) {
- ok = 1; $? ". data matches"
- } else { $? "! data mismatch"
- /* SYSLOG DEBUG: Data mismatch */
- syslog_debug(59, 60, &sa);
- }
- } else { $? "! size mismatch"
- /* SYSLOG DEBUG: Size mismatch */
- syslog_debug(57, 58, &sa);
- }
- }
- if (0 != ok) { $? ". going to shut down"
- /* Shutdown */
- /* SYSLOG: Initiating shutdown */
-#if DK4_HAVE_SYSLOG
- openlog(rshdown_kw[0], LOG_PID, syslogf);
- syslog(LOG_INFO, "%s", rshdown_kw[51]);
- closelog();
-#endif
- if (0 < strlen(cmd)) { $? ". command"
- if (0 != system(cmd)) {
-#if DK4_HAVE_SYSLOG
-
- openlog(rshdown_kw[0], LOG_PID, syslogf);
- syslog(
- LOG_ERR, "%s%s%s",
- rshdown_kw[61], cmd, rshdown_kw[62]
- );
- closelog();
-#endif
- }
- } else { $? ". signal"
- if (0 < signo) {
- kill((pid_t)1, signo);
- } else {
-#ifdef SIGPWR
- kill((pid_t)1, SIGPWR);
-#else
-#ifdef SIGTERM
- kill((pid_t)1, SIGTERM);
-#else
- kill((pid_t)1, 15);
-#endif
-#endif
- }
- }
- cc = 0;
- }
- } else { $? "! size is 0"
- }
- } else { $? "! recvfrom"
- }
- } else { $? "! signal"
- cc = -1;
- }
- } else { $? ". not ready to read"
- }
- }
- } else { $? ". no fd ready"
- }
- } else { $? "! signal"
- cc = -1;
- }
- } else { $? "! signal"
- cc = -1;
- }
- } while (1 == cc); $? ". loop finished"
- dk4socket_set_close(sset, NULL);
- /* SYSLOG: Finished */
-#if DK4_HAVE_SYSLOG
- openlog(rshdown_kw[0], LOG_PID, syslogf);
- syslog(LOG_INFO, "%s", rshdown_kw[52]);
- closelog();
-#endif
- } else { $? "! socket set"
- /* SYSLOG ERROR: Failed to create socket set */
- syslog_1(26);
- }
- } else { $? "! previous errors"
- }
- (void)dk4socket_down(NULL);
- } else { $? "! socket subsystem"
- /* SYSLOG ERROR: Failed to bring socket subsystem up */
- syslog_1(25);
- }
- $? "- run_daemon_loop"
-}
-
-
-
-/** Set signal handlers and run service.
-*/
-static
-void
-run_daemon_with_signals(void)
-{
-#ifdef DK4_HAVE_SIGACTION
-#ifdef SIGPIPE
- struct sigaction opipe;
- struct sigaction npipe;
-#endif
- struct sigaction oint;
- struct sigaction nint;
- struct sigaction oterm;
- struct sigaction nterm;
-#else
-#ifdef SIGPIPE
- dk4_sig_handler_t *opipe = NULL;
-#endif
- dk4_sig_handler_t *oterm = NULL;
- dk4_sig_handler_t *oint = NULL;
-#endif
-#ifdef DK4_HAVE_SIGACTION
-#ifdef SIGPIPE
- int spipe = 0;
-#endif
- int sint = 0;
- int sterm = 0;
- int s_f_i = 0;
- int s_f_r = 0;
-#endif
- $? "+ run_daemon_with_signals"
- /* Set signal handlers
- */
-#if DK4_HAVE_SIGACTION
-#ifdef SIGPIPE
- DK4_MEMRES(&npipe, sizeof(npipe));
- npipe.sa_handler = sig_handler_pipe;
- npipe.sa_flags = 0;
- if (0 != sigemptyset(&npipe.sa_mask)) {
- s_f_i = 1;
- goto finished;
- }
- if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
- s_f_i = 1;
- goto finished;
- }
- if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
- s_f_i = 1;
- goto finished;
- }
- spipe = 1;
-#endif
- DK4_MEMRES(&nterm, sizeof(nterm));
- nterm.sa_handler = sig_handler_term;
- nterm.sa_flags = 0;
- if (0 != sigemptyset(&nterm.sa_mask)) {
- s_f_i = 1;
- goto finished;
- }
- if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
- s_f_i = 1;
- goto finished;
- }
- if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
- s_f_i = 1;
- goto finished;
- }
- sterm = 1;
- DK4_MEMRES(&nint, sizeof(nint));
- nint.sa_handler = sig_handler_int;
- nint.sa_flags = 0;
- if (0 != sigemptyset(&nint.sa_mask)) {
- s_f_i = 1;
- goto finished;
- }
- if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
- s_f_i = 1;
- goto finished;
- }
- if (0 != sigaction(SIGINT, &nint, &oint)) {
- s_f_i = 1;
- goto finished;
- }
- sint = 1;
-#else
-#ifdef SIGPIPE
- opipe = sigset(SIGPIPE, sig_handler_pipe);
-#endif
- oint = sigset(SIGINT, sig_handler_int);
- oterm = sigset(SIGTERM, sig_handler_term);
-#endif
-
- run_daemon_loop();
-
- finished:
-
- /* Restore signal handlers
- */
-#if DK4_HAVE_SIGACTION
- if (0 != s_f_i) {
- /* ERROR: Failed to install signal handlers */
- syslog_1(23);
- dk4dmt_error_sysfct(&dmt);
- }
- if (0 != sint) {
- if (0 != sigaction(SIGINT, &oint, NULL)) {
- s_f_r = 1;
- }
- }
- if (0 != sterm) {
- if (0 != sigaction(SIGTERM, &oterm, NULL)) {
- s_f_r = 1;
- }
- }
-#ifdef SIGPIPE
- if (0 != spipe) {
- if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
- s_f_r = 1;
- }
- }
-#endif
- if (0 != s_f_r) {
- /* ERROR: Failed to restore signal handlers */
- syslog_1(24);
- dk4dmt_error_sysfct(&dmt);
- }
-#else
- if (NULL != oterm) { sigset(SIGTERM, oterm); }
- if (NULL != oint ) { sigset(SIGINT, oint ); }
-#ifdef SIGPIPE
- if (NULL != opipe) { sigset(SIGPIPE, opipe); }
-#endif
-#endif
- $? "- run_daemon_with_signals"
-}
-
-
-
-/** Retrieve port number from a configuration file line.
- @param dest Address of destination variable.
- @param pv String containing the port number.
- @param a0 Flag: Remote port, 0 allowed for arbitrary ports.
- @return 1 on success, 0 on error.
-*/
-static
-int
-set_port_number(
- unsigned short *dest,
- const char *pv,
- int a0
-)
-{
- const char *ep = NULL;
- int back = 0;
- unsigned short us = 0U;
-
- if (0 != dk4ma_input_c8_dec_ushort(&us, pv, &ep, 1, NULL)) {
- if (0U != us) {
- *dest = us;
- back = 1;
- } else {
- if (0 != a0) {
- *dest = us;
- back = 1;
- } else {
- /* ERROR: Port number 0 not allowed! */
- log_1(28);
- }
- }
- } else {
- /* ERROR: Not a 16 bit unsigned number! */
- log_3(11, 12, pv);
- }
- return back;
-}
-
-
-
-/** Set the signal number.
- @param pv Text containing the number.
- @return 1 on success, 0 on error.
-*/
-static
-int
-set_signal_number(const char *pv)
-{
- int back = 1;
- $? "+ set_signal_number \"%s\"", TR_8STR(pv)
- switch ( dk4str8_array_index(signal_names, pv, 0) ) {
- case 0 : case 1 : {
-#ifdef SIGHUP
- signo = SIGHUP;
-#else
- signo = 1;
-#endif
- } break;
- case 2 : case 3 : {
-#ifdef SIGINT
- signo = SIGINT;
-#else
- signo = 2;
-#endif
- } break;
- case 4 : case 5 : {
-#ifdef SIGQUIT
- signo = SIGQUIT;
-#else
- signo = 3;
-#endif
- } break;
- case 6 : case 7 : {
-#ifdef SIGILL
- signo = SIGILL;
-#else
- signo = 4;
-#endif
- } break;
- case 8 : case 9 : {
-#ifdef SIGTRAP
- signo = SIGTRAP;
-#else
- signo = 5;
-#endif
- } break;
- case 10 : case 11 : case 12 : case 13 : {
-#ifdef SIGABRT
- signo = SIGABRT;
-#else
-#ifdef SIGIOT
- signo = SIGIOT;
-#else
- signo = 6;
-#endif
-#endif
- } break;
- case 14 : case 15 : {
-#ifdef SIGBUS
- signo = SIGBUS;
-#else
- signo = 7;
-#endif
- } break;
- case 16 : case 17 : {
-#ifdef SIGFPE
- signo = SIGFPE;
-#else
- signo = 8;
-#endif
- } break;
- case 18 : case 19 : {
-#ifdef SIGKILL
- signo = SIGKILL;
-#else
- signo = 9;
-#endif
- } break;
- case 20 : case 21 : {
-#ifdef SIGUSR1
- signo = SIGUSR1;
-#else
- signo = 10;
-#endif
- } break;
- case 22 : case 23 : {
-#ifdef SIGSEGV
- signo = SIGSEGV;
-#else
- signo = 11;
-#endif
- } break;
- case 24 : case 25 : {
-#ifdef SIGUSR2
- signo = SIGUSR2;
-#else
- signo = 12;
-#endif
- } break;
- case 26 : case 27 : {
-#ifdef SIGPIPE
- signo = SIGPIPE;
-#else
- signo = 13;
-#endif
- } break;
- case 28 : case 29 : {
-#ifdef SIGALRM
- signo = SIGALRM;
-#else
- signo = 14;
-#endif
- } break;
- case 30 : case 31 : {
-#ifdef SIGTERM
- signo = SIGTERM;
-#else
- signo = 15;
-#endif
- } break;
- case 32 : case 33 : {
-#ifdef SIGSTKFLT
- signo = SIGSTKFLT;
-#else
- signo = 16;
-#endif
- } break;
- case 34 : case 35 : case 36 : case 37 : {
-#ifdef SIGCLD
- signo = SIGCLD;
-#else
-#ifdef SIGCHLD
- signo = SIGCHLD;
-#else
- signo = 17;
-#endif
-#endif
- } break;
- case 38 : case 39 : {
-#ifdef SIGCONT
- signo = SIGCONT;
-#else
- signo = 18;
-#endif
- } break;
- case 40 : case 41 : {
-#ifdef SIGSTOP
- signo = SIGSTOP;
-#else
- signo = 19;
-#endif
- } break;
- case 42 : case 43 : {
-#ifdef SIGTSTP
- signo = SIGTSTP;
-#else
- signo = 20;
-#endif
- } break;
- case 44 : case 45 : {
-#ifdef SIGTTIN
- signo = SIGTTIN;
-#else
- signo = 21;
-#endif
- } break;
- case 46 : case 47 : {
-#ifdef SIGTTOU
- signo = SIGTTOU;
-#else
- signo = 22;
-#endif
- } break;
- case 48 : case 49 : {
-#ifdef SIGURG
- signo = SIGURG;
-#else
- signo = 23;
-#endif
- } break;
- case 50 : case 51 : {
-#ifdef SIGXCPU
- signo = SIGXCPU;
-#else
- signo = 24;
-#endif
- } break;
- case 52 : case 53 : {
-#ifdef SIGXFSZ
- signo = SIGXFSZ;
-#else
- signo = 25;
-#endif
- } break;
- case 54 : case 55 : {
-#ifdef SIGVTALRM
- signo = SIGVTALRM;
-#else
- signo = 26;
-#endif
- } break;
- case 56 : case 57 : {
-#ifdef SIGPROF
- signo = SIGPROF;
-#else
- signo = 27;
-#endif
- } break;
- case 58 : case 59 : {
-#ifdef SIGWINCH
- signo = SIGWINCH;
-#else
- signo = 28;
-#endif
- } break;
- case 60 : case 61 : case 62 : case 63 : {
-#ifdef SIGPOLL
- signo = SIGPOLL;
-#else
-#ifdef SIGIO
- signo = SIGIO
-#else
- signo = 29;
-#endif
-#endif
- } break;
- case 64 : case 65 : {
-#ifdef SIGPWR
- signo = SIGPWR;
-#else
- signo = 30;
-#endif
- } break;
- case 66 : case 67 : {
-#ifdef SIGSYS
- signo = SIGSYS;
-#else
- signo = 31;
-#endif
- } break;
- default : { $? "! illegal signal name"
- back = 0;
- /* ERROR: Illegal signal name */
- log_3(31, 32, pv);
- } break;
- } $? "- set_signal_number %d", back
- return back;
-}
-
-
-
-/** Set syslog facility.
- @param pv Text representation of syslog facility.
- @return 1 on success, 0 on error.
-*/
-static
-int
-set_syslog_facility(const char *pv)
-{
- int back = 1;
- if (NULL != pv) {
- switch ( dk4str8_array_index(syslog_facility_names, pv, 0) ) {
-#ifdef LOG_AUTH
- case 0: { syslogf = LOG_AUTH; } break;
-#endif
-#ifdef LOG_AUTHPRIV
- case 1: { syslogf = LOG_AUTHPRIV; } break;
-#endif
-#ifdef LOG_CRON
- case 2: { syslogf = LOG_CRON; } break;
-#endif
-#ifdef LOG_DAEMON
- case 3: { syslogf = LOG_DAEMON; } break;
-#endif
-#ifdef LOG_FTP
- case 4: { syslogf = LOG_FTP; } break;
-#endif
-#ifdef LOG_KERN
- case 5: { syslogf = LOG_KERN; } break;
-#endif
-#ifdef LOG_LPR
- case 6: { syslogf = LOG_LPR; } break;
-#endif
-#ifdef LOG_MAIL
- case 7: { syslogf = LOG_MAIL; } break;
-#endif
-#ifdef LOG_NEWS
- case 8: { syslogf = LOG_NEWS; } break;
-#endif
-#ifdef LOG_AUTH
- case 9: { syslogf = LOG_AUTH; } break;
-#endif
-#ifdef LOG_SYSLOG
- case 10: { syslogf = LOG_SYSLOG; } break;
-#endif
-#ifdef LOG_USER
- case 11: { syslogf = LOG_USER; } break;
-#endif
-#ifdef LOG_UUCP
- case 12: { syslogf = LOG_UUCP; } break;
-#endif
-#ifdef LOG_LOCAL0
- case 13: { syslogf = LOG_LOCAL0; } break;
-#endif
-#ifdef LOG_LOCAL1
- case 14: { syslogf = LOG_LOCAL1; } break;
-#endif
-#ifdef LOG_LOCAL2
- case 15: { syslogf = LOG_LOCAL2; } break;
-#endif
-#ifdef LOG_LOCAL3
- case 16: { syslogf = LOG_LOCAL3; } break;
-#endif
-#ifdef LOG_LOCAL4
- case 17: { syslogf = LOG_LOCAL4; } break;
-#endif
-#ifdef LOG_LOCAL5
- case 18: { syslogf = LOG_LOCAL5; } break;
-#endif
-#ifdef LOG_LOCAL6
- case 19: { syslogf = LOG_LOCAL6; } break;
-#endif
-#ifdef LOG_LOCAL7
- case 20: { syslogf = LOG_LOCAL7; } break;
-#endif
- default: {
- back = 0;
- log_3(48, 49, pv);
- } break;
- }
- }
- return back;
-}
-
-
-
-/** Read configuration file.
- @return 1 on success, 0 on error.
-*/
-static
-int
-read_config_file(void)
-{
- FILE *fipo = NULL; /* Input file to process */
- const char *fn = NULL; /* Input file name */
- const char *ep = NULL; /* End pointer after number */
- char *pk = NULL; /* Pointer to key string */
- char *pv = NULL; /* Pointer to value string */
- dk4_um_t lineno = (dk4_um_t)0UL; /* Current line number */
- int back = 0;
- $? "+ read_config_file"
- if (0 != options[0].found) { fn = options[0].val.t; }
- if (NULL == fn) { fn = def_conf_name; }
- fipo = dk4fopen_c8(fn, "r", DK4_FOPEN_SC_IS_REGULAR, NULL);
- if (NULL != fipo) {
- back = 1;
- while( fgets(b1, sizeof(b1), fipo) ) {
- lineno++;
- pk = dk4str8_start(b1, NULL);
- if (NULL != pk) {
- if ('#' != *pk) {
- pv = dk4str8_chr(pk, '=');
- if (NULL != pv) {
- *(pv++) = '\0';
- pv = dk4str8_start(pv, NULL);
- if (NULL != pv) {
- dk4str8_normalize(pk, NULL);
- dk4str8_delnl(pv);
- switch ( dk4str8_array_index(key_names, pk, 0) ) {
- case 0: { /* sender address */
- if (0 == strlen(asender)) {
- dk4str8_normalize(pv, NULL);
- if (0 == dk4str8_cpy_s(asender,sizeof(asender),pv,NULL)) {
- back = 0; $? "! sender too long"
- /* ERROR: Sender name too long */
- log_3(33, 34, pv);
- }
- } else { $? "! redefinition of sender"
- back = 0;
- /* ERROR: Redefinition of sender */
- log_1(35);
- }
- } break;
- case 1: { /* sender port */
- if (0 == set_port_number(&rp, pv, 1)) {
- back = 0; $? "! remote port not numeric"
- }
- } break;
- case 2: { /* local port */
- if (0 == set_port_number(&lp, pv, 0)) {
- back = 0; $? "! local port not numeric"
- }
- } break;
- case 3: { /* signal */
- ep = NULL;
- if (0 != dk4ma_input_c8_dec_int(&signo, pv, &ep, 1, NULL)) {
- if (1 > signo) {
- back = 0; $? "! illegal value for signo"
- /* ERROR: Signal number must be positive */
- log_1(36);
- }
- } else {
- dk4str8_normalize(pv, NULL);
- if (0 == set_signal_number(pv)) {
- back = 0; $? "! failed to set signo"
- }
- }
- } break;
- case 4: { /* command */
- if (0 == strlen(cmd)) {
- if (0 == dk4str8_cpy_s(cmd, sizeof(cmd), pv, NULL)) {
- back = 0;
- /* ERROR: Command too long! */
- log_3(37, 38, pv);
- }
- } else { $? "! command redefined"
- back = 0;
- /* ERROR: Redefinition of command */
- log_1(39);
- }
- } break;
- case 5: { /* file */
- if (0 == strlen(file_name)) {
- if (0 == dk4str8_cpy_s(file_name,sizeof(file_name),pv,NULL))
- {
- back = 0;
- /* ERROR: File name too long! */
- log_3(40, 41, pv);
- }
- } else { $? "! file name redefined"
- back = 0;
- /* ERROR: Redefinition of file name */
- log_1(42);
- }
- } break;
- case 6: {
- debug = ((dk4str8_is_on(pv)) ? 1 : 0);
- } break;
- case 7: {
- dk4str8_normalize(pv, NULL);
- if (0 == set_syslog_facility(pv)) {
- back = 0;
- }
- } break;
- default : { $? "! unknown key"
- log_1(43);
- } break;
- }
- } else { $? "! missing value"
- back = 0;
- /* ERROR: Missing value */
- log_1(44);
- }
- } else { $? "! missing value"
- back = 0;
- /* ERROR: Missing value */
- log_1(44);
- }
- }
- }
- }
- fclose(fipo);
- if ((0 != back) && (0U == lp)) {
- back = 0; $? "! missing local port"
- /* ERROR: Local port not specified */
- log_1(45);
- }
- if (0 != back) {
- if ((0 == signo) && (0 == strlen(cmd))) {
- back = 0; $? "! command or signo"
- /* ERROR: Signal or command required */
- log_1(46);
- }
- }
- if (0 != back) {
- if (0 != strlen(file_name)) {
- fipo = dk4fopen_c8(file_name, "rb", DK4_FOPEN_SC_IS_REGULAR, NULL);
- if (NULL != fipo) {
- szb1 = fread(b1, 1, sizeof(b1), fipo);
- fclose(fipo);
- if (0 == szb1) {
- back = 0; $? "! data file contents"
- /* ERROR: Failed to read data from file */
- log_3(16, 17, file_name);
- }
- } else { $? "! open data file"
- back = 0;
- /* ERROR: Failed to open data file */
- log_3(14, 15, file_name);
- }
- } else { $? "! data file name"
- back = 0;
- /* ERROR: No data file specified */
- log_1(47);
- }
- }
- } else { $? "! failed to open conf file"
- } $? "- read_config_file %d", back
- return back;
-}
-
-
-/** Daemon waiting for shutdown data packet.
-*/
-static
-void
-run_as_daemon(void)
-{
- pid_t cpid;
-
- dk4dmt_init(&dmt);
- $? "+ run_as_daemon"
- /* Preparations before we start.
- */
- DK4_MEMRES(cmd, sizeof(cmd));
- DK4_MEMRES(asender, sizeof(asender));
- DK4_MEMRES(file_name, sizeof(file_name));
- if (read_config_file()) { $? ". conf ok"
- dk4dmt_set_program(&dmt, rshdown_kw[0]);
- dk4dmt_set_pidfile(&dmt, pid_file_name);
- dk4dmt_set_syslog_feature(&dmt, syslogf);
- if (0 != dk4dmt_parent_before_fork(&dmt)) {
- cpid = fork();
- if ((pid_t)0 == cpid) { /* in the child */
- if (0 != dk4dmt_intermediate_before_fork(&dmt)) {
- cpid = fork();
- if ((pid_t)0 == cpid) { /* in the child */
- $!trace-init /tmp/rshdown.deb
- $? "+ daemon process"
- dk4dmt_success(&dmt);
- if (0 != dk4dmt_daemon_start(&dmt)) {
- run_daemon_with_signals();
- }
- dk4dmt_daemon_end(&dmt);
- if (0 == dk4mem_reset_secure(b1, sizeof(b1), NULL)) {
- dk4dmt_error_sysfct(&dmt);
- }
- if (0 == dk4mem_reset_secure(b2, sizeof(b2), NULL)) {
- dk4dmt_error_sysfct(&dmt);
- }
- $? "- daemon process %d", exval
- $!trace-end
- } else {
- if ((pid_t)(-1) != cpid) { /* intermediate process */
- dk4dmt_success(&dmt);
- if (0 == dk4mem_reset_secure(b1, sizeof(b1), NULL)) {
- dk4dmt_error_sysfct(&dmt);
- }
- if (0 == dk4mem_reset_secure(b2, sizeof(b2), NULL)) {
- dk4dmt_error_sysfct(&dmt);
- }
- dk4dmt_intermediate_after_fork(&dmt);
- } else { /* error */
- if (0 == dk4mem_reset_secure(b1, sizeof(b1), NULL)) {
- dk4dmt_error_sysfct(&dmt);
- }
- if (0 == dk4mem_reset_secure(b2, sizeof(b2), NULL)) {
- dk4dmt_error_sysfct(&dmt);
- }
- /* SYSLOG ERROR: Failed to create child process */
- syslog_1(22);
- dk4dmt_intermediate_fork_failed(&dmt);
- }
- }
- } else {
- if (0 == dk4mem_reset_secure(b1, sizeof(b1), NULL)) {
- dk4dmt_error_sysfct(&dmt);
- }
- if (0 == dk4mem_reset_secure(b2, sizeof(b2), NULL)) {
- dk4dmt_error_sysfct(&dmt);
- }
- /* SYSLOG ERROR: Failed to detach */
- syslog_1(21);
- }
- } else {
- if ((pid_t)(-1) != cpid) { /* parent */
- dk4dmt_parent_after_fork(&dmt);
- } else { /* error */
- /* ERROR: Failed to create child process */
- dk4dmt_parent_fork_failed(&dmt);
- log_1(20);
- }
- }
- }
- }
- else {
- dk4dmt_error_config(&dmt);
- }
- if (0 == dk4mem_reset_secure(b1, sizeof(b1), NULL)) {
- dk4dmt_error_sysfct(&dmt);
- }
- if (0 == dk4mem_reset_secure(b2, sizeof(b2), NULL)) {
- dk4dmt_error_sysfct(&dmt);
- }
- exval = dk4dmt_get_exit_status(&dmt);
- $? "- run_as_daemon"
-}
-
-
-
-/** Show a text paragraph on standard output.
- @param txt Text to show.
-*/
-static
-void
-show_text(const char * const *txt)
-{
- if (NULL != txt) {
- while (NULL != *txt) {
- fputs(*(txt++), stdout);
- fputc('\n', stdout);
- }
- fflush(stdout);
- }
-}
-
-
-
-/** Handle --help, --version, --license options.
-*/
-static
-void
-run_hvl(void)
-{
- if (0 != (1 & hvl)) {
- show_text(help_text);
- }
- if (0 != (2 & hvl)) {
- fputs(version_text, stdout);
- fputc('\n', stdout);
- fflush(stdout);
- }
- if (0 != (4 & hvl)) {
- show_text(license_text);
- }
-}
-
-
-
-/** Program entry point.
- @param argc
- @param argv
- @return 0 on success, any other value indicates an error.
-*/
-int
-main(int argc, char *argv[])
-{
- char *filenames[32];
- size_t szfilenames = 32; /* Array size */
- int res = 0; /* Operation result */
-
- $? "+ main"
- /* Process command line arguments.
- */
- res = dk4opt_process_argv(
- options, szoptions, argc, argv, filenames, &szfilenames, 1, 1, NULL
- );
- if (0 == res) { $? "! option processing"
- goto finished;
- }
-
- /* Check help, version, license.
- */
- if (0 != options[5].found) { hvl |= 1; }
- if (0 != options[6].found) { hvl |= 2; }
- if (0 != options[7].found) { hvl |= 4; }
- if (0 != hvl) {
- run_hvl();
- goto finished;
- }
-
- /* Either send data or run as daemon to receive data.
- */
- if (0 != options[1].found) { $? ". run sender"
- sender((const char * const *)filenames, szfilenames);
- } else { $? ". run daemon"
- run_as_daemon();
- }
-
- finished:
- $? "- main %d", exval
- exit(exval); return exval;
-}
-
-
-#else
-
-
-/** Program entry point.
- @param argc
- @param argv
- @return 0 on success, any other value indicates an error.
-*/
-int
-main(int argc, char *argv[])
-{
- fputs("rshdown: ERROR: Build requirements violation!\n", stderr);
-#if DK4_CHAR_SIZE > 1
- fputs("Default character size is larger than 1!\n", stderr);
-#endif
-#if !((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
- fputs("Neither sigaction() nor sigset() are available!\n", stderr);
-#endif
-#if !((DK4_HAVE_SETSID) || (DK4_HAVE_SETPGRP))
- fputs("Neither setsid() nor setpgrp() are available!\n", stderr);
-#endif
- fflush(stderr);
- exit(EXIT_FAILURE); return EXIT_FAILURE;
-}
-
-#endif
-
-