Implement support for libedit

fixes #8776
This commit is contained in:
Gunnar Beutner 2015-03-17 10:42:46 +01:00
parent 70cbb5a624
commit 37736caa5c
13 changed files with 280 additions and 15 deletions

View File

@ -100,6 +100,12 @@ if(NOT YAJL_FOUND)
set(YAJL_LIBRARIES "yajl")
endif()
find_package(Editline)
set(HAVE_EDITLINE "${EDITLINE_FOUND}")
find_package(Termcap)
set(HAVE_TERMCAP "${TERMCAP_FOUND}")
include_directories(
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/lib
${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/lib
@ -108,7 +114,7 @@ include_directories(
#set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
if(APPLE)
set(CMAKE_INSTALL_NAME_DIR "@executable_path/../lib/icinga2")
set(CMAKE_INSTALL_NAME_DIR "@executable_path/..")
set(CMAKE_MACOSX_RPATH 0)
endif(APPLE)

View File

@ -32,6 +32,9 @@ parentheses):
* optional: PostgreSQL (postgresql-devel on RHEL, libpq-dev on Debian); set CMake
variable `ICINGA2_WITH_PGSQL` to `OFF` to disable this module
* optional: YAJL (yajl-devel on RHEL, libyajl-dev on Debian)
* optional: libedit (libedit-devel on RHEL, libedit-dev on Debian)
* optional: Termcap (libtermcap-devel on RHEL, libtermcap-dev on Debian) - only required
if libedit doesn't already link against termcap/ncurses
Note: RHEL5 ships an ancient flex version. Updated packages are available for
example from the repoforge buildtools repository.

View File

@ -9,6 +9,7 @@
#cmakedefine HAVE_LIBEXECINFO
#cmakedefine HAVE_CXXABI_H
#cmakedefine HAVE_NICE
#cmakedefine HAVE_EDITLINE
#cmakedefine ICINGA2_UNITY_BUILD

View File

@ -33,9 +33,23 @@ set_target_properties (
OUTPUT_NAME icinga2
)
if(WIN32)
set(InstallPath "${CMAKE_INSTALL_SBINDIR}")
else()
configure_file(icinga2.cmake ${CMAKE_CURRENT_BINARY_DIR}/icinga2 @ONLY)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/icinga2
DESTINATION ${CMAKE_INSTALL_SBINDIR}
PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
)
set(InstallPath "${CMAKE_INSTALL_LIBDIR}/icinga2/sbin")
endif()
install(
TARGETS icinga-app
RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}
RUNTIME DESTINATION ${InstallPath}
)
install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/log/icinga2\")")

20
icinga-app/icinga2.cmake Normal file
View File

@ -0,0 +1,20 @@
#!/bin/sh
ICINGA2_BIN=@CMAKE_INSTALL_FULL_LIBDIR@/icinga2/sbin/icinga2
if test "x`uname -s`" = "xLinux"; then
libedit_line=`ldd $ICINGA2_BIN 2>&1 | grep libedit`
if test $? -eq 0; then
libedit_path=`echo $libedit_line | cut -f3 -d' '`
if test -n "$libedit_path"; then
libdir=`dirname -- $libedit_path`
for libreadline_path in $libdir/libreadline.so*; do
break
done
if test -n "$libreadline_path"; then
export LD_PRELOAD="$libreadline_path:$LD_PRELOAD"
fi
fi
fi
fi
exec $ICINGA2_BIN $@

View File

