diff --git a/.gitignore b/.gitignore index a796d4d..25acb3e 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,5 @@ Makefile # Editor Backup Files *~ + +.idea diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..25612ad --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,69 @@ +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") +cmake_minimum_required(VERSION 3.6) +project(bareos-filedaemon-pgsql VERSION 2.2.0.1) + +set(CMAKE_CXX_STANDARD 11) +find_package(PostgreSQL REQUIRED) +find_package(Bareos REQUIRED) + +set(SOURCES + keylist.c + keylist.h + parseconfig.c + parseconfig.h + pgsql-archlog.c + pgsql-fd.c + pgsql-restore.c + pgsqllib.c + pgsqllib.h + pluglib.c + pluglib.h + utils.c + utils.h) +foreach (F ${SOURCES}) + if (F MATCHES ".c$") + set_source_files_properties(${F} PROPERTIES LANGUAGE CXX) + endif () +endforeach () +add_library(pgsql-fd MODULE + pgsql-fd.c + keylist.c keylist.h + parseconfig.c parseconfig.h + pluglib.c pluglib.h + utils.c utils.h + pgsql-tables.sql pgsql-grants.sql pgsql.conf + ) +set_target_properties(pgsql-fd PROPERTIES PREFIX "") +target_link_libraries(pgsql-fd PUBLIC PQ bareos) + +add_executable(pgsql-archlog pgsql-archlog.c parseconfig.c keylist.c pgsqllib.c utils.c pluglib.c) +target_link_libraries(pgsql-archlog PUBLIC PQ bareos) + +add_executable(pgsql-restore pgsql-restore.c parseconfig.c keylist.c pgsqllib.c utils.c pluglib.c) +target_link_libraries(pgsql-restore PUBLIC PQ bareos) + +get_filename_component ( RPATH ${LIBBAREOS_LA} DIRECTORY ) +set_target_properties ( pgsql-restore pgsql-archlog pgsql-fd PROPERTIES INSTALL_RPATH "${RPATH}" ) + +install(TARGETS pgsql-fd pgsql-archlog pgsql-restore LIBRARY DESTINATION ${BAREOS_PLUGIN_DIR} RUNTIME DESTINATION sbin) +install(FILES pgsql.conf DESTINATION etc/bareos/ RENAME pgsql.conf.example) + +list(APPEND CPACK_SOURCE_IGNORE_FILES "/cmake-build.*/") +list(APPEND CPACK_SOURCE_IGNORE_FILES "/.git/") +list(APPEND CPACK_SOURCE_IGNORE_FILES "/.idea/") +set(CPACK_PACKAGE_VERSION_MAJOR ${bareos-filedaemon-pgsql_VERSION_MAJOR}) +set(CPACK_PACKAGE_VERSION_MINOR ${bareos-filedaemon-pgsql_VERSION_MINOR}) +set(CPACK_PACKAGE_VERSION_PATCH ${bareos-filedaemon-pgsql_VERSION_PATCH}) +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "PostgreSQL online backup and recovery plugin (c) Inteos Sp. z o.o.") +set(CPACK_BINARY_TGZ ON) +set(CPACK_BINARY_RPM ON) +set(CPACK_BINARY_STGZ OFF) +set(CPACK_BINARY_TZ OFF) +set(CPACK_SOURCE_TGZ ON) +set(CPACK_SOURCE_ZTGZ OFF) +set(CPACK_SOURCE_TBZ2 OFF) +set(CPACK_SOURCE_TXZ OFF) +set(CPACK_SOURCE_TZ OFF) +set(CPACK_PROJECT_CONFIG_FILE ${CMAKE_BINARY_DIR}/CPack.cmake) +include(CPack) +configure_file(CPack.cmake.in CPack.cmake @ONLY) diff --git a/CPack.cmake.in b/CPack.cmake.in new file mode 100644 index 0000000..3819679 --- /dev/null +++ b/CPack.cmake.in @@ -0,0 +1,7 @@ +set(CPACK_RPM_PACKAGE_GROUP Productivity/Archiving/Backup) +set(CPACK_RPM_PACKAGE_LICENSE AGPLv3) +set(CPACK_RPM_PACKAGE_RELEASE "@bareos-filedaemon-pgsql_VERSION_TWEAK@") +set(CPACK_RPM_FILE_NAME RPM-DEFAULT) +set(CPACK_RPM_PACKAGE_RELEASE_DIST ON) +set(CPACK_RPM_PACKAGE_URL https://github.com/bareos/contrib-pgsql-plugin) +set(CPACK_RPM_PACKAGE_REQUIRES bareos-filedaemon) diff --git a/cmake/FindBareos.cmake b/cmake/FindBareos.cmake new file mode 100644 index 0000000..9e8f23a --- /dev/null +++ b/cmake/FindBareos.cmake @@ -0,0 +1,40 @@ +include(GNUInstallDirs) +list(APPEND SUFFIXES bareos) + +find_file(LIBBAREOS_H_LOCATION bareos.h HINTS ${INCLUDE_DIR} PATH_SUFFIXES ${SUFFIXES} DOC "Location of the bareos header") +get_filename_component(LIBBAREOS_H_DIR ${LIBBAREOS_H_LOCATION} DIRECTORY) +set(LIBBAREOS_INCLUDE_DIR ${LIBBAREOS_H_DIR} CACHE PATH "bareos include dir") + +list(APPEND SUFFIXES lib lib64 lib/bareos lib64/bareos) +set(BAREOS_PLUGIN_DIR ${CMAKE_INSTALL_LIBDIR}/bareos/plugins CACHE PATH "bareos plugins dir") + +include(ParseLibtoolFile) +parse_libtool(FILE libbareos.la QUIET PREFIX LIBBAREOS_LA HINTS ${CMAKE_SYSTEM_PREFIX_PATH} PATH_SUFFIXES ${SUFFIXES} DOC "Location of the bareos lib file") + +if (LIBBAREOS_LA_dlname) + if (LIBBAREOS_LA_dlname MATCHES "([0-9]+.[0-9]+.[0-9]+)") + set(BAREOS_VERSION ${CMAKE_MATCH_1}) + endif () +endif () + +find_library(LIBBAREOS_LOCATION ${LIBBAREOS_LA_dlname} PATH_SUFFIXES ${SUFFIXES} DOC "Location of the bareos lib") + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Bareos + FOUND_VAR Bareos_FOUND + REQUIRED_VARS LIBBAREOS_LOCATION LIBBAREOS_H_DIR + VERSION_VAR BAREOS_VERSION + ) + +get_filename_component(LIBBAREOS_DIR ${LIBBAREOS_LOCATION} DIRECTORY) +if (NOT "${CMAKE_INSTALL_PREFIX}/${BAREOS_PLUGIN_DIR}" STREQUAL "${LIBBAREOS_DIR}/plugins") + message(WARNING "${CMAKE_INSTALL_PREFIX}/${BAREOS_PLUGIN_DIR} != ${LIBBAREOS_DIR}/plugins") +endif () + +add_library(bareos IMPORTED SHARED GLOBAL) +set_target_properties(bareos PROPERTIES + IMPORTED_LOCATION "${LIBBAREOS_LOCATION}" + INTERFACE_INCLUDE_DIRECTORIES "${LIBBAREOS_INCLUDE_DIR}" + INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${LIBBAREOS_INCLUDE_DIR}" + INTERFACE_COMPILE_DEFINITIONS "${DEFINES}") +target_link_libraries(bareos INTERFACE ${LIBBAREOS_LA_LIBS}) diff --git a/cmake/FindPostgreSQL.cmake b/cmake/FindPostgreSQL.cmake new file mode 100644 index 0000000..2b4b737 --- /dev/null +++ b/cmake/FindPostgreSQL.cmake @@ -0,0 +1,88 @@ +if ( NOT LIBPQ_H_LOCATION OR NOT LIBPQ_LOCATION ) + find_file ( PG_CONFIG pg_config DOC "Location of the pg_config executable" ) + if ( PG_CONFIG ) + execute_process ( COMMAND ${PG_CONFIG} --includedir --includedir-server + OUTPUT_VARIABLE INCLUDE_DIR + RESULT_VARIABLE EXIT_CODE + OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET ) + execute_process ( COMMAND ${PG_CONFIG} --libdir + OUTPUT_VARIABLE LIB_DIR + RESULT_VARIABLE EXIT_CODE + OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET ) + execute_process ( COMMAND ${PG_CONFIG} --version + OUTPUT_VARIABLE VER + RESULT_VARIABLE EXIT_CODE + OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET ) + if ( ${EXIT_CODE} EQUAL 0 ) + string ( REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" PG_VERSION ${VER} ) + set ( LIBPQ_VERSION ${PG_VERSION} CACHE STRING "libpq version" FORCE ) + endif () + string ( REGEX REPLACE "\n" ";" INCLUDE_DIR ${INCLUDE_DIR} ) + endif () + if ( NOT INCLUDE_DIR OR NOT LIB_DIR ) + file ( GLOB DIRS /Library/PostgreSQL/* ) + foreach ( D ${DIRS} ) + list ( APPEND HINTS ${D} ) + endforeach () + file ( GLOB DIRS /opt/local/include/postgresql* ) + foreach ( D ${DIRS} ) + list ( APPEND HINTS ${D} ) + endforeach () + list ( APPEND SUFFIXES /include/postgresql/server/ ) + list ( APPEND SUFFIXES /server/ ) + set ( INCLUDE_DIR ${DIRS} ) + set ( LIB_DIR ${DIRS} ) + endif () + find_file ( LIBPQ_H_LOCATION libpq-fe.h HINTS ${INCLUDE_DIR} PATH_SUFFIXES ${SUFFIXES} DOC "Location of the pq lib header" ) + find_library ( LIBPQ_LOCATION pq HINTS ${LIB_DIR} PATH_SUFFIXES "/lib" DOC "Location of the pq lib" ) + get_filename_component ( LIBPQ_INCLUDE_DIR ${LIBPQ_H_LOCATION} DIRECTORY ) + set ( LIBPQ_INCLUDE_DIR ${LIBPQ_INCLUDE_DIR} CACHE PATH "libpq include dir" FORCE ) +endif () +include ( CMakePushCheckState ) +include ( CheckCXXSourceCompiles ) +include ( CheckCXXSourceRuns ) + +cmake_push_check_state ( RESET ) +set ( CMAKE_REQUIRED_INCLUDES ${LIBPQ_INCLUDE_DIR} ) +check_cxx_source_compiles ( " +#include +int main() { + (void)PGRES_SINGLE_TUPLE; +} +" LIBPQ_HAS_PGRES_SINGLE_TUPLE ) +if ( LIBPQ_HAS_PGRES_SINGLE_TUPLE ) + list ( APPEND DEFINES LIBPQ_HAS_PGRES_SINGLE_TUPLE ) +endif () +check_cxx_source_compiles ( " +#include +int main() { + (void)PGRES_POLLING_ACTIVE; +} +" LIBPQ_HAS_PGRES_POLLING_ACTIVE ) +if ( LIBPQ_HAS_PGRES_POLLING_ACTIVE ) + list ( APPEND DEFINES LIBPQ_HAS_PGRES_POLLING_ACTIVE ) +endif () +set ( CMAKE_REQUIRED_LIBRARIES ${LIBPQ_LOCATION} ) +check_cxx_source_runs ( " +#include +int main() { + return PQconninfoParse( \"postgresql://localhost\", NULL ) ? 0 : 1; +}" LIBPQ_SUPPORTS_URL ) +if ( LIBPQ_SUPPORTS_URL ) + list ( APPEND DEFINES LIBPQ_SUPPORTS_URL ) +endif () +cmake_pop_check_state () + +include ( FindPackageHandleStandardArgs ) +find_package_handle_standard_args ( PostgreSQL + FOUND_VAR PostgreSQL_FOUND + REQUIRED_VARS LIBPQ_LOCATION LIBPQ_H_LOCATION + VERSION_VAR PG_VERSION + ) + +add_library ( PQ IMPORTED SHARED GLOBAL ) +set_target_properties ( PQ PROPERTIES + IMPORTED_LOCATION "${LIBPQ_LOCATION}" + INTERFACE_INCLUDE_DIRECTORIES "${LIBPQ_INCLUDE_DIR}" + INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${LIBPQ_INCLUDE_DIR}" + INTERFACE_COMPILE_DEFINITIONS "${DEFINES}" ) diff --git a/cmake/ParseLibtoolFile.cmake b/cmake/ParseLibtoolFile.cmake new file mode 100644 index 0000000..9e35ec1 --- /dev/null +++ b/cmake/ParseLibtoolFile.cmake @@ -0,0 +1,60 @@ +#include(CMakePrintHelpers) + +function(parse_libtool) + cmake_parse_arguments(LA "QUIET" "FILE;PREFIX;DOC" "HINTS;PATHS;PATH_SUFFIXES" ${ARGN}) + if (NOT LA_FILE) + message(FATAL_ERROR "No filename!") + endif () + if (LA_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown arguments ${LA_UNPARSED_ARGUMENTS}") + endif () +# cmake_print_variables(LA_PREFIX LA_FILE LA_DOC LA_HINTS LA_PATHS LA_PATH_SUFFIXES) + + if (NOT LA_QUIET) + message(STATUS "Looking for ${LA_FILE}") + endif () + + if (EXISTS ${LA_FILE}) + set(${LA_PREFIX} ${LA_FILE}) + else () + find_file(${LA_PREFIX} ${LA_FILE} HINTS ${LA_HINTS} PATHS ${LA_PATHS} PATH_SUFFIXES ${LA_PATH_SUFFIXES}) + endif () + + if (${LA_PREFIX}) + if (NOT LA_QUIET) + message(STATUS "Found ${LA_FILE} at ${${LA_PREFIX}}") + endif () + file(STRINGS ${${LA_PREFIX}} LINES) + foreach (L ${LINES}) + if (L MATCHES "^([a-zA-Z_]+)='?([^']*)'?") + set(NAME ${LA_PREFIX}_${CMAKE_MATCH_1}) + string(STRIP "${CMAKE_MATCH_2}" ${NAME}) + set(${NAME} ${${NAME}} PARENT_SCOPE) + endif () + endforeach () + set(NAME ${LA_PREFIX}_dependency_libs) + if (${NAME}) + libtool_deps_to_libs("${${NAME}}" ${LA_PREFIX}_LIBS) + endif () + else (NOT LA_QUIET) + message(STATUS "did not find ${LA_FILE}") + endif () + set(${LA_PREFIX}_LIBS "${${LA_PREFIX}_LIBS}" PARENT_SCOPE) + set(${LA_PREFIX}_LIBS "${${LA_PREFIX}_LIBS}" CACHE STRING "Libraries required to use ${LA_FILE}") + # cmake_print_variables(${LA_PREFIX} ${LA_PREFIX}_LIBS) +endfunction() + +function(libtool_deps_to_libs LIBS OUT) + set(OLIBS "") + separate_arguments(LIBS) + foreach (L ${LIBS}) + if (L MATCHES ".la$") + string(MAKE_C_IDENTIFIER ${L} PREFIX) + parse_libtool(FILE ${L} PREFIX ${PREFIX} QUIET) + list(APPEND OLIBS "${${PREFIX}_dlname};${${PREFIX}_LIBS}") + else () + list(APPEND OLIBS "${L}") + endif () + endforeach () + set(${OUT} ${OLIBS} PARENT_SCOPE) +endfunction() diff --git a/pgsql-fd.c b/pgsql-fd.c index 2564862..d29957d 100644 --- a/pgsql-fd.c +++ b/pgsql-fd.c @@ -578,7 +578,8 @@ bRC pg_internal_conn ( bpContext *ctx, const char * sql ){ db = PQconnectdb ( connstring ); status = PQstatus ( db ); if ( status == CONNECTION_BAD ){ - DMSG0 ( ctx, D1, "pg_internal_conn.conndb failed!\n" ); + char *error = PQerrorMessage(db); + DMSG1 ( ctx, D1, "pg_internal_conn.conndb failed %s!\n", error ); JMSG0 ( ctx, M_WARNING, "pg_internal_conn.conndb failed!\n" ); /* not all goes ok so we have to raise it, but it is not a critical error, * it should be handled by calling function */ diff --git a/utils.h b/utils.h index 9b1f910..c16d2f1 100644 --- a/utils.h +++ b/utils.h @@ -9,6 +9,8 @@ #ifndef _UTIL_H_ #define _UTIL_H_ +#include + #ifdef __cplusplus extern "C" { #endif