Bordeaux is a voice application server for modern IP telephony networks using modern C++ practices along with advances originally made in GNU Bayonne.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

119 lines
3.2 KiB

/*
* Copyright (C) 2020-2021 David Sugar <tychosoft@gmail.com>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "compiler.hpp"
#include "print.hpp"
#include "strings.hpp"
#include "args.hpp"
#include <csignal>
#include <unistd.h>
#include <fcntl.h>
namespace {
args::option helpflag('h', "--help", "display this list");
args::option quiet('q', "--quiet", "surpress most output");
args::option timeout('t', "--timeout","reply wait", "seconds");
args::option althelp('?', nullptr, nullptr);
class fifo_error final : public std::exception
{
public:
explicit fifo_error(const char *text, int code) noexcept {
err = code;
msg = text;
}
auto what() const noexcept -> const char * override {
return msg;
}
inline auto exit() const noexcept {
return err;
}
private:
const char *msg;
int err;
};
} // end namespace
auto main(int argc, const char **argv) -> int // NOLINT
{
auto exit_code = 0;
try {
auto wait_time = 5;
auto count = args::parse(argc, argv);
if(is(helpflag) || is(althelp) || !count) {
args::help({"bordeauxctl [options] command..."}, {
"Send command to server ipc"
});
return 0;
}
signal(SIGUSR2, []([[maybe_unused]]int signo){
throw fifo_error("error", 1);
});
signal(SIGUSR1, []([[maybe_unused]]int signo){
if(!is(quiet))
print("success\n");
::exit(0);
});
if(is(timeout))
wait_time = std::stoi(*timeout);
auto command = std::to_string(getpid());
for(auto &arg : args::list())
command += " " + std::string(arg);
auto fifo = ::open(SERVER_CONTROL_IPC, O_WRONLY|O_SYNC); // FlawFinder: ignored
if(fifo < 0) {
throw fifo_error("fifo offline or not permitted", 4);
}
command += '\n';
auto result = ::write(fifo, command.data(), command.size());
if(size_t(result) < command.size())
throw fifo_error("fifo failed write", 3);
::close(fifo);
::sleep(wait_time);
throw fifo_error("timeout", 2);
}
catch(const fifo_error& e) {
exit_code = e.exit();
if(!is(quiet))
die(exit_code, "*** bordeauxctl: {}\n", e.what());
}
catch(const std::exception& e) {
if(is(quiet))
exit_code = -1;
else
die(-1, "*** bordeauxctl: {}\n", e.what());
}
catch(...) {
if(is(quiet))
exit_code = -1;
else
die(-1, "*** bordeauxctl: unknown error\n");
}
return exit_code;
}