@ -90,6 +90,8 @@ Recommends: monitoring-plugins
BuildRequires: libyajl-devel
%endif
%endif
BuildRequires: libedit-devel
BuildRequires: ncurses-devel
BuildRequires: openssl-devel
BuildRequires: gcc-c++
BuildRequires: libstdc++-devel
@ -453,6 +455,8 @@ exit 0
%exclude %{_libdir}/%{name}/libdb_ido_pgsql*
%dir %{_libdir}/%{name}
%{_libdir}/%{name}/*.so*
%dir %{_libdir}/%{name}/sbin
%{_libdir}/%{name}/sbin/%{name}
%{_datadir}/%{name}
%exclude %{_datadir}/%{name}/include
%{_mandir}/man8/%{name}.8.gz

View File

@ -27,10 +27,6 @@ INITIALIZE_ONCE(&Console::DetectType);
static ConsoleType l_ConsoleType = Console_Dumb;
ConsoleColorTag::ConsoleColorTag(int color)
: m_Color(color), m_ConsoleType(-1)
{ }
ConsoleColorTag::ConsoleColorTag(int color, ConsoleType consoleType)
: m_Color(color), m_ConsoleType(consoleType)
{ }

View File

@ -56,6 +56,8 @@ enum ConsoleColor
enum ConsoleType
{
Console_Autodetect = -1,
Console_Dumb,
#ifndef _WIN32
Console_VT100,
@ -67,8 +69,7 @@ enum ConsoleType
class I2_BASE_API ConsoleColorTag
{
public:
ConsoleColorTag(int color);
ConsoleColorTag(int color, ConsoleType consoleType);
ConsoleColorTag(int color, ConsoleType consoleType = Console_Autodetect);
friend I2_BASE_API std::ostream& operator<<(std::ostream& fp, const ConsoleColorTag& cct);

View File

@ -38,6 +38,16 @@ add_library(cli SHARED ${cli_SOURCES})
target_link_libraries(cli ${Boost_LIBRARIES} base config remote)
if(EDITLINE_FOUND)
target_link_libraries(cli ${EDITLINE_LIBRARIES})
include_directories(${EDITLINE_INCLUDE_DIR})
endif()
if(TERMCAP_FOUND)
target_link_libraries(cli ${TERMCAP_LIBRARIES})
include_directories(${TERMCAP_INCLUDE_DIR})
endif()
set_target_properties (
cli PROPERTIES
INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}/icinga2

View File

@ -26,7 +26,9 @@
#include "base/utility.hpp"
#include "base/networkstream.hpp"
#include <iostream>
#ifdef HAVE_EDITLINE
#include "cli/editline.hpp"
#endif /* HAVE_EDITLINE */
using namespace icinga;
namespace po = boost::program_options;
@ -84,20 +86,44 @@ int ConsoleCommand::Run(const po::variables_map& vm, const std::vector<std::stri
std::string command;
incomplete:
#ifdef HAVE_EDITLINE
ConsoleType console_type = Console_VT100;
std::ostringstream promptbuf;
std::ostream& os = promptbuf;
#else /* HAVE_EDITLINE */
ConsoleType console_type = Console_Autodetect;
std::ostream& os = std::cout;
#endif /* HAVE_EDITLINE */
std::cout << ConsoleColorTag(Console_ForegroundCyan)
<< fileName
<< ConsoleColorTag(Console_ForegroundRed);
os << ConsoleColorTag(Console_ForegroundCyan, console_type)
<< fileName
<< ConsoleColorTag(Console_ForegroundRed, console_type);
if (!continuation)
std::cout << " => ";
os << " => ";
else
std::cout << " .. ";
os << " .. ";
std::cout << ConsoleColorTag(Console_Normal);
os << ConsoleColorTag(Console_Normal, console_type);
#ifdef HAVE_EDITLINE
String prompt = promptbuf.str();
char *cline;
cline = readline(prompt.CStr());
if (!cline)
break;
add_history(cline);
std::string line = cline;
free(cline);
#else /* HAVE_EDITLINE */
std::string line;
std::getline(std::cin, line);
#endif /* HAVE_EDITLINE */
if (!command.empty())
command += "\n";

30
lib/cli/editline.hpp Normal file
View File

@ -0,0 +1,30 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
* *
* 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 2 *
* 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, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef EDITLINE_H
#define EDITLINE_H
extern "C" {
char *readline(const char *prompt);
int add_history(const char *line);
}
#endif /* EDITLINE_H */

86
third-party/cmake/FindEditline.cmake vendored Normal file
View File

@ -0,0 +1,86 @@
# Copyright (c) 2014, Matthias Vallentin
# 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.
# Tries to find editline headers and libraries
#
# Usage of this module as follows:
#
# find_package(Editline)
#
# Variables used by this module, they can change the default behaviour and need
# to be set before calling find_package:
#
# EDITLINE_ROOT_DIR Set this variable to the root installation of
# editline if the module has problems finding
# the proper installation path.
#
# Variables defined by this module:
#
# EDITLINE_FOUND System has Editline libs/headers
# EDITLINE_LIBRARIES The Editline libraries
# EDITLINE_INCLUDE_DIR The location of Editline headers
# EDITLINE_VERSION The full version of Editline
# EDITLINE_VERSION_MAJOR The version major of Editline
# EDITLINE_VERSION_MINOR The version minor of Editline
find_path(EDITLINE_INCLUDE_DIR
NAMES histedit.h
HINTS ${EDITLINE_ROOT_DIR}/include)
if (EDITLINE_INCLUDE_DIR)
file(STRINGS ${EDITLINE_INCLUDE_DIR}/histedit.h editline_header REGEX "^#define.LIBEDIT_[A-Z]+.*$")
string(REGEX REPLACE ".*#define.LIBEDIT_MAJOR[ \t]+([0-9]+).*" "\\1" EDITLINE_VERSION_MAJOR "${editline_header}")
string(REGEX REPLACE ".*#define.LIBEDIT_MINOR[ \t]+([0-9]+).*" "\\1" EDITLINE_VERSION_MINOR "${editline_header}")
set(EDITLINE_VERSION_MAJOR ${EDITLINE_VERSION_MAJOR} CACHE STRING "" FORCE)
set(EDITLINE_VERSION_MINOR ${EDITLINE_VERSION_MINOR} CACHE STRING "" FORCE)
set(EDITLINE_VERSION ${EDITLINE_VERSION_MAJOR}.${EDITLINE_VERSION_MINOR}
CACHE STRING "" FORCE)
endif ()
find_library(EDITLINE_LIBRARIES
NAMES edit
HINTS ${EDITLINE_ROOT_DIR}/lib)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
Editline
DEFAULT_MSG
EDITLINE_LIBRARIES
EDITLINE_INCLUDE_DIR)
mark_as_advanced(
EDITLINE_ROOT_DIR
EDITLINE_LIBRARIES
EDITLINE_INCLUDE_DIR
EDITLINE_VERSION
EDITLINE_VERSION_MAJOR
EDITLINE_VERSION_MINOR
)

