216 lines
7.6 KiB
C++
Executable File
216 lines
7.6 KiB
C++
Executable File
//-----------------------------------------------------------------------------------------//
|
|
// Distributed under the MIT License - https://opensource.org/licenses/MIT
|
|
//-----------------------------------------------------------------------------------------//
|
|
//
|
|
// Copyright © 2019 Sasko Usinov
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights to
|
|
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
// the Software, and to permit persons to whom the Software is furnished to do so,
|
|
// subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in all
|
|
// copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
|
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
//
|
|
//-----------------------------------------------------------------------------------------//
|
|
// Distributed under the MIT License - https://opensource.org/licenses/MIT
|
|
//-----------------------------------------------------------------------------------------//
|
|
|
|
|
|
#include "api.h"
|
|
#include "liblogman/log_manager.h"
|
|
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <sstream>
|
|
|
|
#include <sys/klog.h>
|
|
#include <sys/stat.h>
|
|
|
|
#include <stdio.h>
|
|
#include <iostream>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sstream>
|
|
#include <fstream>
|
|
#include <algorithm>
|
|
|
|
#include <array>
|
|
|
|
api::log_manager api::cns::g_out, api::cns::g_err(api::log_manager::level_err);;
|
|
|
|
//-------------------------------------------------------------------------------//
|
|
// Type: namespace
|
|
//-------------------------------------------------------------------------------//
|
|
//
|
|
// ToDo: n/a
|
|
//
|
|
// Notes: Returns a list of supported terminals that we can use
|
|
//
|
|
// Returns: n/a
|
|
//
|
|
//-------------------------------------------------------------------------------//
|
|
std::vector<std::string> api::cns::get_supported_terminals()
|
|
{
|
|
std::vector<std::string> term_list;
|
|
|
|
term_list.push_back("xterm");
|
|
term_list.push_back("xfce4-terminal");
|
|
term_list.push_back("gnome-terminal");
|
|
term_list.push_back("konsole");
|
|
term_list.push_back("terminator");
|
|
term_list.push_back("tilix");
|
|
term_list.push_back("mate-terminal");
|
|
|
|
return term_list;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------//
|
|
// Type: namespace
|
|
//-------------------------------------------------------------------------------//
|
|
//
|
|
// ToDo: n/a
|
|
//
|
|
// Notes: Returns a terminal that we can use
|
|
//
|
|
// Returns: n/a
|
|
//
|
|
//-------------------------------------------------------------------------------//
|
|
std::string api::cns::get_preferred_terminal()
|
|
{
|
|
std::string out;
|
|
|
|
//------------------------------------------------------------------------------------------------
|
|
// Warning! Do not add lxterminal - the version I tested did not work properly with "-e"
|
|
// when you add quotations etc
|
|
//------------------------------------------------------------------------------------------------
|
|
std::vector<std::string> term_list = get_supported_terminals();
|
|
|
|
for (size_t i = 0; i < term_list.size(); i++)
|
|
{
|
|
std::string t = "which " + term_list[i] + " > /dev/null";
|
|
|
|
if (!system(t.c_str()))
|
|
out = term_list[i];
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------//
|
|
// Type: namespace
|
|
//-------------------------------------------------------------------------------//
|
|
//
|
|
// ToDo: n/a
|
|
//
|
|
// Notes: Runs a console command, waits for the process to finish and returns the output
|
|
// output_dir is the destination path for the temporary files
|
|
//
|
|
// Returns: n/a
|
|
//
|
|
//-------------------------------------------------------------------------------//
|
|
api::cns::runstruct api::cns::exec(const std::string & cmd, const std::string & output_dir)
|
|
{
|
|
runstruct out;
|
|
out.tmp_dir = output_dir;
|
|
|
|
std::string tmpname_out {api::fs::generate_unique_filename(out.tmp_dir, "tmpfile_out")};
|
|
std::string tmpname_err {api::fs::generate_unique_filename(out.tmp_dir, "tmpfile_err")};
|
|
std::string run_cmd {std::string("bash -c \"" + SHELL_PATH + " && " + cmd + " > " + tmpname_out + " 2>" + tmpname_err + "\"").c_str()};
|
|
|
|
out.exit_code = system(run_cmd.c_str());
|
|
|
|
out.std_out = api::fs::load_from_file(tmpname_out);
|
|
out.std_err = api::fs::load_from_file(tmpname_err);
|
|
|
|
return out;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------//
|
|
// Type: namespace
|
|
//-------------------------------------------------------------------------------//
|
|
//
|
|
// ToDo: n/a
|
|
//
|
|
// Notes: Runs a console command, waits for the process to finish and returns the output
|
|
// output_dir is the destination path for the temporary files
|
|
//
|
|
// Remarks: Something experimental I was working on.
|
|
//
|
|
// I have a real-time version using forkpty and execvp but we don't need it here.
|
|
//
|
|
// Returns: n/a
|
|
//
|
|
//-------------------------------------------------------------------------------//
|
|
api::cns::runstruct api::cns::exec_ext(const std::string & cmd, const std::string & output_dir)
|
|
{
|
|
runstruct out;
|
|
out.tmp_dir = output_dir;
|
|
|
|
std::string tmpname_out = api::fs::generate_unique_filename(out.tmp_dir, "tmpfile_out");
|
|
std::string tmpname_err = api::fs::generate_unique_filename(out.tmp_dir, "tmpfile_err");
|
|
|
|
std::string script_path {api::fs::generate_unique_filename(out.tmp_dir, "_tmpfile_s_")};
|
|
std::vector<std::string> script {};
|
|
|
|
script.push_back("#!/bin/bash");
|
|
script.push_back(SHELL_PATH);
|
|
script.push_back(std::string(cmd + " > " + tmpname_out + " 2>" + tmpname_err).c_str());
|
|
|
|
if (!api::fs::save_to_file(script_path, api::vct::to_string(script, '\n')))
|
|
return out; // perhaps raise an exception
|
|
|
|
if (system(("chmod u+x " + script_path).c_str()))
|
|
return out; // perhaps raise an exception
|
|
|
|
out.exit_code = system(script_path.c_str());
|
|
|
|
out.std_out = api::fs::load_from_file(tmpname_out);
|
|
out.std_err = api::fs::load_from_file(tmpname_err);
|
|
|
|
return out;
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------------------------//
|
|
// Type: namespace
|
|
//-------------------------------------------------------------------------------//
|
|
//
|
|
// ToDo: n/a
|
|
//
|
|
// Notes: Runs a console command and returns its output
|
|
//
|
|
// Remarks: I have a version that's using forkpty and execvp that captures
|
|
// the output in real time but it's not currently needed in this project...
|
|
//
|
|
// Returns: n/a
|
|
//
|
|
//-------------------------------------------------------------------------------//
|
|
std::string api::cns::run(const std::string & cmd)
|
|
{
|
|
std::array <char, 256> buffer;
|
|
std::string result;
|
|
|
|
std::shared_ptr <FILE> sptr(popen(cmd.c_str(), "r"), pclose);
|
|
|
|
if (!sptr) return std::string("");
|
|
|
|
while (!feof(sptr.get()))
|
|
{
|
|
if (fgets(buffer.data(), 128, sptr.get()) != nullptr)
|
|
result += buffer.data();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|