68
third-party/cmake/FindTermcap.cmake vendored Normal file
View File

@ -0,0 +1,68 @@
# Copyright (c) 2014, Matthias Vallentin
# 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.
# Tries to find termcap headers and libraries
#
# Usage of this module as follows:
#
# find_package(Termcap)
#
# Variables used by this module, they can change the default behaviour and need
# to be set before calling find_package:
#
# TERMCAP_ROOT_DIR Set this variable to the root installation of
# termcap if the module has problems finding
# the proper installation path.
#
# Variables defined by this module:
#
# TERMCAP_FOUND System has Termcap libs/headers
# TERMCAP_LIBRARIES The Termcap libraries
# TERMCAP_INCLUDE_DIR The location of Termcap headers
find_path(TERMCAP_INCLUDE_DIR
NAMES termcap.h
HINTS ${TERMCAP_ROOT_DIR}/include)
find_library(TERMCAP_LIBRARIES
NAMES termcap ncurses
HINTS ${TERMCAP_ROOT_DIR}/lib)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
Termcap
DEFAULT_MSG
TERMCAP_LIBRARIES
TERMCAP_INCLUDE_DIR)
mark_as_advanced(
TERMCAP_ROOT_DIR
TERMCAP_LIBRARIES
TERMCAP_INCLUDE_DIR
)