diff options
129 files changed, 6734 insertions, 179 deletions
diff --git a/.travis.yml b/.travis.yml index cb3d09c671c..83e13961c31 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ before_install: - sudo apt-get -qq update - sudo apt-get -qq install build-essential libtool gcc-4.8 g++-4.8 make cmake openssl - sudo apt-get -qq install libssl-dev libmysqlclient15-dev libmysql++-dev libreadline6-dev zlib1g-dev libbz2-dev libzmq3-dev - - sudo apt-get -qq install libboost1.55-dev libboost-thread1.55-dev libboost-filesystem1.55-dev libboost-system1.55-dev libboost-program-options1.55-dev + - sudo apt-get -qq install libboost1.55-dev libboost-thread1.55-dev libboost-filesystem1.55-dev libboost-system1.55-dev libboost-program-options1.55-dev libboost-iostreams1.55-dev install: - mysql -uroot -e 'create database test_mysql;' @@ -26,7 +26,7 @@ script: - mysql -utrinity -ptrinity auth < sql/base/auth_database.sql - mysql -utrinity -ptrinity characters < sql/base/characters_database.sql - mysql -utrinity -ptrinity world < sql/base/dev/world_database.sql - - mysql -utrinity -ptrinity hotfixes < sql/base/dev/hotfixes_database.sql + - mysql -utrinity -ptrinity hotfixes < sql/base/hotfixes_database.sql - cat sql/updates/world/*.sql | mysql -utrinity -ptrinity world - cat sql/updates/hotfixes/*.sql | mysql -utrinity -ptrinity hotfixes - mysql -uroot < sql/create/drop_mysql.sql diff --git a/cmake/macros/ConfigureBoost.cmake b/cmake/macros/ConfigureBoost.cmake index 4147eeef2f5..190151af155 100644 --- a/cmake/macros/ConfigureBoost.cmake +++ b/cmake/macros/ConfigureBoost.cmake @@ -25,7 +25,7 @@ if(WIN32) add_definitions(-D_WIN32_WINNT=${ver}) endif() -find_package(Boost 1.49 REQUIRED system filesystem thread program_options) +find_package(Boost 1.49 REQUIRED system filesystem thread program_options iostreams) add_definitions(-DBOOST_DATE_TIME_NO_LIB) add_definitions(-DBOOST_REGEX_NO_LIB) add_definitions(-DBOOST_CHRONO_NO_LIB) @@ -35,7 +35,7 @@ add_definitions(-DBOOST_CHRONO_NO_LIB) include (CheckCXXSourceCompiles) set(CMAKE_REQUIRED_INCLUDES ${Boost_INCLUDE_DIR}) -set(CMAKE_REQUIRED_LIBRARIES ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY}) +set(CMAKE_REQUIRED_LIBRARIES ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_IOSTREAMS_LIBRARY}) set(CMAKE_REQUIRED_FLAGS "-std=c++11") unset(boost_filesystem_copy_links_without_NO_SCOPED_ENUM CACHE) check_cxx_source_compiles(" diff --git a/cmake/macros/FindMySQL.cmake b/cmake/macros/FindMySQL.cmake index 990f4918d6a..6b00510ba42 100644 --- a/cmake/macros/FindMySQL.cmake +++ b/cmake/macros/FindMySQL.cmake @@ -5,6 +5,7 @@ # This module defines # MYSQL_INCLUDE_DIR, where to find mysql.h # MYSQL_LIBRARIES, the libraries to link against to connect to MySQL +# MYSQL_EXECUTABLE, the MySQL executable. # MYSQL_FOUND, if false, you cannot build anything that requires MySQL. # also defined, but not for general use are @@ -182,6 +183,65 @@ else( NOT WIN32 ) set( MYSQL_EXTRA_LIBRARIES "" ) endif( NOT WIN32 ) +if( UNIX ) + find_program(MYSQL_EXECUTABLE mysql + PATHS + ${MYSQL_CONFIG_PREFER_PATH} + /usr/local/mysql/bin/ + /usr/local/bin/ + /usr/bin/ + DOC + "path to your mysql binary." + ) +endif( UNIX ) + +if( WIN32 ) + find_program(MYSQL_EXECUTABLE mysql + PATHS + "C:/Program Files/MySQL/MySQL Server 5.6/bin" + "C:/Program Files/MySQL/MySQL Server 5.6/bin/opt" + "C:/Program Files/MySQL/MySQL Server 5.5/bin" + "C:/Program Files/MySQL/MySQL Server 5.5/bin/opt" + "C:/Program Files/MySQL/MySQL Server 5.1/bin" + "C:/Program Files/MySQL/MySQL Server 5.1/bin/opt" + "C:/Program Files/MySQL/MySQL Server 5.0/bin" + "C:/Program Files/MySQL/MySQL Server 5.0/bin/opt" + "C:/Program Files/MySQL/bin" + "C:/Program Files (x86)/MySQL/MySQL Server 5.6/bin" + "C:/Program Files (x86)/MySQL/MySQL Server 5.6/bin/opt" + "C:/Program Files (x86)/MySQL/MySQL Server 5.5/bin" + "C:/Program Files (x86)/MySQL/MySQL Server 5.5/bin/opt" + "C:/Program Files (x86)/MySQL/MySQL Server 5.1/bin" + "C:/Program Files (x86)/MySQL/MySQL Server 5.1/bin/opt" + "C:/Program Files (x86)/MySQL/MySQL Server 5.0/bin" + "C:/Program Files (x86)/MySQL/MySQL Server 5.0/bin/opt" + "C:/Program Files (x86)/MySQL/bin" + "C:/MySQL/bin/debug" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.6;Location]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.6;Location]/bin/opt" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.5;Location]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.5;Location]/bin/opt" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.1;Location]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.1;Location]/bin/opt" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.0;Location]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.0;Location]/bin/opt" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.6;Location]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.6;Location]/bin/opt" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.5;Location]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.5;Location]/bin/opt" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.1;Location]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.1;Location]/bin/opt" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.0;Location]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.0;Location]/bin/opt" + "$ENV{ProgramFiles}/MySQL/*/bin/opt" + "$ENV{SystemDrive}/MySQL/*/bin/opt" + "c:/msys/local/include" + "$ENV{MYSQL_ROOT}/bin" + DOC + "path to your mysql binary." + ) +endif( WIN32 ) + if( MYSQL_LIBRARY ) if( MYSQL_INCLUDE_DIR ) set( MYSQL_FOUND 1 ) @@ -190,7 +250,10 @@ if( MYSQL_LIBRARY ) else( MYSQL_INCLUDE_DIR ) message(FATAL_ERROR "Could not find MySQL headers! Please install the development libraries and headers") endif( MYSQL_INCLUDE_DIR ) - mark_as_advanced( MYSQL_FOUND MYSQL_LIBRARY MYSQL_EXTRA_LIBRARIES MYSQL_INCLUDE_DIR ) + if( MYSQL_EXECUTABLE ) + message(STATUS "Found MySQL executable: ${MYSQL_EXECUTABLE}") + endif( MYSQL_EXECUTABLE ) + mark_as_advanced( MYSQL_FOUND MYSQL_LIBRARY MYSQL_EXTRA_LIBRARIES MYSQL_INCLUDE_DIR MYSQL_EXECUTABLE) else( MYSQL_LIBRARY ) message(FATAL_ERROR "Could not find the MySQL libraries! Please install the development libraries and headers") endif( MYSQL_LIBRARY ) diff --git a/dep/PackageList.txt b/dep/PackageList.txt index 0bee1e14d92..2290a1980ec 100644 --- a/dep/PackageList.txt +++ b/dep/PackageList.txt @@ -4,6 +4,10 @@ Boost http://www.boost.org Version: 1.55 +Boost Process (Proposed for boost, but its not an official part of it yet. Used to start child processes.) + http://www.highscore.de/boost/process0.5/ + Version: 0.5 + bzip2 (a freely available, patent free, high-quality data compressor) http://www.bzip.org/ Version: 1.0.6 diff --git a/dep/process/License.txt b/dep/process/License.txt new file mode 100644 index 00000000000..36b7cd93cdf --- /dev/null +++ b/dep/process/License.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/dep/process/Readme.txt b/dep/process/Readme.txt new file mode 100644 index 00000000000..ada7cf74974 --- /dev/null +++ b/dep/process/Readme.txt @@ -0,0 +1,6 @@ +Boost.Process (Not part of the official boost libraries yet) +================================================================ +Its used to start child processes within the application. + +Website: http://www.highscore.de/boost/process0.5/ +Downloaded from: http://www.highscore.de/boost/process0.5/process.zip diff --git a/dep/process/boost/process.hpp b/dep/process/boost/process.hpp new file mode 100644 index 00000000000..2271e9b49e7 --- /dev/null +++ b/dep/process/boost/process.hpp @@ -0,0 +1,22 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011 Jeff Flinn, Boris Schaeling +// Copyright (c) 2012 Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/** + * \file boost/process.hpp + * + * Convenience header which includes all public Boost.Process header files. + */ + +#ifndef BOOST_PROCESS_HPP +#define BOOST_PROCESS_HPP + +#include <boost/process/all.hpp> + +#endif diff --git a/dep/process/boost/process/all.hpp b/dep/process/boost/process/all.hpp new file mode 100644 index 00000000000..234dd05d4c1 --- /dev/null +++ b/dep/process/boost/process/all.hpp @@ -0,0 +1,30 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/** + * \file boost/process/all.hpp + * + * Convenience header which includes all public Boost.Process header files. + */ + +#ifndef BOOST_PROCESS_ALL_HPP +#define BOOST_PROCESS_ALL_HPP + +#include <boost/process/child.hpp> +#include <boost/process/create_pipe.hpp> +#include <boost/process/execute.hpp> +#include <boost/process/executor.hpp> +#include <boost/process/initializers.hpp> +#include <boost/process/pipe.hpp> +#include <boost/process/search_path.hpp> +#include <boost/process/shell_path.hpp> +#include <boost/process/terminate.hpp> +#include <boost/process/wait_for_exit.hpp> + +#endif diff --git a/dep/process/boost/process/child.hpp b/dep/process/boost/process/child.hpp new file mode 100644 index 00000000000..ec129fc9367 --- /dev/null +++ b/dep/process/boost/process/child.hpp @@ -0,0 +1,74 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/** + * \file boost/process/child.hpp + * + * Defines a child process class. + */ + +#ifndef BOOST_PROCESS_CHILD_HPP +#define BOOST_PROCESS_CHILD_HPP + +#include <boost/process/config.hpp> + +#include BOOST_PROCESS_PLATFORM_PROMOTE_PATH(child) +BOOST_PROCESS_PLATFORM_PROMOTE_NAMESPACE(child) + +#if defined(BOOST_PROCESS_DOXYGEN) +namespace boost { namespace process { + +/** + * Represents a child process. + * + * On Windows child is movable but non-copyable. The destructor + * automatically closes handles to the child process. + */ +struct child +{ + /** + * Process information. + * + * \remark <em>Windows only.</em> + */ + PROCESS_INFORMATION proc_info; + + /** + * Constructor. + * + * \remark <em>Windows only.<em/> + */ + explicit child(const PROCESS_INFORMATION &pi) : proc_info(pi) {} + + /** + * Returns the process handle. + * + * \remark <em>Windows only.</em> + */ + HANDLE process_handle() const { return proc_info.hProcess; } + + /** + * Process identifier. + * + * \remark <em>POSIX only.</em> + */ + pid_t pid; + + /** + * Constructor. + * + * \remark <em>POSIX only.</em> + */ + explicit child(pid_t p) : pid(p) {} +}; + +}} +#endif + +#endif diff --git a/dep/process/boost/process/config.hpp b/dep/process/boost/process/config.hpp new file mode 100644 index 00000000000..7aae4d3ca4f --- /dev/null +++ b/dep/process/boost/process/config.hpp @@ -0,0 +1,82 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/** + * \file boost/process/config.hpp + * + * Defines various macros. + */ + +#ifndef BOOST_PROCESS_CONFIG_HPP +#define BOOST_PROCESS_CONFIG_HPP + +#include <boost/config.hpp> +#include <boost/system/config.hpp> +#include <boost/system/error_code.hpp> +#include <boost/system/system_error.hpp> + +#if defined(BOOST_POSIX_API) +# include <errno.h> +# define BOOST_PROCESS_LAST_ERROR errno +# define BOOST_PROCESS_PLATFORM posix +#elif defined(BOOST_WINDOWS_API) +# include <Windows.h> +# define BOOST_PROCESS_LAST_ERROR GetLastError() +# define BOOST_PROCESS_PLATFORM windows +#endif + +/** \cond */ +#define BOOST_PROCESS_PLATFORM_PROMOTE_PATH(COMPONENT) \ + <boost/process/BOOST_PROCESS_PLATFORM/COMPONENT.hpp> +#define BOOST_PROCESS_PLATFORM_PROMOTE_NAMESPACE(COMPONENT) \ + namespace boost { namespace process { using BOOST_PROCESS_PLATFORM::COMPONENT; }} +#define BOOST_PROCESS_PLATFORM_PROMOTE_INITIALIZERS_NAMESPACE \ + namespace boost { namespace process { namespace initializers { \ + using namespace boost::process::BOOST_PROCESS_PLATFORM::initializers; }}} +/** \endcond */ + +#if defined(BOOST_PROCESS_DOXYGEN) +/** + * \def BOOST_POSIX_API + * + * This macro is defined on POSIX. + */ +#define BOOST_POSIX_API +/** + * \def BOOST_WINDOWS_API + * + * This macro is defined on Windows. + */ +#define BOOST_WINDOWS_API +#endif + +/** + * \def BOOST_PROCESS_THROW(EX) + * + * Defines how exceptions are thrown. Set this macro for example + * to \c BOOST_THROW_EXCEPTION if you like to use Boost.Exception. + */ +#define BOOST_PROCESS_THROW(EX) throw EX + +/** \cond */ +#define BOOST_PROCESS_SOURCE_LOCATION \ + "in file '" __FILE__ "', line " BOOST_STRINGIZE(__LINE__) ": " + +#define BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(what) \ + BOOST_PROCESS_THROW(boost::system::system_error( \ + boost::system::error_code(BOOST_PROCESS_LAST_ERROR, \ + boost::system::system_category()), \ + BOOST_PROCESS_SOURCE_LOCATION what)) + +#define BOOST_PROCESS_RETURN_LAST_SYSTEM_ERROR(ec) \ + ec = boost::system::error_code(BOOST_PROCESS_LAST_ERROR, \ + boost::system::system_category()) +/** \endcond */ + +#endif diff --git a/dep/process/boost/process/create_pipe.hpp b/dep/process/boost/process/create_pipe.hpp new file mode 100644 index 00000000000..6c34ecf44b1 --- /dev/null +++ b/dep/process/boost/process/create_pipe.hpp @@ -0,0 +1,48 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/** + * \file boost/process/create_pipe.hpp + * + * Defines a function to create a pipe. + */ + +#ifndef BOOST_PROCESS_CREATE_PIPE_HPP +#define BOOST_PROCESS_CREATE_PIPE_HPP + +#include <boost/process/config.hpp> + +#include BOOST_PROCESS_PLATFORM_PROMOTE_PATH(create_pipe) +BOOST_PROCESS_PLATFORM_PROMOTE_NAMESPACE(create_pipe) + +#if defined(BOOST_PROCESS_DOXYGEN) +namespace boost { namespace process { + +/** + * Creates an anonymous pipe. + * + * \note On Windows anonymous pipes don't support + * asynchronous I/O. + * + * \throws boost::system::system_error in case of an error + */ +pipe create_pipe(); + +/** + * Creates an anonymous pipe. + * + * \note On Windows anonymous pipes don't support + * asynchronous I/O. + */ +pipe create_pipe(boost::system::error_code &ec); + +}} +#endif + +#endif diff --git a/dep/process/boost/process/execute.hpp b/dep/process/boost/process/execute.hpp new file mode 100644 index 00000000000..608831171e9 --- /dev/null +++ b/dep/process/boost/process/execute.hpp @@ -0,0 +1,38 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/** + * \file boost/process/execute.hpp + * + * Defines a function to execute a program. + */ + +#ifndef BOOST_PROCESS_EXECUTE_HPP +#define BOOST_PROCESS_EXECUTE_HPP + +#include <boost/process/config.hpp> + +#include BOOST_PROCESS_PLATFORM_PROMOTE_PATH(execute) +BOOST_PROCESS_PLATFORM_PROMOTE_NAMESPACE(execute) + +#if defined(BOOST_PROCESS_DOXYGEN) +namespace boost { namespace process { + +/** + * Starts a program. + * + * \tparam initializers define what and how the program is started + */ +template <class Initializer, class... Initializers> +child execute(const Initializer &initializer, const Initializers... &initializers); + +}} +#endif + +#endif diff --git a/dep/process/boost/process/executor.hpp b/dep/process/boost/process/executor.hpp new file mode 100644 index 00000000000..905d7f84cc7 --- /dev/null +++ b/dep/process/boost/process/executor.hpp @@ -0,0 +1,176 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/** + * \file boost/process/executor.hpp + * + * Defines an executor which can create child processes. + */ + +#ifndef BOOST_PROCESS_EXECUTOR_HPP +#define BOOST_PROCESS_EXECUTOR_HPP + +#include <boost/process/config.hpp> + +#include BOOST_PROCESS_PLATFORM_PROMOTE_PATH(executor) +BOOST_PROCESS_PLATFORM_PROMOTE_NAMESPACE(executor) + +#if defined(BOOST_PROCESS_DOXYGEN) +namespace boost { namespace process { + +/** + * Starts a program. + * + * boost::process::executor is a functor which calls the system functions + * to start a program. Before system functions are called it iterates + * over initializers and calls a member function passing a reference + * to itself as a parameter. Initializers get then a chance to setup + * the executor. If system functions fail boost::process::executor again + * iterates over initializers and calls another member function passing a + * reference to itself as a parameter. This gives initializers a + * chance to handle the error. + * + * \note Library users shouldn't need to use boost::process::executor. + * It is recommended to call boost::process::execute which uses + * boost::pocess::executor internally. + */ +struct executor +{ + /** + * Default constructor. + */ + executor(); + + /** + * Starts a program. + * + * \tparam initializers define what and how the program is started + */ + template <class Initializer, class... Initializers> + child operator()(const Initializer &initializer, const Initializers... &initializers); + + ///\defgroup WindowsOnly Windows only. + ///@{ + + /** + * Program name. + * + * \remark <em>Windows only.</em> + */ + LPCTSTR exe; + + /** + * Command line. + * + * \remark <em>Windows only.</em> + */ + LPTSTR cmd_line; + + /** + * Process attributes. + * + * \remark <em>Windows only.</em> + */ + LPSECURITY_ATTRIBUTES proc_attrs; + + /** + * Thread attributes. + * + * \remark <em>Windows only.</em> + */ + LPSECURITY_ATTRIBUTES thread_attrs; + + /** + * Flag to inherit handles. + * + * \remark <em>Windows only.</em> + */ + BOOL inherit_handles; + + /** + * Creation flags. + * + * \remark <em>Windows only.</em> + */ + DWORD creation_flags; + + /** + * Environment variables. + * + * \remark <em>Windows only.</em> + */ + LPVOID env; + + /** + * Work directory. + * + * \remark <em>Windows only.</em> + */ + LPCTSTR work_dir; + + /** + * Startupinfo structure. + * + * \remark <em>Windows only.</em> + */ + STARTUPINFO startup_info; + + /** + * Startupinfoex structure. + * + * If this member variable is available, \c startup_info is a reference + * to \c StartupInfo in STARTUPINFOEX. + * + * \remark <em>Windows Vista, Windows Server 2008 or better.</em> + */ + STARTUPINFOEX startup_info_ex; + + /** + * Process information. + * + * \c proc_info contains the result after a child process + * could be started successfully. + * + * \remark <em>Windows only.</em> + */ + PROCESS_INFORMATION proc_info; + + ///@} + + ///\defgroup POSIXOnly POSIX only. + ///@{ + + /** + * Program name. + * + * \remark <em>POSIX only.</em> + */ + const char *exe; + + /** + * Command line arguments. + * + * \remark <em>POSIX only.</em> + */ + char **cmd_line; + + /** + * Environment variables. + * + * \remark <em>POSIX only.</em> + */ + char **env; + + ///@} +}; + +}} +#endif + +#endif diff --git a/dep/process/boost/process/initializers.hpp b/dep/process/boost/process/initializers.hpp new file mode 100644 index 00000000000..c7175d1425d --- /dev/null +++ b/dep/process/boost/process/initializers.hpp @@ -0,0 +1,497 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/** + * \file boost/process/initializers.hpp + * + * Defines initializers. + */ + +#ifndef BOOST_PROCESS_INITIALIZERS_HPP +#define BOOST_PROCESS_INITIALIZERS_HPP + +#include <boost/process/config.hpp> + +#include BOOST_PROCESS_PLATFORM_PROMOTE_PATH(initializers) +BOOST_PROCESS_PLATFORM_PROMOTE_INITIALIZERS_NAMESPACE + +#if defined(BOOST_PROCESS_DOXYGEN) +namespace boost { namespace process { namespace initializers { + +/** + * Binds the standard error stream. + */ +class bind_stderr : public initializer_base +{ +public: + /** + * Constructor. + */ + explicit bind_stderr(const boost::iostreams::file_descriptor_sink &sink); +}; + +/** + * Binds the standard input stream. + */ +class bind_stdin : public initializer_base +{ +public: + /** + * Constructor. + */ + explicit bind_stdin(const boost::iostreams::file_descriptor_source &source); +}; + +/** + * Binds the standard output stream. + */ +class bind_stdout : public initializer_base +{ +public: + /** + * Constructor. + */ + explicit bind_stdout(const boost::iostreams::file_descriptor_sink &sink); +}; + +/** + * Binds a file descriptor. + * + * \remark <em>POSIX only.</em> + */ +class bind_fd : public initializer_base +{ +public: + /** + * Constructor. + */ + bind_fd(int id, const boost::iostreams::file_descriptor &fd); +}; + +/** + * Closes a file descriptor. + * + * \remark <em>POSIX only.</em> + */ +class close_fd : public initializer_base +{ + /** + * Constructor. + */ + explicit close_fd(int fd); +}; + +/** + * Closes file descriptors. + * + * \remark <em>POSIX only.</em> + */ +class close_fds : public initializer_base +{ +public: + /** + * Constructor. + * + * \c range_type must be an <tt>int</tt>-range. + */ + explicit close_fds(const range_type &fds); +}; + +/** + * Closes all file descriptors a predicate returns + * true for. + * + * This initializer doesn't close file descriptors + * immediately. Instead it sets the \c FD_CLOEXEC + * flag. File descriptors are closed when \c execve + * is called and the call succeeds. + * + * \remark <em>POSIX only.</em> + */ +class close_fds_if : public initializer_base +{ +public: + /** + * Constructor. + * + * \c predicate_type must be a function or functor with + * this signature: <tt>bool(int)</tt> + */ + explicit close_fds_if(const predicate_type &pred); +}; + +/** + * Closes the standard error stream. + */ +class close_stderr : public initializer_base +{ + /** + * Constructor. + */ + close_stderr(); +}; + +/** + * Closes the standard input stream. + */ +class close_stdin : public initializer_base +{ + /** + * Constructor. + */ + close_stdin(); +}; + +/** + * Closes the standard output stream. + */ +class close_stdout : public initializer_base +{ + /** + * Constructor. + */ + close_stdout(); +}; + +/** + * Hides the console. + */ +class hide_console : public initializer_base +{ +public: + /** + * Constructor. + */ + hide_console(); +}; + +/** + * Inherits environment variables. + */ +class inherit_env : public initializer_base +{ +public: + /** + * Constructor. + */ + inherit_env(); +}; + +/** + * Notifies an I/O service object of fork-related events. + * + * \see boost::asio::io_service::notify_fork + * + * \remark <em>POSIX only.</em> + */ +class notify_io_service : public initializer_base +{ +public: + /** + * Constructor. + */ + explicit notify_io_service(boost::asio::io_service &io_service); +}; + +/** + * Generic initializer to execute any code if \c execve + * failed. + * + * \remark <em>POSIX only.</em> + */ +class on_exec_error : public initializer_base +{ +public: + /** + * Constructor. + * + * \c handler_type must be a function or functor with + * this signature: <tt>void(executor&)</tt> + */ + explicit on_exec_error(handler_type handler); +}; + +/** + * Generic initializer to execute any code before \c execve + * is called. + * + * \remark <em>POSIX only.</em> + */ +class on_exec_setup : public initializer_base +{ +public: + /** + * Constructor. + * + * \c handler_type must be a function or functor with + * this signature: <tt>void(executor&)</tt> + */ + explicit on_exec_setup(handler_type handler); +}; + +/** + * Generic initializer to execute any code if \c fork + * failed. + * + * \remark <em>POSIX only.</em> + */ +class on_fork_error : public initializer_base +{ +public: + /** + * Constructor. + * + * \c handler_type must be a function or functor with + * this signature: <tt>void(executor&)</tt> + */ + explicit on_fork_error(handler_type handler); +}; + +/** + * Generic initializer to execute any code before \c fork + * is called. + * + * \remark <em>POSIX only.</em> + */ +class on_fork_setup : public initializer_base +{ +public: + /** + * Constructor. + * + * \c handler_type must be a function or functor with + * this signature: <tt>void(executor&)</tt> + */ + explicit on_fork_setup(handler_type handler); +}; + +/** + * Generic initializer to execute any code in the parent + * process after \c fork has been called successfully. + * + * \remark <em>POSIX only.</em> + */ +class on_fork_success : public initializer_base +{ +public: + /** + * Constructor. + * + * \c handler_type must be a function or functor with + * this signature: <tt>void(executor&)</tt> + */ + explicit on_fork_success(handler_type handler); +}; + +/** + * Generic initializer to execute any code if \c CreateProcess + * failed. + * + * \remark <em>Windows only.</em> + */ +class on_CreateProcess_error : public initializer_base +{ +public: + /** + * Constructor. + * + * \c handler_type must be a function or functor with + * this signature: <tt>void(executor&)</tt> + */ + explicit on_CreateProcess_error(handler_type handler); +}; + +/** + * Generic initializer to execute any code before \c CreateProcess + * is called. + * + * \remark <em>Windows only.</em> + */ +class on_CreateProcess_setup : public initializer_base +{ +public: + /** + * Constructor. + * + * \c handler_type must be a function or functor with + * this signature: <tt>void(executor&)</tt> + */ + explicit on_CreateProcess_setup(handler_type handler); +}; + +/** + * Generic initializer to execute any code after \c CreateProcess + * has been called successfully. + * + * \remark <em>Windows only.</em> + */ +class on_CreateProcess_success : public initializer_base +{ +public: + /** + * Constructor. + * + * \c handler_type must be a function or functor with + * this signature: <tt>void(executor&)</tt> + */ + explicit on_CreateProcess_success(handler_type handler); +}; + +/** + * Specifies the executable to start. + * + * This initializer must always be used. The only exception is + * if you use \c set_args or a generic initializer which + * specifies the executable. + */ +class run_exe : public initializer_base +{ +public: + /** + * Constructor. + * + * On Windows \c string_type must be <tt>const char*</tt>, + * <tt>std::string</tt> or <tt>boost::filesystem::path</tt>. + * If Unicode is used, \c string_type must be + * <tt>const wchar_t*</tt>, <tt>std::wstring</tt> or + * <tt>boost::filesystem::path</tt>. + * + * On POSIX \c string_type must be <tt>const char*</tt>, + * <tt>std::string</tt> or <tt>boost::filesystem::path</tt>. + */ + explicit run_exe(const string_type &s); +}; + +/** + * Sets the command line arguments. + * + * The first argument specifies the executable to start unless + * \c run_exe is used. + * + * Use \c set_cmd_line if you don't want to pass a collection of + * command line arguments but set the command line as one string. + */ +class set_args : public initializer_base +{ +public: + /** + * Constructor. + * + * On Windows \c range_type must be a <tt>std::string</tt>-range. + * If Unicode is used, \c range_type must be a + * <tt>std::wstring</tt>-range. + * + * On POSIX \c range_type must be a <tt>std::string</tt>-range. + */ + explicit set_args(const range_type &r); +}; + +/** + * Sets the command line. + * + * Use \c set_args if you don't want to set the command line as + * one string but pass a collection of command line arguments. + */ +class set_cmd_line : public initializer_base +{ +public: + /** + * Constructor. + * + * On Windows \c string_type must be <tt>const char*</tt>, + * <tt>std::string</tt> or <tt>boost::filesystem::path</tt>. + * If Unicode is used, \c string_type must be + * <tt>const wchar_t*</tt>, <tt>std::wstring</tt> or + * <tt>boost::filesystem::path</tt>. + * + * On POSIX \c string_type must be <tt>const char*</tt>, + * <tt>std::string</tt> or <tt>boost::filesystem::path</tt>. + */ + explicit set_cmd_line(const string_type &s); +}; + +/** + * Sets the environment. + */ +class set_env : public initializer_base +{ +public: + /** + * Constructor. + * + * On Windows \c range_type must be a <tt>std::string</tt>-range. + * If Unicode is used, \c range_type must be a + * <tt>std::wstring</tt>-range. + * + * On POSIX \c range_type must be a <tt>std::string</tt>-range. + */ + explicit set_env(const range_type &r); +}; + +/** + * Sets an error if a child process can't be created. + */ +class set_on_error : public initializer_base +{ +public: + /** + * Constructor. + */ + explicit set_on_error(boost::system::error_code &ec); +}; + +/** + * Sets the flag \c wShowWindow in \c STARTUPINFO. + * + * \remark <em>Windows only.</em> + */ +class show_window : public initializer_base +{ +public: + /** + * Constructor. + */ + explicit show_window(WORD flags); +}; + +/** + * Sets the work directory. + */ +class start_in_dir : public initializer_base +{ +public: + /** + * Constructor. + * + * On Windows \c string_type must be <tt>const char*</tt>, + * <tt>std::string</tt> or <tt>boost::filesystem::path</tt>. + * If Unicode is used, \c string_type must be + * <tt>const wchar_t*</tt>, <tt>std::wstring</tt> or + * <tt>boost::filesystem::path</tt>. + * + * On POSIX \c string_type must be <tt>const char*</tt>, + * <tt>std::string</tt> or <tt>boost::filesystem::path</tt>. + */ + explicit start_in_dir(const string_type &s); +}; + +/** + * Throws an error if a child process can't be created. + * + * The type of the error thrown is \c boost::system::system_error. + */ +class throw_on_error : public initializer_base +{ +public: +}; + +}}} +#endif + +#endif diff --git a/dep/process/boost/process/mitigate.hpp b/dep/process/boost/process/mitigate.hpp new file mode 100644 index 00000000000..6838984aa1a --- /dev/null +++ b/dep/process/boost/process/mitigate.hpp @@ -0,0 +1,104 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/** + * \file boost/process/mitigate.hpp + * + * Helpers to mitigate platform differences. + */ + +#ifndef BOOST_PROCESS_MITIGATE_HPP +#define BOOST_PROCESS_MITIGATE_HPP + +#include <boost/asio.hpp> +#if defined(BOOST_POSIX_API) +# include <sys/wait.h> +#endif + +namespace boost { namespace process { + +#if defined(BOOST_WINDOWS_API) +typedef boost::asio::windows::stream_handle pipe_end; +#elif defined(BOOST_POSIX_API) +typedef boost::asio::posix::stream_descriptor pipe_end; +#endif + +inline const char *zero_device() +{ +#if defined(BOOST_WINDOWS_API) + return "NUL"; +#elif defined(BOOST_POSIX_API) + return "/dev/zero"; +#endif +} + +inline const char *null_device() +{ +#if defined(BOOST_WINDOWS_API) + return "NUL"; +#elif defined(BOOST_POSIX_API) + return "/dev/null"; +#endif +} + +#if defined(BOOST_WINDOWS_API) +# define BOOST_PROCESS_EXITSTATUS(a) static_cast<int>(a) +#elif defined(BOOST_POSIX_API) +# define BOOST_PROCESS_EXITSTATUS WEXITSTATUS +#endif + +#if defined(BOOST_PROCESS_DOXYGEN) +/** + * Type definition for the end of a pipe. + * + * On Windows the type is based on boost::asio::windows::stream_handle. On + * POSIX it is based on boost::asio::posix::stream_descriptor. + * + * You can use this type definition for asynchronous I/O with streams of + * child processes. + */ +typedef boost_asio_type pipe_end; + +/** + * Gets the name of the zero device. + * + * You can use zero_device to initialize a + * boost::iostreams::file_descriptor_source to read + * null characters from. + * + * \returns NUL on Windows and /dev/zero on POSIX. + */ +const char *zero_device(); + +/** + * Gets the name of the null device. + * + * You can use null_device to initialize a + * boost::iostreams::file_descriptor_sink which discards + * data written to it. + * + * \returns NUL on Windows and /dev/null on POSIX. + */ +const char *null_device(); + +/** + * \def BOOST_PROCESS_EXITSTATUS + * + * On Windows \c BOOST_PROCESS_EXITSTATUS is a static cast to \c int. + * On POSIX it is set to \c WEXITSTATUS. + * + * You can use \c BOOST_PROCESS_EXITSTATUS for the return value of + * boost::process::wait_for_exit to get the exit status of a process. + */ +#define BOOST_PROCESS_EXITSTATUS +#endif + +}} + +#endif diff --git a/dep/process/boost/process/pipe.hpp b/dep/process/boost/process/pipe.hpp new file mode 100644 index 00000000000..35f2a4470d6 --- /dev/null +++ b/dep/process/boost/process/pipe.hpp @@ -0,0 +1,64 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/** + * \file boost/process/pipe.hpp + * + * Defines a pipe. + */ + +#ifndef BOOST_PROCESS_PIPE_HPP +#define BOOST_PROCESS_PIPE_HPP + +#include <boost/process/config.hpp> + +#include BOOST_PROCESS_PLATFORM_PROMOTE_PATH(pipe) +BOOST_PROCESS_PLATFORM_PROMOTE_NAMESPACE(pipe) +BOOST_PROCESS_PLATFORM_PROMOTE_NAMESPACE(make_pipe) + +#if defined(BOOST_PROCESS_DOXYGEN) +namespace boost { namespace process { + +/** + * Represents a pipe. + */ +struct pipe +{ + /** + * Read-end. + */ + pipe_end_type source; + + /** + * Write-end. + */ + pipe_end_type sink; + + /** + * Constructor. + */ + pipe(pipe_end_type source, pipe_end_type sink); +}; + +/** + * Returns a pipe instance. + * + * This is a helper function to instantiate boost::process::pipe. + * + * \note boost::process::make_pipe does not create a pipe. + * You must pass existing pipe ends to this function. + * If you want to create an anonymous pipe, call + * boost::process::create_pipe. + */ +pipe make_pipe(pipe_end_type source, pipe_end_type sink); + +}} +#endif + +#endif diff --git a/dep/process/boost/process/posix/child.hpp b/dep/process/boost/process/posix/child.hpp new file mode 100644 index 00000000000..913484529e8 --- /dev/null +++ b/dep/process/boost/process/posix/child.hpp @@ -0,0 +1,26 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_CHILD_HPP +#define BOOST_PROCESS_POSIX_CHILD_HPP + +#include <sys/types.h> + +namespace boost { namespace process { namespace posix { + +struct child +{ + pid_t pid; + + explicit child(pid_t p) : pid(p) {} +}; + +}}} + +#endif diff --git a/dep/process/boost/process/posix/create_pipe.hpp b/dep/process/boost/process/posix/create_pipe.hpp new file mode 100644 index 00000000000..ecdd523516f --- /dev/null +++ b/dep/process/boost/process/posix/create_pipe.hpp @@ -0,0 +1,40 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_CREATE_PIPE_HPP +#define BOOST_PROCESS_POSIX_CREATE_PIPE_HPP + +#include <boost/process/config.hpp> +#include <boost/process/posix/pipe.hpp> +#include <boost/system/error_code.hpp> +#include <unistd.h> + +namespace boost { namespace process { namespace posix { + +inline pipe create_pipe() +{ + int fds[2]; + if (::pipe(fds) == -1) + BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("pipe(2) failed"); + return pipe(fds[0], fds[1]); +} + +inline pipe create_pipe(boost::system::error_code &ec) +{ + int fds[2]; + if (::pipe(fds) == -1) + BOOST_PROCESS_RETURN_LAST_SYSTEM_ERROR(ec); + else + ec.clear(); + return pipe(fds[0], fds[1]); +} + +}}} + +#endif diff --git a/dep/process/boost/process/posix/execute.hpp b/dep/process/boost/process/posix/execute.hpp new file mode 100644 index 00000000000..27082196c8a --- /dev/null +++ b/dep/process/boost/process/posix/execute.hpp @@ -0,0 +1,82 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_EXECUTE_HPP +#define BOOST_PROCESS_POSIX_EXECUTE_HPP + +#include <boost/process/posix/executor.hpp> +#include <boost/process/posix/child.hpp> +#include <boost/fusion/tuple/make_tuple.hpp> +#include <boost/ref.hpp> + +namespace boost { namespace process { namespace posix { + +template <class I0> +child execute(const I0 &i0) +{ + return executor()(boost::fusion::make_tuple(boost::cref(i0))); +} + +template <class I0, class I1> +child execute(const I0 &i0, const I1 &i1) +{ + return executor()(boost::fusion::make_tuple(boost::cref(i0), boost::cref(i1))); +} + +template <class I0, class I1, class I2> +child execute(const I0 &i0, const I1 &i1, const I2 &i2) +{ + return executor()(boost::fusion::make_tuple(boost::cref(i0), boost::cref(i1), boost::cref(i2))); +} + +template <class I0, class I1, class I2, class I3> +child execute(const I0 &i0, const I1 &i1, const I2 &i2, const I3 &i3) +{ + return executor()(boost::fusion::make_tuple(boost::cref(i0), boost::cref(i1), boost::cref(i2), boost::cref(i3))); +} + +template <class I0, class I1, class I2, class I3, class I4> +child execute(const I0 &i0, const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4) +{ + return executor()(boost::fusion::make_tuple(boost::cref(i0), boost::cref(i1), boost::cref(i2), boost::cref(i3), boost::cref(i4))); +} + +template <class I0, class I1, class I2, class I3, class I4, class I5> +child execute(const I0 &i0, const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4, const I5 &i5) +{ + return executor()(boost::fusion::make_tuple(boost::cref(i0), boost::cref(i1), boost::cref(i2), boost::cref(i3), boost::cref(i4), boost::cref(i5))); +} + +template <class I0, class I1, class I2, class I3, class I4, class I5, class I6> +child execute(const I0 &i0, const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4, const I5 &i5, const I6 &i6) +{ + return executor()(boost::fusion::make_tuple(boost::cref(i0), boost::cref(i1), boost::cref(i2), boost::cref(i3), boost::cref(i4), boost::cref(i5), boost::cref(i6))); +} + +template <class I0, class I1, class I2, class I3, class I4, class I5, class I6, class I7> +child execute(const I0 &i0, const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4, const I5 &i5, const I6 &i6, const I7 &i7) +{ + return executor()(boost::fusion::make_tuple(boost::cref(i0), boost::cref(i1), boost::cref(i2), boost::cref(i3), boost::cref(i4), boost::cref(i5), boost::cref(i6), boost::cref(i7))); +} + +template <class I0, class I1, class I2, class I3, class I4, class I5, class I6, class I7, class I8> +child execute(const I0 &i0, const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4, const I5 &i5, const I6 &i6, const I7 &i7, const I8 &i8) +{ + return executor()(boost::fusion::make_tuple(boost::cref(i0), boost::cref(i1), boost::cref(i2), boost::cref(i3), boost::cref(i4), boost::cref(i5), boost::cref(i6), boost::cref(i7), boost::cref(i8))); +} + +template <class I0, class I1, class I2, class I3, class I4, class I5, class I6, class I7, class I8, class I9> +child execute(const I0 &i0, const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4, const I5 &i5, const I6 &i6, const I7 &i7, const I8 &i8, const I9 &i9) +{ + return executor()(boost::fusion::make_tuple(boost::cref(i0), boost::cref(i1), boost::cref(i2), boost::cref(i3), boost::cref(i4), boost::cref(i5), boost::cref(i6), boost::cref(i7), boost::cref(i8), boost::cref(i9))); +} + +}}} + +#endif diff --git a/dep/process/boost/process/posix/executor.hpp b/dep/process/boost/process/posix/executor.hpp new file mode 100644 index 00000000000..a3e81f128f5 --- /dev/null +++ b/dep/process/boost/process/posix/executor.hpp @@ -0,0 +1,120 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_EXECUTOR_HPP +#define BOOST_PROCESS_POSIX_EXECUTOR_HPP + +#include <boost/process/posix/child.hpp> +#include <boost/fusion/algorithm/iteration/for_each.hpp> +#include <cstdlib> +#include <sys/types.h> +#include <unistd.h> + +namespace boost { namespace process { namespace posix { + +struct executor +{ + executor() : exe(0), cmd_line(0), env(0) {} + + struct call_on_fork_setup + { + executor &e_; + + call_on_fork_setup(executor &e) : e_(e) {} + + template <class Arg> + void operator()(const Arg &arg) const + { + arg.on_fork_setup(e_); + } + }; + + struct call_on_fork_error + { + executor &e_; + + call_on_fork_error(executor &e) : e_(e) {} + + template <class Arg> + void operator()(Arg &arg) const + { + arg.on_fork_error(e_); + } + }; + + struct call_on_fork_success + { + executor &e_; + + call_on_fork_success(executor &e) : e_(e) {} + + template <class Arg> + void operator()(Arg &arg) const + { + arg.on_fork_success(e_); + } + }; + + struct call_on_exec_setup + { + executor &e_; + + call_on_exec_setup(executor &e) : e_(e) {} + + template <class Arg> + void operator()(Arg &arg) const + { + arg.on_exec_setup(e_); + } + }; + + struct call_on_exec_error + { + executor &e_; + + call_on_exec_error(executor &e) : e_(e) {} + + template <class Arg> + void operator()(Arg &arg) const + { + arg.on_exec_error(e_); + } + }; + + template <class InitializerSequence> + child operator()(const InitializerSequence &seq) + { + boost::fusion::for_each(seq, call_on_fork_setup(*this)); + + pid_t pid = ::fork(); + if (pid == -1) + { + boost::fusion::for_each(seq, call_on_fork_error(*this)); + } + else if (pid == 0) + { + boost::fusion::for_each(seq, call_on_exec_setup(*this)); + ::execve(exe, cmd_line, env); + boost::fusion::for_each(seq, call_on_exec_error(*this)); + _exit(EXIT_FAILURE); + } + + boost::fusion::for_each(seq, call_on_fork_success(*this)); + + return child(pid); + } + + const char *exe; + char **cmd_line; + char **env; +}; + +}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers.hpp b/dep/process/boost/process/posix/initializers.hpp new file mode 100644 index 00000000000..78295c14cb6 --- /dev/null +++ b/dep/process/boost/process/posix/initializers.hpp @@ -0,0 +1,39 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_HPP + +#include <boost/process/posix/initializers/bind_fd.hpp> +#include <boost/process/posix/initializers/bind_stderr.hpp> +#include <boost/process/posix/initializers/bind_stdin.hpp> +#include <boost/process/posix/initializers/bind_stdout.hpp> +#include <boost/process/posix/initializers/close_fd.hpp> +#include <boost/process/posix/initializers/close_fds.hpp> +#include <boost/process/posix/initializers/close_fds_if.hpp> +#include <boost/process/posix/initializers/close_stderr.hpp> +#include <boost/process/posix/initializers/close_stdin.hpp> +#include <boost/process/posix/initializers/close_stdout.hpp> +#include <boost/process/posix/initializers/hide_console.hpp> +#include <boost/process/posix/initializers/inherit_env.hpp> +#include <boost/process/posix/initializers/notify_io_service.hpp> +#include <boost/process/posix/initializers/on_exec_error.hpp> +#include <boost/process/posix/initializers/on_exec_setup.hpp> +#include <boost/process/posix/initializers/on_fork_error.hpp> +#include <boost/process/posix/initializers/on_fork_setup.hpp> +#include <boost/process/posix/initializers/on_fork_success.hpp> +#include <boost/process/posix/initializers/run_exe.hpp> +#include <boost/process/posix/initializers/set_args.hpp> +#include <boost/process/posix/initializers/set_cmd_line.hpp> +#include <boost/process/posix/initializers/set_env.hpp> +#include <boost/process/posix/initializers/set_on_error.hpp> +#include <boost/process/posix/initializers/start_in_dir.hpp> +#include <boost/process/posix/initializers/throw_on_error.hpp> + +#endif diff --git a/dep/process/boost/process/posix/initializers/bind_fd.hpp b/dep/process/boost/process/posix/initializers/bind_fd.hpp new file mode 100644 index 00000000000..851b7ef3e44 --- /dev/null +++ b/dep/process/boost/process/posix/initializers/bind_fd.hpp @@ -0,0 +1,43 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_BIND_FD_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_BIND_FD_HPP + +#include <boost/process/posix/initializers/initializer_base.hpp> +#include <unistd.h> + +namespace boost { namespace process { namespace posix { namespace initializers { + +template <class FileDescriptor> +class bind_fd_ : public initializer_base +{ +public: + bind_fd_(int id, const FileDescriptor &fd) : id_(id), fd_(fd) {} + + template <class PosixExecutor> + void on_exec_setup(PosixExecutor&) const + { + ::dup2(fd_.handle(), id_); + } + +private: + int id_; + FileDescriptor fd_; +}; + +template <class FileDescriptor> +bind_fd_<FileDescriptor> bind_fd(int id, const FileDescriptor &fd) +{ + return bind_fd_<FileDescriptor>(id, fd); +} + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/bind_stderr.hpp b/dep/process/boost/process/posix/initializers/bind_stderr.hpp new file mode 100644 index 00000000000..be767bf2fe1 --- /dev/null +++ b/dep/process/boost/process/posix/initializers/bind_stderr.hpp @@ -0,0 +1,37 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_BIND_STDERR_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_BIND_STDERR_HPP + +#include <boost/process/posix/initializers/initializer_base.hpp> +#include <boost/iostreams/device/file_descriptor.hpp> +#include <unistd.h> + +namespace boost { namespace process { namespace posix { namespace initializers { + +class bind_stderr : public initializer_base +{ +public: + explicit bind_stderr(const boost::iostreams::file_descriptor_sink &sink) + : sink_(sink) {} + + template <class PosixExecutor> + void on_exec_setup(PosixExecutor&) const + { + ::dup2(sink_.handle(), STDERR_FILENO); + } + +private: + boost::iostreams::file_descriptor_sink sink_; +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/bind_stdin.hpp b/dep/process/boost/process/posix/initializers/bind_stdin.hpp new file mode 100644 index 00000000000..b592d6f8b38 --- /dev/null +++ b/dep/process/boost/process/posix/initializers/bind_stdin.hpp @@ -0,0 +1,37 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_BIND_STDIN_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_BIND_STDIN_HPP + +#include <boost/process/posix/initializers/initializer_base.hpp> +#include <boost/iostreams/device/file_descriptor.hpp> +#include <unistd.h> + +namespace boost { namespace process { namespace posix { namespace initializers { + +class bind_stdin : public initializer_base +{ +public: + explicit bind_stdin(const boost::iostreams::file_descriptor_source &source) + : source_(source) {} + + template <class PosixExecutor> + void on_exec_setup(PosixExecutor&) const + { + ::dup2(source_.handle(), STDIN_FILENO); + } + +private: + boost::iostreams::file_descriptor_source source_; +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/bind_stdout.hpp b/dep/process/boost/process/posix/initializers/bind_stdout.hpp new file mode 100644 index 00000000000..a2c316d9972 --- /dev/null +++ b/dep/process/boost/process/posix/initializers/bind_stdout.hpp @@ -0,0 +1,37 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_BIND_STDOUT_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_BIND_STDOUT_HPP + +#include <boost/process/posix/initializers/initializer_base.hpp> +#include <boost/iostreams/device/file_descriptor.hpp> +#include <unistd.h> + +namespace boost { namespace process { namespace posix { namespace initializers { + +class bind_stdout : public initializer_base +{ +public: + explicit bind_stdout(const boost::iostreams::file_descriptor_sink &sink) + : sink_(sink) {} + + template <class PosixExecutor> + void on_exec_setup(PosixExecutor&) const + { + ::dup2(sink_.handle(), STDOUT_FILENO); + } + +private: + boost::iostreams::file_descriptor_sink sink_; +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/close_fd.hpp b/dep/process/boost/process/posix/initializers/close_fd.hpp new file mode 100644 index 00000000000..fd516e41005 --- /dev/null +++ b/dep/process/boost/process/posix/initializers/close_fd.hpp @@ -0,0 +1,35 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_CLOSE_FD_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_CLOSE_FD_HPP + +#include <boost/process/posix/initializers/initializer_base.hpp> +#include <unistd.h> + +namespace boost { namespace process { namespace posix { namespace initializers { + +class close_fd : public initializer_base +{ +public: + explicit close_fd(int fd) : fd_(fd) {} + + template <class PosixExecutor> + void on_exec_setup(PosixExecutor&) const + { + ::close(fd_); + } + +private: + int fd_; +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/close_fds.hpp b/dep/process/boost/process/posix/initializers/close_fds.hpp new file mode 100644 index 00000000000..2fa338501eb --- /dev/null +++ b/dep/process/boost/process/posix/initializers/close_fds.hpp @@ -0,0 +1,43 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_CLOSE_FDS_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_CLOSE_FDS_HPP + +#include <boost/process/posix/initializers/initializer_base.hpp> +#include <boost/range/algorithm/for_each.hpp> +#include <unistd.h> + +namespace boost { namespace process { namespace posix { namespace initializers { + +template <class Range> +class close_fds_ : public initializer_base +{ +public: + explicit close_fds_(const Range &fds) : fds_(fds) {} + + template <class PosixExecutor> + void on_exec_setup(PosixExecutor&) const + { + boost::for_each(fds_, ::close); + } + +private: + Range fds_; +}; + +template <class Range> +close_fds_<Range> close_fds(const Range &fds) +{ + return close_fds_<Range>(fds); +} + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/close_fds_if.hpp b/dep/process/boost/process/posix/initializers/close_fds_if.hpp new file mode 100644 index 00000000000..fb3a651d628 --- /dev/null +++ b/dep/process/boost/process/posix/initializers/close_fds_if.hpp @@ -0,0 +1,80 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_CLOSE_FDS_IF_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_CLOSE_FDS_IF_HPP + +#include <boost/process/posix/initializers/initializer_base.hpp> +#include <boost/iterator/counting_iterator.hpp> +#include <boost/range/counting_range.hpp> +#include <boost/range/adaptor/filtered.hpp> +#include <boost/range/algorithm/for_each.hpp> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> + +#ifndef BOOST_PROCESS_POSIX_MAX_FD +# define BOOST_PROCESS_POSIX_MAX_FD 32 +#endif + +namespace boost { namespace process { namespace posix { namespace initializers { + +template <class Predicate> +class close_fds_if_ : public initializer_base +{ +private: + static void close(int fd) + { + ::fcntl(fd, F_SETFD, FD_CLOEXEC); + } + +public: + explicit close_fds_if_(const Predicate &pred) : pred_(pred) {} + + template <class PosixExecutor> + void on_exec_setup(PosixExecutor&) const + { + boost::for_each( + boost::adaptors::filter( + boost::counting_range(0, upper_bound()), + pred_ + ), + close + ); + } + +private: + static int upper_bound() + { + int up; +#if defined(F_MAXFD) + do + { + up = ::fcntl(0, F_MAXFD); + } while (up == -1 && errno == EINTR); + if (up == -1) +#endif + up = ::sysconf(_SC_OPEN_MAX); + if (up == -1) + up = BOOST_PROCESS_POSIX_MAX_FD; + return up; + } + + Predicate pred_; +}; + +template <class Predicate> +close_fds_if_<Predicate> close_fds_if(const Predicate &pred) +{ + return close_fds_if_<Predicate>(pred); +} + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/close_stderr.hpp b/dep/process/boost/process/posix/initializers/close_stderr.hpp new file mode 100644 index 00000000000..1a4c2ad00df --- /dev/null +++ b/dep/process/boost/process/posix/initializers/close_stderr.hpp @@ -0,0 +1,30 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_CLOSE_STDERR_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_CLOSE_STDERR_HPP + +#include <boost/process/posix/initializers/initializer_base.hpp> +#include <unistd.h> + +namespace boost { namespace process { namespace posix { namespace initializers { + +class close_stderr : public initializer_base +{ +public: + template <class PosixExecutor> + void on_exec_setup(PosixExecutor&) const + { + ::close(STDERR_FILENO); + } +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/close_stdin.hpp b/dep/process/boost/process/posix/initializers/close_stdin.hpp new file mode 100644 index 00000000000..021c3ec54df --- /dev/null +++ b/dep/process/boost/process/posix/initializers/close_stdin.hpp @@ -0,0 +1,30 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_CLOSE_STDIN_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_CLOSE_STDIN_HPP + +#include <boost/process/posix/initializers/initializer_base.hpp> +#include <unistd.h> + +namespace boost { namespace process { namespace posix { namespace initializers { + +class close_stdin : public initializer_base +{ +public: + template <class PosixExecutor> + void on_exec_setup(PosixExecutor&) const + { + ::close(STDIN_FILENO); + } +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/close_stdout.hpp b/dep/process/boost/process/posix/initializers/close_stdout.hpp new file mode 100644 index 00000000000..cfab7d1d62f --- /dev/null +++ b/dep/process/boost/process/posix/initializers/close_stdout.hpp @@ -0,0 +1,30 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_CLOSE_STDOUT_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_CLOSE_STDOUT_HPP + +#include <boost/process/posix/initializers/initializer_base.hpp> +#include <unistd.h> + +namespace boost { namespace process { namespace posix { namespace initializers { + +class close_stdout : public initializer_base +{ +public: + template <class PosixExecutor> + void on_exec_setup(PosixExecutor&) const + { + ::close(STDOUT_FILENO); + } +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/hide_console.hpp b/dep/process/boost/process/posix/initializers/hide_console.hpp new file mode 100644 index 00000000000..20d527b457f --- /dev/null +++ b/dep/process/boost/process/posix/initializers/hide_console.hpp @@ -0,0 +1,24 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_HIDE_CONSOLE_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_HIDE_CONSOLE_HPP + +#include <boost/process/posix/initializers/initializer_base.hpp> + +namespace boost { namespace process { namespace posix { namespace initializers { + +class hide_console : public initializer_base +{ +public: +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/inherit_env.hpp b/dep/process/boost/process/posix/initializers/inherit_env.hpp new file mode 100644 index 00000000000..bc73c8571f8 --- /dev/null +++ b/dep/process/boost/process/posix/initializers/inherit_env.hpp @@ -0,0 +1,36 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_INHERIT_ENV_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_INHERIT_ENV_HPP + +#include <boost/process/posix/initializers/initializer_base.hpp> +// From <https://svn.boost.org/trac/boost/changeset/67768> +#if defined(__APPLE__) && defined(__DYNAMIC__) +extern "C" { extern char ***_NSGetEnviron(void); } +# define environ (*_NSGetEnviron()) +#else +# include <unistd.h> +#endif + +namespace boost { namespace process { namespace posix { namespace initializers { + +class inherit_env : public initializer_base +{ +public: + template <class PosixExecutor> + void on_fork_setup(PosixExecutor &e) const + { + e.env = environ; + } +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/initializer_base.hpp b/dep/process/boost/process/posix/initializers/initializer_base.hpp new file mode 100644 index 00000000000..775f00e48ce --- /dev/null +++ b/dep/process/boost/process/posix/initializers/initializer_base.hpp @@ -0,0 +1,35 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_INITIALIZER_BASE_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_INITIALIZER_BASE_HPP + +namespace boost { namespace process { namespace posix { namespace initializers { + +struct initializer_base +{ + template <class PosixExecutor> + void on_fork_setup(PosixExecutor&) const {} + + template <class PosixExecutor> + void on_fork_error(PosixExecutor&) const {} + + template <class PosixExecutor> + void on_fork_success(PosixExecutor&) const {} + + template <class PosixExecutor> + void on_exec_setup(PosixExecutor&) const {} + + template <class PosixExecutor> + void on_exec_error(PosixExecutor&) const {} +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/notify_io_service.hpp b/dep/process/boost/process/posix/initializers/notify_io_service.hpp new file mode 100644 index 00000000000..d94f674c81a --- /dev/null +++ b/dep/process/boost/process/posix/initializers/notify_io_service.hpp @@ -0,0 +1,55 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_NOTIFY_IO_SERVICE_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_NOTIFY_IO_SERVICE_HPP + +#include <boost/process/config.hpp> +#include <boost/process/posix/initializers/initializer_base.hpp> + +namespace boost { namespace process { namespace posix { namespace initializers { + +template <class IOService> +class notify_io_service_ : public initializer_base +{ +public: + explicit notify_io_service_(IOService &io_service) : + io_service_(io_service) {} + + template <class PosixExecutor> + void on_fork_setup(PosixExecutor&) const + { + io_service_.notify_fork(IOService::fork_prepare); + } + + template <class PosixExecutor> + void on_fork_success(PosixExecutor&) const + { + io_service_.notify_fork(IOService::fork_parent); + } + + template <class PosixExecutor> + void on_exec_setup(PosixExecutor&) const + { + io_service_.notify_fork(IOService::fork_child); + } + +private: + IOService &io_service_; +}; + +template <class IOService> +notify_io_service_<IOService> notify_io_service(IOService &io_service) +{ + return notify_io_service_<IOService>(io_service); +} + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/on_exec_error.hpp b/dep/process/boost/process/posix/initializers/on_exec_error.hpp new file mode 100644 index 00000000000..63b56def4f2 --- /dev/null +++ b/dep/process/boost/process/posix/initializers/on_exec_error.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_ON_EXEC_ERROR_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_ON_EXEC_ERROR_HPP + +#include <boost/process/config.hpp> +#include <boost/process/posix/initializers/initializer_base.hpp> + +namespace boost { namespace process { namespace posix { namespace initializers { + +template <class Handler> +class on_exec_error_ : public initializer_base +{ +public: + explicit on_exec_error_(Handler handler) : handler_(handler) {} + + template <class PosixExecutor> + void on_exec_error(PosixExecutor &e) const + { + handler_(e); + } + +private: + Handler handler_; +}; + +template <class Handler> +on_exec_error_<Handler> on_exec_error(Handler handler) +{ + return on_exec_error_<Handler>(handler); +} + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/on_exec_setup.hpp b/dep/process/boost/process/posix/initializers/on_exec_setup.hpp new file mode 100644 index 00000000000..50f5f3736b1 --- /dev/null +++ b/dep/process/boost/process/posix/initializers/on_exec_setup.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_ON_EXEC_SETUP_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_ON_EXEC_SETUP_HPP + +#include <boost/process/config.hpp> +#include <boost/process/posix/initializers/initializer_base.hpp> + +namespace boost { namespace process { namespace posix { namespace initializers { + +template <class Handler> +class on_exec_setup_ : public initializer_base +{ +public: + explicit on_exec_setup_(Handler handler) : handler_(handler) {} + + template <class PosixExecutor> + void on_exec_setup(PosixExecutor &e) const + { + handler_(e); + } + +private: + Handler handler_; +}; + +template <class Handler> +on_exec_setup_<Handler> on_exec_setup(Handler handler) +{ + return on_exec_setup_<Handler>(handler); +} + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/on_fork_error.hpp b/dep/process/boost/process/posix/initializers/on_fork_error.hpp new file mode 100644 index 00000000000..42ecf1aac91 --- /dev/null +++ b/dep/process/boost/process/posix/initializers/on_fork_error.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_ON_FORK_ERROR_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_ON_FORK_ERROR_HPP + +#include <boost/process/config.hpp> +#include <boost/process/posix/initializers/initializer_base.hpp> + +namespace boost { namespace process { namespace posix { namespace initializers { + +template <class Handler> +class on_fork_error_ : public initializer_base +{ +public: + explicit on_fork_error_(Handler handler) : handler_(handler) {} + + template <class PosixExecutor> + void on_fork_error(PosixExecutor &e) const + { + handler_(e); + } + +private: + Handler handler_; +}; + +template <class Handler> +on_fork_error_<Handler> on_fork_error(Handler handler) +{ + return on_fork_error_<Handler>(handler); +} + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/on_fork_setup.hpp b/dep/process/boost/process/posix/initializers/on_fork_setup.hpp new file mode 100644 index 00000000000..c0c5b0682f2 --- /dev/null +++ b/dep/process/boost/process/posix/initializers/on_fork_setup.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_ON_FORK_SETUP_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_ON_FORK_SETUP_HPP + +#include <boost/process/config.hpp> +#include <boost/process/posix/initializers/initializer_base.hpp> + +namespace boost { namespace process { namespace posix { namespace initializers { + +template <class Handler> +class on_fork_setup_ : public initializer_base +{ +public: + explicit on_fork_setup_(Handler handler) : handler_(handler) {} + + template <class PosixExecutor> + void on_fork_setup(PosixExecutor &e) const + { + handler_(e); + } + +private: + Handler handler_; +}; + +template <class Handler> +on_fork_setup_<Handler> on_fork_setup(Handler handler) +{ + return on_fork_setup_<Handler>(handler); +} + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/on_fork_success.hpp b/dep/process/boost/process/posix/initializers/on_fork_success.hpp new file mode 100644 index 00000000000..01c9b12db06 --- /dev/null +++ b/dep/process/boost/process/posix/initializers/on_fork_success.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_ON_FORK_SUCCESS_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_ON_FORK_SUCCESS_HPP + +#include <boost/process/config.hpp> +#include <boost/process/posix/initializers/initializer_base.hpp> + +namespace boost { namespace process { namespace posix { namespace initializers { + +template <class Handler> +class on_fork_success_ : public initializer_base +{ +public: + explicit on_fork_success_(Handler handler) : handler_(handler) {} + + template <class PosixExecutor> + void on_fork_success(PosixExecutor &e) const + { + handler_(e); + } + +private: + Handler handler_; +}; + +template <class Handler> +on_fork_success_<Handler> on_fork_success(Handler handler) +{ + return on_fork_success_<Handler>(handler); +} + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/run_exe.hpp b/dep/process/boost/process/posix/initializers/run_exe.hpp new file mode 100644 index 00000000000..6cceeea8c15 --- /dev/null +++ b/dep/process/boost/process/posix/initializers/run_exe.hpp @@ -0,0 +1,59 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_RUN_EXE_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_RUN_EXE_HPP + +#include <boost/process/posix/initializers/initializer_base.hpp> +#include <boost/filesystem.hpp> +#include <boost/shared_array.hpp> +#include <string> + +namespace boost { namespace process { namespace posix { namespace initializers { + +class run_exe_ : public initializer_base +{ +public: + explicit run_exe_(const std::string &s) : s_(s), cmd_line_(new char*[2]) + { + cmd_line_[0] = const_cast<char*>(s_.c_str()); + cmd_line_[1] = 0; + } + + template <class PosixExecutor> + void on_exec_setup(PosixExecutor &e) const + { + e.exe = s_.c_str(); + if (!e.cmd_line) + e.cmd_line = cmd_line_.get(); + } + +private: + std::string s_; + boost::shared_array<char*> cmd_line_; +}; + +inline run_exe_ run_exe(const char *s) +{ + return run_exe_(s); +} + +inline run_exe_ run_exe(const std::string &s) +{ + return run_exe_(s); +} + +inline run_exe_ run_exe(const boost::filesystem::path &p) +{ + return run_exe_(p.string()); +} + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/set_args.hpp b/dep/process/boost/process/posix/initializers/set_args.hpp new file mode 100644 index 00000000000..294926dc222 --- /dev/null +++ b/dep/process/boost/process/posix/initializers/set_args.hpp @@ -0,0 +1,57 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_SET_ARGS_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_SET_ARGS_HPP + +#include <boost/process/posix/initializers/initializer_base.hpp> +#include <boost/range/algorithm/transform.hpp> +#include <boost/shared_array.hpp> +#include <string> + +namespace boost { namespace process { namespace posix { namespace initializers { + +template <class Range> +class set_args_ : public initializer_base +{ +private: + static char *c_str(const std::string &s) + { + return const_cast<char*>(s.c_str()); + } + +public: + explicit set_args_(const Range &args) + { + args_.reset(new char*[args.size() + 1]); + boost::transform(args, args_.get(), c_str); + args_[args.size()] = 0; + } + + template <class PosixExecutor> + void on_exec_setup(PosixExecutor &e) const + { + e.cmd_line = args_.get(); + if (!e.exe && *args_[0]) + e.exe = args_[0]; + } + +private: + boost::shared_array<char*> args_; +}; + +template <class Range> +set_args_<Range> set_args(const Range &range) +{ + return set_args_<Range>(range); +} + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/set_cmd_line.hpp b/dep/process/boost/process/posix/initializers/set_cmd_line.hpp new file mode 100644 index 00000000000..0f59d253594 --- /dev/null +++ b/dep/process/boost/process/posix/initializers/set_cmd_line.hpp @@ -0,0 +1,54 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_SET_CMD_LINE_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_SET_CMD_LINE_HPP + +#include <boost/process/posix/initializers/initializer_base.hpp> +#include <boost/tokenizer.hpp> +#include <boost/shared_array.hpp> +#include <string> +#include <vector> + +namespace boost { namespace process { namespace posix { namespace initializers { + +class set_cmd_line : public initializer_base +{ +private: + static char *c_str(const std::string &s) + { + return const_cast<char*>(s.c_str()); + } + +public: + explicit set_cmd_line(const std::string &s) + { + typedef boost::tokenizer<boost::escaped_list_separator<char> > tokenizer; + boost::escaped_list_separator<char> sep('\\', ' ', '\"'); + tokenizer tok(s, sep); + args_.assign(tok.begin(), tok.end()); + cmd_line_.reset(new char*[args_.size() + 1]); + boost::transform(args_, cmd_line_.get(), c_str); + cmd_line_[args_.size()] = 0; + } + + template <class PosixExecutor> + void on_exec_setup(PosixExecutor &e) const + { + e.cmd_line = cmd_line_.get(); + } + +private: + std::vector<std::string> args_; + boost::shared_array<char*> cmd_line_; +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/set_env.hpp b/dep/process/boost/process/posix/initializers/set_env.hpp new file mode 100644 index 00000000000..76649184f34 --- /dev/null +++ b/dep/process/boost/process/posix/initializers/set_env.hpp @@ -0,0 +1,54 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_SET_ENV_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_SET_ENV_HPP + +#include <boost/process/posix/initializers/initializer_base.hpp> +#include <boost/range/algorithm/transform.hpp> +#include <boost/shared_array.hpp> +#include <string> + +namespace boost { namespace process { namespace posix { namespace initializers { + +template <class Range> +class set_env_ : public initializer_base +{ +private: + static char *get_ptr(const std::string &s) + { + return const_cast<char*>(s.c_str()); + } + +public: + explicit set_env_(const Range &envs) : env_(new char*[envs.size() + 1]) + { + boost::transform(envs, env_.get(), get_ptr); + env_[envs.size()] = 0; + } + + template <class PosixExecutor> + void on_fork_setup(PosixExecutor &e) const + { + e.env = env_.get(); + } + +private: + boost::shared_array<char*> env_; +}; + +template <class Range> +set_env_<Range> set_env(const Range &envs) +{ + return set_env_<Range>(envs); +} + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/set_on_error.hpp b/dep/process/boost/process/posix/initializers/set_on_error.hpp new file mode 100644 index 00000000000..c01a816e603 --- /dev/null +++ b/dep/process/boost/process/posix/initializers/set_on_error.hpp @@ -0,0 +1,95 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_SET_ON_ERROR_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_SET_ON_ERROR_HPP + +#include <boost/process/config.hpp> +#include <boost/process/posix/initializers/initializer_base.hpp> +#include <boost/system/error_code.hpp> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> + +namespace boost { namespace process { namespace posix { namespace initializers { + +class set_on_error : public initializer_base +{ +public: + explicit set_on_error(boost::system::error_code &ec) : ec_(ec) {} + + template <class PosixExecutor> + void on_fork_setup(PosixExecutor&) const + { + if (::pipe(fds_) == -1) + BOOST_PROCESS_RETURN_LAST_SYSTEM_ERROR(ec_); + if (::fcntl(fds_[1], F_SETFD, FD_CLOEXEC) == -1) + { + BOOST_PROCESS_RETURN_LAST_SYSTEM_ERROR(ec_); + ::close(fds_[0]); + ::close(fds_[1]); + } + } + + template <class PosixExecutor> + void on_fork_error(PosixExecutor&) const + { + if (!ec_) + { + BOOST_PROCESS_RETURN_LAST_SYSTEM_ERROR(ec_); + ::close(fds_[0]); + ::close(fds_[1]); + } + } + + template <class PosixExecutor> + void on_fork_success(PosixExecutor&) const + { + if (!ec_) + { + ::close(fds_[1]); + int code; + if (::read(fds_[0], &code, sizeof(int)) > 0) + { + ec_ = boost::system::error_code(code, + boost::system::system_category()); + } + ::close(fds_[0]); + } + } + + template <class PosixExecutor> + void on_exec_setup(PosixExecutor&) const + { + if (!ec_) + { + ::close(fds_[0]); + } + } + + template <class PosixExecutor> + void on_exec_error(PosixExecutor&) const + { + if (!ec_) + { + int e = errno; + while (::write(fds_[1], &e, sizeof(int)) == -1 && errno == EINTR) + ; + ::close(fds_[1]); + } + } + +private: + boost::system::error_code &ec_; + mutable int fds_[2]; +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/start_in_dir.hpp b/dep/process/boost/process/posix/initializers/start_in_dir.hpp new file mode 100644 index 00000000000..187b5a31f44 --- /dev/null +++ b/dep/process/boost/process/posix/initializers/start_in_dir.hpp @@ -0,0 +1,36 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_START_IN_DIR_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_START_IN_DIR_HPP + +#include <boost/process/posix/initializers/initializer_base.hpp> +#include <string> +#include <unistd.h> + +namespace boost { namespace process { namespace posix { namespace initializers { + +class start_in_dir : public initializer_base +{ +public: + explicit start_in_dir(const std::string &s) : s_(s) {} + + template <class PosixExecutor> + void on_exec_setup(PosixExecutor&) const + { + ::chdir(s_.c_str()); + } + +private: + std::string s_; +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/initializers/throw_on_error.hpp b/dep/process/boost/process/posix/initializers/throw_on_error.hpp new file mode 100644 index 00000000000..7734c19e30b --- /dev/null +++ b/dep/process/boost/process/posix/initializers/throw_on_error.hpp @@ -0,0 +1,90 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_INITIALIZERS_THROW_ON_ERROR_HPP +#define BOOST_PROCESS_POSIX_INITIALIZERS_THROW_ON_ERROR_HPP + +#include <boost/process/config.hpp> +#include <boost/process/posix/initializers/initializer_base.hpp> +#include <boost/system/error_code.hpp> +#include <boost/system/system_error.hpp> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> + +namespace boost { namespace process { namespace posix { namespace initializers { + +class throw_on_error : public initializer_base +{ +public: + template <class PosixExecutor> + void on_fork_setup(PosixExecutor&) const + { + if (::pipe(fds_) == -1) + BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("pipe(2) failed"); + if (::fcntl(fds_[1], F_SETFD, FD_CLOEXEC) == -1) + { + int e = errno; + ::close(fds_[0]); + ::close(fds_[1]); + BOOST_PROCESS_THROW(boost::system::system_error( + boost::system::error_code(e, boost::system::system_category()), + BOOST_PROCESS_SOURCE_LOCATION "fcntl(2) failed")); + } + } + + template <class PosixExecutor> + void on_fork_error(PosixExecutor&) const + { + int e = errno; + ::close(fds_[0]); + ::close(fds_[1]); + BOOST_PROCESS_THROW(boost::system::system_error( + boost::system::error_code(e, boost::system::system_category()), + BOOST_PROCESS_SOURCE_LOCATION "fork(2) failed")); + } + + template <class PosixExecutor> + void on_fork_success(PosixExecutor&) const + { + ::close(fds_[1]); + int code; + if (::read(fds_[0], &code, sizeof(int)) > 0) + { + ::close(fds_[0]); + BOOST_PROCESS_THROW(boost::system::system_error( + boost::system::error_code(code, + boost::system::system_category()), + BOOST_PROCESS_SOURCE_LOCATION "execve(2) failed")); + } + ::close(fds_[0]); + } + + template <class PosixExecutor> + void on_exec_setup(PosixExecutor&) const + { + ::close(fds_[0]); + } + + template <class PosixExecutor> + void on_exec_error(PosixExecutor&) const + { + int e = errno; + while (::write(fds_[1], &e, sizeof(int)) == -1 && errno == EINTR) + ; + ::close(fds_[1]); + } + +private: + mutable int fds_[2]; +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/posix/pipe.hpp b/dep/process/boost/process/posix/pipe.hpp new file mode 100644 index 00000000000..ca5b29447ab --- /dev/null +++ b/dep/process/boost/process/posix/pipe.hpp @@ -0,0 +1,30 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_PIPE_HPP +#define BOOST_PROCESS_POSIX_PIPE_HPP + +namespace boost { namespace process { namespace posix { + +struct pipe +{ + int source; + int sink; + + pipe(int source, int sink) : source(source), sink(sink) {} +}; + +inline pipe make_pipe(int source, int sink) +{ + return pipe(source, sink); +} + +}}} + +#endif diff --git a/dep/process/boost/process/posix/search_path.hpp b/dep/process/boost/process/posix/search_path.hpp new file mode 100644 index 00000000000..6dc2bea063d --- /dev/null +++ b/dep/process/boost/process/posix/search_path.hpp @@ -0,0 +1,53 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_SEARCH_PATH_HPP +#define BOOST_PROCESS_POSIX_SEARCH_PATH_HPP + +#include <boost/process/config.hpp> +#include <boost/filesystem.hpp> +#include <boost/tokenizer.hpp> +#include <string> +#include <stdexcept> +#include <stdlib.h> +#include <unistd.h> + +namespace boost { namespace process { namespace posix { + +inline std::string search_path(const std::string &filename, + std::string path = "") +{ + if (path.empty()) + { + path = ::getenv("PATH"); + if (path.empty()) + BOOST_PROCESS_THROW(std::runtime_error( + "Environment variable PATH not found")); + } + + std::string result; + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + boost::char_separator<char> sep(":"); + tokenizer tok(path, sep); + for (tokenizer::iterator it = tok.begin(); it != tok.end(); ++it) + { + boost::filesystem::path p = *it; + p /= filename; + if (!::access(p.c_str(), X_OK)) + { + result = p.string(); + break; + } + } + return result; +} + +}}} + +#endif diff --git a/dep/process/boost/process/posix/shell_path.hpp b/dep/process/boost/process/posix/shell_path.hpp new file mode 100644 index 00000000000..3e21e757591 --- /dev/null +++ b/dep/process/boost/process/posix/shell_path.hpp @@ -0,0 +1,32 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_SHELL_PATH_HPP +#define BOOST_PROCESS_POSIX_SHELL_PATH_HPP + +#include <boost/process/config.hpp> +#include <boost/system/error_code.hpp> +#include <boost/filesystem/path.hpp> + +namespace boost { namespace process { namespace posix { + +inline boost::filesystem::path shell_path() +{ + return "/bin/sh"; +} + +inline boost::filesystem::path shell_path(boost::system::error_code &ec) +{ + ec.clear(); + return "/bin/sh"; +} + +}}} + +#endif diff --git a/dep/process/boost/process/posix/terminate.hpp b/dep/process/boost/process/posix/terminate.hpp new file mode 100644 index 00000000000..9be087df253 --- /dev/null +++ b/dep/process/boost/process/posix/terminate.hpp @@ -0,0 +1,37 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_TERMINATE_HPP +#define BOOST_PROCESS_POSIX_TERMINATE_HPP + +#include <boost/process/config.hpp> +#include <boost/system/error_code.hpp> +#include <signal.h> + +namespace boost { namespace process { namespace posix { + +template <class Process> +void terminate(const Process &p) +{ + if (::kill(p.pid, SIGKILL) == -1) + BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("kill(2) failed"); +} + +template <class Process> +void terminate(const Process &p, boost::system::error_code &ec) +{ + if (::kill(p.pid, SIGKILL) == -1) + BOOST_PROCESS_RETURN_LAST_SYSTEM_ERROR(ec); + else + ec.clear(); +} + +}}} + +#endif diff --git a/dep/process/boost/process/posix/wait_for_exit.hpp b/dep/process/boost/process/posix/wait_for_exit.hpp new file mode 100644 index 00000000000..d2b946c262a --- /dev/null +++ b/dep/process/boost/process/posix/wait_for_exit.hpp @@ -0,0 +1,52 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_POSIX_WAIT_FOR_EXIT_HPP +#define BOOST_PROCESS_POSIX_WAIT_FOR_EXIT_HPP + +#include <boost/process/config.hpp> +#include <boost/system/error_code.hpp> +#include <sys/types.h> +#include <sys/wait.h> + +namespace boost { namespace process { namespace posix { + +template <class Process> +inline int wait_for_exit(const Process &p) +{ + pid_t ret; + int status; + do + { + ret = ::waitpid(p.pid, &status, 0); + } while ((ret == -1 && errno == EINTR) || (ret != -1 && !WIFEXITED(status))); + if (ret == -1) + BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("waitpid(2) failed"); + return status; +} + +template <class Process> +inline int wait_for_exit(const Process &p, boost::system::error_code &ec) +{ + pid_t ret; + int status; + do + { + ret = ::waitpid(p.pid, &status, 0); + } while ((ret == -1 && errno == EINTR) || (ret != -1 && !WIFEXITED(status))); + if (ret == -1) + BOOST_PROCESS_RETURN_LAST_SYSTEM_ERROR(ec); + else + ec.clear(); + return status; +} + +}}} + +#endif diff --git a/dep/process/boost/process/search_path.hpp b/dep/process/boost/process/search_path.hpp new file mode 100644 index 00000000000..20bff060b62 --- /dev/null +++ b/dep/process/boost/process/search_path.hpp @@ -0,0 +1,51 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/** + * \file boost/process/search_path.hpp + * + * Defines a function to search for an executable in path. + */ + +#ifndef BOOST_PROCESS_SEARCH_PATH_HPP +#define BOOST_PROCESS_SEARCH_PATH_HPP + +#include <boost/process/config.hpp> + +#include BOOST_PROCESS_PLATFORM_PROMOTE_PATH(search_path) +BOOST_PROCESS_PLATFORM_PROMOTE_NAMESPACE(search_path) + +#if defined(BOOST_PROCESS_DOXYGEN) +namespace boost { namespace process { + +/** + * Searches for an executable in path. + * + * filename must be a basename including the file extension. + * It must not include any directory separators (like a slash). + * On Windows the file extension may be omitted. The function + * will then try the various file extensions for executables on + * Windows to find filename. + * + * path must be a set of directories. Directories must be + * separated by colons on POSIX and by semicolons on Windows. + * If path is empty, the environment variable PATH is used. + * + * \returns the absolute path to the executable filename or an + * empty string if filename isn't found + * + * \throws std::runtime_error if path is empty and no environment + * variable PATH exists + */ +string_type search_path(const string_type &filename, string_type path = ""); + +}} +#endif + +#endif diff --git a/dep/process/boost/process/shell_path.hpp b/dep/process/boost/process/shell_path.hpp new file mode 100644 index 00000000000..92e9f0814b0 --- /dev/null +++ b/dep/process/boost/process/shell_path.hpp @@ -0,0 +1,46 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/** + * \file boost/process/shell_path.hpp + * + * Defines a function to return the absolute path to a shell executable. + */ + +#ifndef BOOST_PROCESS_SHELL_PATH_HPP +#define BOOST_PROCESS_SHELL_PATH_HPP + +#include <boost/process/config.hpp> + +#include BOOST_PROCESS_PLATFORM_PROMOTE_PATH(shell_path) +BOOST_PROCESS_PLATFORM_PROMOTE_NAMESPACE(shell_path) + +#if defined(BOOST_PROCESS_DOXYGEN) +namespace boost { namespace process { + +/** + * Returns the absolute path to a shell executable. + * + * \returns the path to cmd.exe on Windows and /bin/sh on POSIX. + * + * \throws boost::system::system_error in case of an error + */ +boost::filesystem::path shell_path(); + +/** + * Returns the absolute path to a shell executable. + * + * \returns the path to cmd.exe on Windows and /bin/sh on POSIX. + */ +boost::filesystem::path shell_path(boost::system::error_code &ec); + +}} +#endif + +#endif diff --git a/dep/process/boost/process/terminate.hpp b/dep/process/boost/process/terminate.hpp new file mode 100644 index 00000000000..140eba7e8dd --- /dev/null +++ b/dep/process/boost/process/terminate.hpp @@ -0,0 +1,52 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/** + * \file boost/process/terminate.hpp + * + * Defines a function to terminate a process. + */ + +#ifndef BOOST_PROCESS_TERMINATE_HPP +#define BOOST_PROCESS_TERMINATE_HPP + +#include <boost/process/config.hpp> + +#include BOOST_PROCESS_PLATFORM_PROMOTE_PATH(terminate) +BOOST_PROCESS_PLATFORM_PROMOTE_NAMESPACE(terminate) + +#if defined(BOOST_PROCESS_DOXYGEN) +namespace boost { namespace process { + +/** + * Terminates a process. + * + * \warning Call this function only as a last resort. The process + * is terminated immediately and forcefully and has no + * chance to close or clean up resources properly. + * + * \throws boost::system::system_error in case of an error + */ +template <class Process> +void terminate(const Process &p); + +/** + * Terminates a process. + * + * \warning Call this function only as a last resort. The process + * is terminated immediately and forcefully and has no + * chance to close or clean up resources properly. + */ +template <class Process> +void terminate(const Process &p, boost::system::error_code &ec); + +}} +#endif + +#endif diff --git a/dep/process/boost/process/wait_for_exit.hpp b/dep/process/boost/process/wait_for_exit.hpp new file mode 100644 index 00000000000..d9b118695d7 --- /dev/null +++ b/dep/process/boost/process/wait_for_exit.hpp @@ -0,0 +1,58 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/** + * \file boost/process/wait_for_exit.hpp + * + * Defines a function to wait for a process to exit. + */ + +#ifndef BOOST_PROCESS_WAIT_FOR_EXIT_HPP +#define BOOST_PROCESS_WAIT_FOR_EXIT_HPP + +#include <boost/process/config.hpp> + +#include BOOST_PROCESS_PLATFORM_PROMOTE_PATH(wait_for_exit) +BOOST_PROCESS_PLATFORM_PROMOTE_NAMESPACE(wait_for_exit) + +#if defined(BOOST_PROCESS_DOXYGEN) +namespace boost { namespace process { + +/** + * Waits for a process to exit. + * + * On Window boost::process::wait_for_exit returns the exit code + * of the process. On POSIX the exit status is returned. You must + * use the macro \c WEXITSTATUS (defined in sys/wait.h) to fetch + * the exit code from the exit status. + * + * \note This is a blocking function. + * + * \throws boost::system::system_error in case of an error + */ +template <class Process> +int_type wait_for_exit(const Process &p); + +/** + * Waits for a process to exit. + * + * On Window boost::process::wait_for_exit returns the exit code + * of the process. On POSIX the exit status is returned. You must + * use the macro \c WEXITSTATUS (defined in sys/wait.h) to fetch + * the exit code from the exit status. + * + * \note This is a blocking function. + */ +template <class Process> +int_type wait_for_exit(const Process &p, boost::system::error_code &ec); + +}} +#endif + +#endif diff --git a/dep/process/boost/process/windows/child.hpp b/dep/process/boost/process/windows/child.hpp new file mode 100644 index 00000000000..083cd29da0e --- /dev/null +++ b/dep/process/boost/process/windows/child.hpp @@ -0,0 +1,55 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_CHILD_HPP +#define BOOST_PROCESS_WINDOWS_CHILD_HPP + +#include <boost/move/move.hpp> +#include <Windows.h> + +namespace boost { namespace process { namespace windows { + +class child +{ +public: + PROCESS_INFORMATION proc_info; + + explicit child(const PROCESS_INFORMATION &pi) : proc_info(pi) {} + + ~child() + { + ::CloseHandle(proc_info.hProcess); + ::CloseHandle(proc_info.hThread); + } + + child(BOOST_RV_REF(child) c) : proc_info(c.proc_info) + { + c.proc_info.hProcess = INVALID_HANDLE_VALUE; + c.proc_info.hThread = INVALID_HANDLE_VALUE; + } + + child &operator=(BOOST_RV_REF(child) c) + { + ::CloseHandle(proc_info.hProcess); + ::CloseHandle(proc_info.hThread); + proc_info = c.proc_info; + c.proc_info.hProcess = INVALID_HANDLE_VALUE; + c.proc_info.hThread = INVALID_HANDLE_VALUE; + return *this; + } + + HANDLE process_handle() const { return proc_info.hProcess; } + +private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(child); +}; + +}}} + +#endif diff --git a/dep/process/boost/process/windows/create_pipe.hpp b/dep/process/boost/process/windows/create_pipe.hpp new file mode 100644 index 00000000000..fe1e49751d8 --- /dev/null +++ b/dep/process/boost/process/windows/create_pipe.hpp @@ -0,0 +1,40 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_CREATE_PIPE_HPP +#define BOOST_PROCESS_WINDOWS_CREATE_PIPE_HPP + +#include <boost/process/config.hpp> +#include <boost/process/windows/pipe.hpp> +#include <boost/system/error_code.hpp> +#include <Windows.h> + +namespace boost { namespace process { namespace windows { + +inline pipe create_pipe() +{ + HANDLE handles[2]; + if (!::CreatePipe(&handles[0], &handles[1], NULL, 0)) + BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreatePipe() failed"); + return make_pipe(handles[0], handles[1]); +} + +inline pipe create_pipe(boost::system::error_code &ec) +{ + HANDLE handles[2]; + if (!::CreatePipe(&handles[0], &handles[1], NULL, 0)) + BOOST_PROCESS_RETURN_LAST_SYSTEM_ERROR(ec); + else + ec.clear(); + return make_pipe(handles[0], handles[1]); +} + +}}} + +#endif diff --git a/dep/process/boost/process/windows/execute.hpp b/dep/process/boost/process/windows/execute.hpp new file mode 100644 index 00000000000..43067521ead --- /dev/null +++ b/dep/process/boost/process/windows/execute.hpp @@ -0,0 +1,82 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_EXECUTE_HPP +#define BOOST_PROCESS_WINDOWS_EXECUTE_HPP + +#include <boost/process/windows/executor.hpp> +#include <boost/process/windows/child.hpp> +#include <boost/fusion/tuple/make_tuple.hpp> +#include <boost/ref.hpp> + +namespace boost { namespace process { namespace windows { + +template <class I0> +child execute(const I0 &i0) +{ + return executor()(boost::fusion::make_tuple(boost::cref(i0))); +} + +template <class I0, class I1> +child execute(const I0 &i0, const I1 &i1) +{ + return executor()(boost::fusion::make_tuple(boost::cref(i0), boost::cref(i1))); +} + +template <class I0, class I1, class I2> +child execute(const I0 &i0, const I1 &i1, const I2 &i2) +{ + return executor()(boost::fusion::make_tuple(boost::cref(i0), boost::cref(i1), boost::cref(i2))); +} + +template <class I0, class I1, class I2, class I3> +child execute(const I0 &i0, const I1 &i1, const I2 &i2, const I3 &i3) +{ + return executor()(boost::fusion::make_tuple(boost::cref(i0), boost::cref(i1), boost::cref(i2), boost::cref(i3))); +} + +template <class I0, class I1, class I2, class I3, class I4> +child execute(const I0 &i0, const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4) +{ + return executor()(boost::fusion::make_tuple(boost::cref(i0), boost::cref(i1), boost::cref(i2), boost::cref(i3), boost::cref(i4))); +} + +template <class I0, class I1, class I2, class I3, class I4, class I5> +child execute(const I0 &i0, const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4, const I5 &i5) +{ + return executor()(boost::fusion::make_tuple(boost::cref(i0), boost::cref(i1), boost::cref(i2), boost::cref(i3), boost::cref(i4), boost::cref(i5))); +} + +template <class I0, class I1, class I2, class I3, class I4, class I5, class I6> +child execute(const I0 &i0, const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4, const I5 &i5, const I6 &i6) +{ + return executor()(boost::fusion::make_tuple(boost::cref(i0), boost::cref(i1), boost::cref(i2), boost::cref(i3), boost::cref(i4), boost::cref(i5), boost::cref(i6))); +} + +template <class I0, class I1, class I2, class I3, class I4, class I5, class I6, class I7> +child execute(const I0 &i0, const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4, const I5 &i5, const I6 &i6, const I7 &i7) +{ + return executor()(boost::fusion::make_tuple(boost::cref(i0), boost::cref(i1), boost::cref(i2), boost::cref(i3), boost::cref(i4), boost::cref(i5), boost::cref(i6), boost::cref(i7))); +} + +template <class I0, class I1, class I2, class I3, class I4, class I5, class I6, class I7, class I8> +child execute(const I0 &i0, const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4, const I5 &i5, const I6 &i6, const I7 &i7, const I8 &i8) +{ + return executor()(boost::fusion::make_tuple(boost::cref(i0), boost::cref(i1), boost::cref(i2), boost::cref(i3), boost::cref(i4), boost::cref(i5), boost::cref(i6), boost::cref(i7), boost::cref(i8))); +} + +template <class I0, class I1, class I2, class I3, class I4, class I5, class I6, class I7, class I8, class I9> +child execute(const I0 &i0, const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4, const I5 &i5, const I6 &i6, const I7 &i7, const I8 &i8, const I9 &i9) +{ + return executor()(boost::fusion::make_tuple(boost::cref(i0), boost::cref(i1), boost::cref(i2), boost::cref(i3), boost::cref(i4), boost::cref(i5), boost::cref(i6), boost::cref(i7), boost::cref(i8), boost::cref(i9))); +} + +}}} + +#endif diff --git a/dep/process/boost/process/windows/executor.hpp b/dep/process/boost/process/windows/executor.hpp new file mode 100644 index 00000000000..1560f30793d --- /dev/null +++ b/dep/process/boost/process/windows/executor.hpp @@ -0,0 +1,130 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_EXECUTOR_HPP +#define BOOST_PROCESS_WINDOWS_EXECUTOR_HPP + +#include <boost/process/windows/child.hpp> +#include <boost/fusion/algorithm/iteration/for_each.hpp> +#include <Windows.h> + +namespace boost { namespace process { namespace windows { + +struct executor +{ + executor() : exe(0), cmd_line(0), proc_attrs(0), thread_attrs(0), + inherit_handles(FALSE), +#if (_WIN32_WINNT >= 0x0600) + creation_flags(EXTENDED_STARTUPINFO_PRESENT), +#else + creation_flags(0), +#endif + env(0), work_dir(0) +#if (_WIN32_WINNT >= 0x0600) + ,startup_info(startup_info_ex.StartupInfo) +#endif + { +#if (_WIN32_WINNT >= 0x0600) + ZeroMemory(&startup_info_ex, sizeof(STARTUPINFOEX)); + startup_info.cb = sizeof(STARTUPINFOEX); +#else + ZeroMemory(&startup_info, sizeof(STARTUPINFO)); + startup_info.cb = sizeof(STARTUPINFO); +#endif + startup_info.hStdInput = INVALID_HANDLE_VALUE; + startup_info.hStdOutput = INVALID_HANDLE_VALUE; + startup_info.hStdError = INVALID_HANDLE_VALUE; + } + + struct call_on_CreateProcess_setup + { + executor &e_; + + call_on_CreateProcess_setup(executor &e) : e_(e) {} + + template <class Arg> + void operator()(Arg &arg) const + { + arg.on_CreateProcess_setup(e_); + } + }; + + struct call_on_CreateProcess_error + { + executor &e_; + + call_on_CreateProcess_error(executor &e) : e_(e) {} + + template <class Arg> + void operator()(Arg &arg) const + { + arg.on_CreateProcess_error(e_); + } + }; + + struct call_on_CreateProcess_success + { + executor &e_; + + call_on_CreateProcess_success(executor &e) : e_(e) {} + + template <class Arg> + void operator()(Arg &arg) const + { + arg.on_CreateProcess_success(e_); + } + }; + + template <class InitializerSequence> + child operator()(const InitializerSequence &seq) + { + boost::fusion::for_each(seq, call_on_CreateProcess_setup(*this)); + + if (!::CreateProcess( + exe, + cmd_line, + proc_attrs, + thread_attrs, + inherit_handles, + creation_flags, + env, + work_dir, + &startup_info, + &proc_info)) + { + boost::fusion::for_each(seq, call_on_CreateProcess_error(*this)); + } + else + { + boost::fusion::for_each(seq, call_on_CreateProcess_success(*this)); + } + + return child(proc_info); + } + + LPCTSTR exe; + LPTSTR cmd_line; + LPSECURITY_ATTRIBUTES proc_attrs; + LPSECURITY_ATTRIBUTES thread_attrs; + BOOL inherit_handles; + DWORD creation_flags; + LPVOID env; + LPCTSTR work_dir; +#if (_WIN32_WINNT >= 0x0600) + STARTUPINFOEX startup_info_ex; + STARTUPINFO &startup_info; +#else + STARTUPINFO startup_info; +#endif + PROCESS_INFORMATION proc_info; +}; + +}}} + +#endif diff --git a/dep/process/boost/process/windows/initializers.hpp b/dep/process/boost/process/windows/initializers.hpp new file mode 100644 index 00000000000..2d7098c034c --- /dev/null +++ b/dep/process/boost/process/windows/initializers.hpp @@ -0,0 +1,33 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_HPP + +#include <boost/process/windows/initializers/bind_stderr.hpp> +#include <boost/process/windows/initializers/bind_stdin.hpp> +#include <boost/process/windows/initializers/bind_stdout.hpp> +#include <boost/process/windows/initializers/close_stderr.hpp> +#include <boost/process/windows/initializers/close_stdin.hpp> +#include <boost/process/windows/initializers/close_stdout.hpp> +#include <boost/process/windows/initializers/hide_console.hpp> +#include <boost/process/windows/initializers/inherit_env.hpp> +#include <boost/process/windows/initializers/on_CreateProcess_error.hpp> +#include <boost/process/windows/initializers/on_CreateProcess_setup.hpp> +#include <boost/process/windows/initializers/on_CreateProcess_success.hpp> +#include <boost/process/windows/initializers/run_exe.hpp> +#include <boost/process/windows/initializers/set_args.hpp> +#include <boost/process/windows/initializers/set_cmd_line.hpp> +#include <boost/process/windows/initializers/set_env.hpp> +#include <boost/process/windows/initializers/set_on_error.hpp> +#include <boost/process/windows/initializers/show_window.hpp> +#include <boost/process/windows/initializers/start_in_dir.hpp> +#include <boost/process/windows/initializers/throw_on_error.hpp> + +#endif diff --git a/dep/process/boost/process/windows/initializers/bind_stderr.hpp b/dep/process/boost/process/windows/initializers/bind_stderr.hpp new file mode 100644 index 00000000000..de3ee30dc53 --- /dev/null +++ b/dep/process/boost/process/windows/initializers/bind_stderr.hpp @@ -0,0 +1,39 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_BIND_STDERR_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_BIND_STDERR_HPP + +#include <boost/process/windows/initializers/initializer_base.hpp> +#include <boost/iostreams/device/file_descriptor.hpp> +#include <Windows.h> + +namespace boost { namespace process { namespace windows { namespace initializers { + +class bind_stderr : public initializer_base +{ +public: + explicit bind_stderr(const boost::iostreams::file_descriptor_sink &sink) : sink_(sink) {} + + template <class WindowsExecutor> + void on_CreateProcess_setup(WindowsExecutor &e) const + { + ::SetHandleInformation(sink_.handle(), HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); + e.startup_info.hStdError = sink_.handle(); + e.startup_info.dwFlags |= STARTF_USESTDHANDLES; + e.inherit_handles = true; + } + +private: + boost::iostreams::file_descriptor_sink sink_; +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/windows/initializers/bind_stdin.hpp b/dep/process/boost/process/windows/initializers/bind_stdin.hpp new file mode 100644 index 00000000000..54c942ab639 --- /dev/null +++ b/dep/process/boost/process/windows/initializers/bind_stdin.hpp @@ -0,0 +1,39 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_BIND_STDIN_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_BIND_STDIN_HPP + +#include <boost/process/windows/initializers/initializer_base.hpp> +#include <boost/iostreams/device/file_descriptor.hpp> +#include <Windows.h> + +namespace boost { namespace process { namespace windows { namespace initializers { + +class bind_stdin : public initializer_base +{ +public: + explicit bind_stdin(const boost::iostreams::file_descriptor_source &source) : source_(source) {} + + template <class WindowsExecutor> + void on_CreateProcess_setup(WindowsExecutor &e) const + { + ::SetHandleInformation(source_.handle(), HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); + e.startup_info.hStdInput = source_.handle(); + e.startup_info.dwFlags |= STARTF_USESTDHANDLES; + e.inherit_handles = true; + } + +private: + boost::iostreams::file_descriptor_source source_; +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/windows/initializers/bind_stdout.hpp b/dep/process/boost/process/windows/initializers/bind_stdout.hpp new file mode 100644 index 00000000000..c72c05f1bfb --- /dev/null +++ b/dep/process/boost/process/windows/initializers/bind_stdout.hpp @@ -0,0 +1,39 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_BIND_STDOUT_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_BIND_STDOUT_HPP + +#include <boost/process/windows/initializers/initializer_base.hpp> +#include <boost/iostreams/device/file_descriptor.hpp> +#include <Windows.h> + +namespace boost { namespace process { namespace windows { namespace initializers { + +class bind_stdout : public initializer_base +{ +public: + explicit bind_stdout(const boost::iostreams::file_descriptor_sink &sink) : sink_(sink) {} + + template <class WindowsExecutor> + void on_CreateProcess_setup(WindowsExecutor &e) const + { + ::SetHandleInformation(sink_.handle(), HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); + e.startup_info.hStdOutput = sink_.handle(); + e.startup_info.dwFlags |= STARTF_USESTDHANDLES; + e.inherit_handles = true; + } + +private: + boost::iostreams::file_descriptor_sink sink_; +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/windows/initializers/close_stderr.hpp b/dep/process/boost/process/windows/initializers/close_stderr.hpp new file mode 100644 index 00000000000..373c097f3ab --- /dev/null +++ b/dep/process/boost/process/windows/initializers/close_stderr.hpp @@ -0,0 +1,31 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_CLOSE_STDERR_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_CLOSE_STDERR_HPP + +#include <boost/process/windows/initializers/initializer_base.hpp> +#include <Windows.h> + +namespace boost { namespace process { namespace windows { namespace initializers { + +class close_stderr : public initializer_base +{ +public: + template <class WindowsExecutor> + void on_CreateProcess_setup(WindowsExecutor &e) const + { + e.startup_info.hStdError = INVALID_HANDLE_VALUE; + e.startup_info.dwFlags |= STARTF_USESTDHANDLES; + } +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/windows/initializers/close_stdin.hpp b/dep/process/boost/process/windows/initializers/close_stdin.hpp new file mode 100644 index 00000000000..036b0bb4ce9 --- /dev/null +++ b/dep/process/boost/process/windows/initializers/close_stdin.hpp @@ -0,0 +1,31 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_CLOSE_STDIN_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_CLOSE_STDIN_HPP + +#include <boost/process/windows/initializers/initializer_base.hpp> +#include <Windows.h> + +namespace boost { namespace process { namespace windows { namespace initializers { + +class close_stdin : public initializer_base +{ +public: + template <class WindowsExecutor> + void on_CreateProcess_setup(WindowsExecutor &e) const + { + e.startup_info.hStdInput = INVALID_HANDLE_VALUE; + e.startup_info.dwFlags |= STARTF_USESTDHANDLES; + } +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/windows/initializers/close_stdout.hpp b/dep/process/boost/process/windows/initializers/close_stdout.hpp new file mode 100644 index 00000000000..b58a6000f9c --- /dev/null +++ b/dep/process/boost/process/windows/initializers/close_stdout.hpp @@ -0,0 +1,31 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_CLOSE_STDOUT_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_CLOSE_STDOUT_HPP + +#include <boost/process/windows/initializers/initializer_base.hpp> +#include <Windows.h> + +namespace boost { namespace process { namespace windows { namespace initializers { + +class close_stdout : public initializer_base +{ +public: + template <class WindowsExecutor> + void on_CreateProcess_setup(WindowsExecutor &e) const + { + e.startup_info.hStdOutput = INVALID_HANDLE_VALUE; + e.startup_info.dwFlags |= STARTF_USESTDHANDLES; + } +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/windows/initializers/hide_console.hpp b/dep/process/boost/process/windows/initializers/hide_console.hpp new file mode 100644 index 00000000000..b01aa026f0e --- /dev/null +++ b/dep/process/boost/process/windows/initializers/hide_console.hpp @@ -0,0 +1,31 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_HIDE_CONSOLE_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_HIDE_CONSOLE_HPP + +#include <boost/process/windows/initializers/initializer_base.hpp> +#include <Windows.h> + +namespace boost { namespace process { namespace windows { namespace initializers { + +class hide_console : public initializer_base +{ +public: + template <class WindowsExecutor> + void on_CreateProcess_setup(WindowsExecutor &e) const + { + e.startup_info.dwFlags |= STARTF_USESHOWWINDOW; + e.startup_info.wShowWindow |= SW_HIDE; + } +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/windows/initializers/inherit_env.hpp b/dep/process/boost/process/windows/initializers/inherit_env.hpp new file mode 100644 index 00000000000..a2b2eda00a3 --- /dev/null +++ b/dep/process/boost/process/windows/initializers/inherit_env.hpp @@ -0,0 +1,24 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_INHERIT_ENV_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_INHERIT_ENV_HPP + +#include <boost/process/windows/initializers/initializer_base.hpp> + +namespace boost { namespace process { namespace windows { namespace initializers { + +class inherit_env : public initializer_base +{ +public: +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/windows/initializers/initializer_base.hpp b/dep/process/boost/process/windows/initializers/initializer_base.hpp new file mode 100644 index 00000000000..b98da7b21b9 --- /dev/null +++ b/dep/process/boost/process/windows/initializers/initializer_base.hpp @@ -0,0 +1,29 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_INITIALIZER_BASE_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_INITIALIZER_BASE_HPP + +namespace boost { namespace process { namespace windows { namespace initializers { + +struct initializer_base +{ + template <class WindowsExecutor> + void on_CreateProcess_setup(WindowsExecutor&) const {} + + template <class WindowsExecutor> + void on_CreateProcess_error(WindowsExecutor&) const {} + + template <class WindowsExecutor> + void on_CreateProcess_success(WindowsExecutor&) const {} +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/windows/initializers/on_CreateProcess_error.hpp b/dep/process/boost/process/windows/initializers/on_CreateProcess_error.hpp new file mode 100644 index 00000000000..71eeada0720 --- /dev/null +++ b/dep/process/boost/process/windows/initializers/on_CreateProcess_error.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_ON_CREATEPROCESS_ERROR_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_ON_CREATEPROCESS_ERROR_HPP + +#include <boost/process/config.hpp> +#include <boost/process/windows/initializers/initializer_base.hpp> + +namespace boost { namespace process { namespace windows { namespace initializers { + +template <class Handler> +class on_CreateProcess_error_ : public initializer_base +{ +public: + explicit on_CreateProcess_error_(Handler handler) : handler_(handler) {} + + template <class WindowsExecutor> + void on_CreateProcess_error(WindowsExecutor &e) const + { + handler_(e); + } + +private: + Handler handler_; +}; + +template <class Handler> +on_CreateProcess_error_<Handler> on_CreateProcess_error(Handler handler) +{ + return on_CreateProcess_error_<Handler>(handler); +} + +}}}} + +#endif diff --git a/dep/process/boost/process/windows/initializers/on_CreateProcess_setup.hpp b/dep/process/boost/process/windows/initializers/on_CreateProcess_setup.hpp new file mode 100644 index 00000000000..671fc9ac5c2 --- /dev/null +++ b/dep/process/boost/process/windows/initializers/on_CreateProcess_setup.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_ON_CREATEPROCESS_SETUP_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_ON_CREATEPROCESS_SETUP_HPP + +#include <boost/process/config.hpp> +#include <boost/process/windows/initializers/initializer_base.hpp> + +namespace boost { namespace process { namespace windows { namespace initializers { + +template <class Handler> +class on_CreateProcess_setup_ : public initializer_base +{ +public: + explicit on_CreateProcess_setup_(Handler handler) : handler_(handler) {} + + template <class WindowsExecutor> + void on_CreateProcess_setup(WindowsExecutor &e) const + { + handler_(e); + } + +private: + Handler handler_; +}; + +template <class Handler> +on_CreateProcess_setup_<Handler> on_CreateProcess_setup(Handler handler) +{ + return on_CreateProcess_setup_<Handler>(handler); +} + +}}}} + +#endif diff --git a/dep/process/boost/process/windows/initializers/on_CreateProcess_success.hpp b/dep/process/boost/process/windows/initializers/on_CreateProcess_success.hpp new file mode 100644 index 00000000000..67b3b2bdcf7 --- /dev/null +++ b/dep/process/boost/process/windows/initializers/on_CreateProcess_success.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_ON_CREATEPROCESS_SUCCESS_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_ON_CREATEPROCESS_SUCCESS_HPP + +#include <boost/process/config.hpp> +#include <boost/process/windows/initializers/initializer_base.hpp> + +namespace boost { namespace process { namespace windows { namespace initializers { + +template <class Handler> +class on_CreateProcess_success_ : public initializer_base +{ +public: + explicit on_CreateProcess_success_(Handler handler) : handler_(handler) {} + + template <class WindowsExecutor> + void on_CreateProcess_sucess(WindowsExecutor &e) const + { + handler_(e); + } + +private: + Handler handler_; +}; + +template <class Handler> +on_CreateProcess_success_<Handler> on_CreateProcess_success(Handler handler) +{ + return on_CreateProcess_success_<Handler>(handler); +} + +}}}} + +#endif diff --git a/dep/process/boost/process/windows/initializers/run_exe.hpp b/dep/process/boost/process/windows/initializers/run_exe.hpp new file mode 100644 index 00000000000..bfa2b790b17 --- /dev/null +++ b/dep/process/boost/process/windows/initializers/run_exe.hpp @@ -0,0 +1,69 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_RUN_EXE_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_RUN_EXE_HPP + +#include <boost/process/windows/initializers/initializer_base.hpp> +#include <boost/filesystem.hpp> +#include <string> + +namespace boost { namespace process { namespace windows { namespace initializers { + +template <class String> +class run_exe_ : public initializer_base +{ +public: + explicit run_exe_(const String &s) : s_(s) {} + + template <class WindowsExecutor> + void on_CreateProcess_setup(WindowsExecutor &e) const + { + e.exe = s_.c_str(); + } + +private: + String s_; +}; + +#if defined(_UNICODE) || defined(UNICODE) +inline run_exe_<std::wstring> run_exe(const wchar_t *ws) +{ + return run_exe_<std::wstring>(ws); +} + +inline run_exe_<std::wstring> run_exe(const std::wstring &ws) +{ + return run_exe_<std::wstring>(ws); +} + +inline run_exe_<std::wstring> run_exe(const boost::filesystem::path &p) +{ + return run_exe_<std::wstring>(p.wstring()); +} +#else +inline run_exe_<std::string> run_exe(const char *s) +{ + return run_exe_<std::string>(s); +} + +inline run_exe_<std::string> run_exe(const std::string &s) +{ + return run_exe_<std::string>(s); +} + +inline run_exe_<std::string> run_exe(const boost::filesystem::path &p) +{ + return run_exe_<std::string>(p.string()); +} +#endif + +}}}} + +#endif diff --git a/dep/process/boost/process/windows/initializers/set_args.hpp b/dep/process/boost/process/windows/initializers/set_args.hpp new file mode 100644 index 00000000000..4b3c5b6249e --- /dev/null +++ b/dep/process/boost/process/windows/initializers/set_args.hpp @@ -0,0 +1,87 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_SET_ARGS_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_SET_ARGS_HPP + +#include <boost/process/windows/initializers/initializer_base.hpp> +#include <boost/range/begin.hpp> +#include <boost/range/end.hpp> +#include <boost/range/algorithm/copy.hpp> +#include <boost/algorithm/string/predicate.hpp> +#include <boost/shared_array.hpp> +#include <sstream> + +namespace boost { namespace process { namespace windows { namespace initializers { + +template <class Range> +class set_args_ : public initializer_base +{ +private: + typedef typename Range::const_iterator ConstIterator; + typedef typename Range::value_type String; + typedef typename String::value_type Char; + typedef std::basic_ostringstream<Char> OStringStream; + +public: + explicit set_args_(const Range &args) + { + ConstIterator it = boost::const_begin(args); + ConstIterator end = boost::const_end(args); + if (it != end) + { + exe_ = *it; + OStringStream os; + for (; it != end; ++it) + { + if (boost::algorithm::contains(*it, + String(1, static_cast<Char>(' ')))) + { + os << static_cast<Char>('"') << *it << + static_cast<Char>('"'); + } + else + { + os << *it; + } + os << static_cast<Char>(' '); + } + String s = os.str(); + cmd_line_.reset(new Char[s.size() + 1]); + boost::copy(s, cmd_line_.get()); + cmd_line_[s.size()] = 0; + } + else + { + cmd_line_.reset(new Char[1]()); + } + } + + template <class WindowsExecutor> + void on_CreateProcess_setup(WindowsExecutor &e) const + { + e.cmd_line = cmd_line_.get(); + if (!e.exe && !exe_.empty()) + e.exe = exe_.c_str(); + } + +private: + boost::shared_array<Char> cmd_line_; + String exe_; +}; + +template <class Range> +set_args_<Range> set_args(const Range &range) +{ + return set_args_<Range>(range); +} + +}}}} + +#endif diff --git a/dep/process/boost/process/windows/initializers/set_cmd_line.hpp b/dep/process/boost/process/windows/initializers/set_cmd_line.hpp new file mode 100644 index 00000000000..a3d9f6f7615 --- /dev/null +++ b/dep/process/boost/process/windows/initializers/set_cmd_line.hpp @@ -0,0 +1,68 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_SET_CMD_LINE_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_SET_CMD_LINE_HPP + +#include <boost/process/windows/initializers/initializer_base.hpp> +#include <boost/range/algorithm/copy.hpp> +#include <boost/shared_array.hpp> +#include <memory> + +namespace boost { namespace process { namespace windows { namespace initializers { + +template <class String> +class set_cmd_line_ : public initializer_base +{ +private: + typedef typename String::value_type Char; + +public: + explicit set_cmd_line_(const String &s) + : cmd_line_(new Char[s.size() + 1]) + { + boost::copy(s, cmd_line_.get()); + cmd_line_[s.size()] = 0; + } + + template <class WindowsExecutor> + void on_CreateProcess_setup(WindowsExecutor &e) const + { + e.cmd_line = cmd_line_.get(); + } + +private: + boost::shared_array<Char> cmd_line_; +}; + +#if defined(_UNICODE) || defined(UNICODE) +inline set_cmd_line_<std::wstring> set_cmd_line(const wchar_t *ws) +{ + return set_cmd_line_<std::wstring>(ws); +} + +inline set_cmd_line_<std::wstring> set_cmd_line(const std::wstring &ws) +{ + return set_cmd_line_<std::wstring>(ws); +} +#else +inline set_cmd_line_<std::string> set_cmd_line(const char *s) +{ + return set_cmd_line_<std::string>(s); +} + +inline set_cmd_line_<std::string> set_cmd_line(const std::string &s) +{ + return set_cmd_line_<std::string>(s); +} +#endif + +}}}} + +#endif diff --git a/dep/process/boost/process/windows/initializers/set_env.hpp b/dep/process/boost/process/windows/initializers/set_env.hpp new file mode 100644 index 00000000000..6dfdfc58a48 --- /dev/null +++ b/dep/process/boost/process/windows/initializers/set_env.hpp @@ -0,0 +1,88 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_SET_ENV_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_SET_ENV_HPP + +#include <Windows.h> +#include <boost/process/windows/initializers/initializer_base.hpp> +#include <boost/range/numeric.hpp> +#include <boost/range/algorithm/copy.hpp> +#include <boost/range/algorithm/for_each.hpp> +#include <boost/shared_array.hpp> +#include <iterator> +#include <cstddef> + +namespace boost { namespace process { namespace windows { namespace initializers { + +template <class Range, bool Unicode> +class set_env_ : public initializer_base +{ +private: + typedef typename Range::value_type String; + typedef typename String::value_type Char; + + static std::size_t add_size(std::size_t size, const String &s) + { + return size + s.size() + 1u; + } + + struct copy + { + Char *it_; + + copy(Char *it) : it_(it) {} + + void operator()(const String &s) + { + it_ = boost::copy(s, it_); + *it_ = 0; + ++it_; + } + }; + +public: + set_env_(const Range &envs) + : size_(boost::accumulate(envs, 0, add_size) + 1), + env_(new Char[size_]) + { + boost::for_each(envs, copy(env_.get())); + env_[size_ - 1] = 0; + } + + template <class WindowsExecutor> + void on_CreateProcess_setup(WindowsExecutor &e) const + { + e.env = env_.get(); + if (Unicode) + e.creation_flags |= CREATE_UNICODE_ENVIRONMENT; + } + +private: + std::size_t size_; + boost::shared_array<Char> env_; +}; + +#if defined(_UNICODE) || defined(UNICODE) +template <class Range> +set_env_<Range, true> set_env(const Range &envs) +{ + return set_env_<Range, true>(envs); +} +#else +template <class Range> +set_env_<Range, false> set_env(const Range &envs) +{ + return set_env_<Range, false>(envs); +} +#endif + +}}}} + +#endif diff --git a/dep/process/boost/process/windows/initializers/set_on_error.hpp b/dep/process/boost/process/windows/initializers/set_on_error.hpp new file mode 100644 index 00000000000..695ea5904d7 --- /dev/null +++ b/dep/process/boost/process/windows/initializers/set_on_error.hpp @@ -0,0 +1,36 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_SET_ON_ERROR_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_SET_ON_ERROR_HPP + +#include <boost/process/config.hpp> +#include <boost/process/windows/initializers/initializer_base.hpp> +#include <boost/system/error_code.hpp> + +namespace boost { namespace process { namespace windows { namespace initializers { + +class set_on_error : public initializer_base +{ +public: + explicit set_on_error(boost::system::error_code &ec) : ec_(ec) {} + + template <class WindowsExecutor> + void on_CreateProcess_error(WindowsExecutor&) const + { + BOOST_PROCESS_RETURN_LAST_SYSTEM_ERROR(ec_); + } + +private: + boost::system::error_code &ec_; +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/windows/initializers/show_window.hpp b/dep/process/boost/process/windows/initializers/show_window.hpp new file mode 100644 index 00000000000..3046179205a --- /dev/null +++ b/dep/process/boost/process/windows/initializers/show_window.hpp @@ -0,0 +1,36 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_SHOW_WINDOW_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_SHOW_WINDOW_HPP + +#include <boost/process/windows/initializers/initializer_base.hpp> +#include <Windows.h> + +namespace boost { namespace process { namespace windows { namespace initializers { + +class show_window : public initializer_base +{ +public: + explicit show_window(WORD flags) : flags_(flags) {} + + template <class WindowsExecutor> + void on_CreateProcess_setup(WindowsExecutor &e) const + { + e.startup_info.dwFlags |= STARTF_USESHOWWINDOW; + e.startup_info.wShowWindow |= flags_; + } + +private: + WORD flags_; +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/windows/initializers/start_in_dir.hpp b/dep/process/boost/process/windows/initializers/start_in_dir.hpp new file mode 100644 index 00000000000..8dc952abcc0 --- /dev/null +++ b/dep/process/boost/process/windows/initializers/start_in_dir.hpp @@ -0,0 +1,69 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_START_IN_DIR_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_START_IN_DIR_HPP + +#include <boost/process/windows/initializers/initializer_base.hpp> +#include <boost/filesystem/path.hpp> +#include <string> + +namespace boost { namespace process { namespace windows { namespace initializers { + +template <class String> +class start_in_dir_ : public initializer_base +{ +public: + explicit start_in_dir_(const String &s) : s_(s) {} + + template <class WindowsExecutor> + void on_CreateProcess_setup(WindowsExecutor &e) const + { + e.work_dir = s_.c_str(); + } + +private: + String s_; +}; + +#if defined(_UNICODE) || defined(UNICODE) +inline start_in_dir_<std::wstring> start_in_dir(const wchar_t *ws) +{ + return start_in_dir_<std::wstring>(ws); +} + +inline start_in_dir_<std::wstring> start_in_dir(const std::wstring &ws) +{ + return start_in_dir_<std::wstring>(ws); +} + +inline start_in_dir_<std::wstring> start_in_dir(const boost::filesystem::path &p) +{ + return start_in_dir_<std::wstring>(p.wstring()); +} +#else +inline start_in_dir_<std::string> start_in_dir(const char *s) +{ + return start_in_dir_<std::string>(s); +} + +inline start_in_dir_<std::string> start_in_dir(const std::string &s) +{ + return start_in_dir_<std::string>(s); +} + +inline start_in_dir_<std::string> start_in_dir(const boost::filesystem::path &p) +{ + return start_in_dir_<std::string>(p.string()); +} +#endif + +}}}} + +#endif diff --git a/dep/process/boost/process/windows/initializers/throw_on_error.hpp b/dep/process/boost/process/windows/initializers/throw_on_error.hpp new file mode 100644 index 00000000000..044fa004177 --- /dev/null +++ b/dep/process/boost/process/windows/initializers/throw_on_error.hpp @@ -0,0 +1,30 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_THROW_ON_ERROR_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_THROW_ON_ERROR_HPP + +#include <boost/process/config.hpp> +#include <boost/process/windows/initializers/initializer_base.hpp> + +namespace boost { namespace process { namespace windows { namespace initializers { + +class throw_on_error : public initializer_base +{ +public: + template <class WindowsExecutor> + void on_CreateProcess_error(WindowsExecutor&) const + { + BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateProcess() failed"); + } +}; + +}}}} + +#endif diff --git a/dep/process/boost/process/windows/pipe.hpp b/dep/process/boost/process/windows/pipe.hpp new file mode 100644 index 00000000000..fd912afcc9e --- /dev/null +++ b/dep/process/boost/process/windows/pipe.hpp @@ -0,0 +1,32 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_PIPE_HPP +#define BOOST_PROCESS_WINDOWS_PIPE_HPP + +#include <Windows.h> + +namespace boost { namespace process { namespace windows { + +struct pipe +{ + HANDLE source; + HANDLE sink; + + pipe(HANDLE source, HANDLE sink) : source(source), sink(sink) {} +}; + +inline pipe make_pipe(HANDLE source, HANDLE sink) +{ + return pipe(source, sink); +} + +}}} + +#endif diff --git a/dep/process/boost/process/windows/search_path.hpp b/dep/process/boost/process/windows/search_path.hpp new file mode 100644 index 00000000000..62bb5f27454 --- /dev/null +++ b/dep/process/boost/process/windows/search_path.hpp @@ -0,0 +1,104 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_SEARCH_PATH_HPP +#define BOOST_PROCESS_WINDOWS_SEARCH_PATH_HPP + +#include <boost/process/config.hpp> +#include <boost/filesystem.hpp> +#include <boost/tokenizer.hpp> +#include <boost/array.hpp> +#include <boost/system/error_code.hpp> +#include <string> +#include <stdexcept> +#include <stdlib.h> +#include <Shellapi.h> + +namespace boost { namespace process { namespace windows { + +#if defined(_UNICODE) || defined(UNICODE) +inline std::wstring search_path(const std::wstring &filename, + std::wstring path = L"") +{ + if (path.empty()) + { + path = ::_wgetenv(L"PATH"); + if (path.empty()) + BOOST_PROCESS_THROW(std::runtime_error( + "Environment variable PATH not found")); + } + + typedef boost::tokenizer<boost::char_separator<wchar_t>, + std::wstring::const_iterator, std::wstring> tokenizer; + boost::char_separator<wchar_t> sep(L";"); + tokenizer tok(path, sep); + for (tokenizer::iterator it = tok.begin(); it != tok.end(); ++it) + { + boost::filesystem::path p = *it; + p /= filename; + boost::array<std::wstring, 4> extensions = + { L"", L".exe", L".com", L".bat" }; + for (boost::array<std::wstring, 4>::iterator it2 = extensions.begin(); + it2 != extensions.end(); ++it2) + { + boost::filesystem::path p2 = p; + p2 += *it2; + boost::system::error_code ec; + bool file = boost::filesystem::is_regular_file(p2, ec); + if (!ec && file && + SHGetFileInfoW(p2.c_str(), 0, 0, 0, SHGFI_EXETYPE)) + { + return p2.wstring(); + } + } + } + return L""; +} +#else +inline std::string search_path(const std::string &filename, + std::string path = "") +{ + if (path.empty()) + { + path = ::getenv("PATH"); + if (path.empty()) + BOOST_PROCESS_THROW(std::runtime_error( + "Environment variable PATH not found")); + } + + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + boost::char_separator<char> sep(";"); + tokenizer tok(path, sep); + for (tokenizer::iterator it = tok.begin(); it != tok.end(); ++it) + { + boost::filesystem::path p = *it; + p /= filename; + boost::array<std::string, 4> extensions = + { "", ".exe", ".com", ".bat" }; + for (boost::array<std::string, 4>::iterator it2 = extensions.begin(); + it2 != extensions.end(); ++it2) + { + boost::filesystem::path p2 = p; + p2 += *it2; + boost::system::error_code ec; + bool file = boost::filesystem::is_regular_file(p2, ec); + if (!ec && file && + SHGetFileInfoA(p2.string().c_str(), 0, 0, 0, SHGFI_EXETYPE)) + { + return p2.string(); + } + } + } + return ""; +} +#endif + +}}} + +#endif diff --git a/dep/process/boost/process/windows/shell_path.hpp b/dep/process/boost/process/windows/shell_path.hpp new file mode 100644 index 00000000000..ace15b96e10 --- /dev/null +++ b/dep/process/boost/process/windows/shell_path.hpp @@ -0,0 +1,50 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_SHELL_PATH_HPP +#define BOOST_PROCESS_WINDOWS_SHELL_PATH_HPP + +#include <boost/process/config.hpp> +#include <boost/system/error_code.hpp> +#include <boost/filesystem/path.hpp> +#include <Windows.h> + +namespace boost { namespace process { namespace windows { + +inline boost::filesystem::path shell_path() +{ + TCHAR sysdir[MAX_PATH]; + UINT size = ::GetSystemDirectory(sysdir, sizeof(sysdir)); + if (!size) + BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("GetSystemDirectory() failed"); + boost::filesystem::path p = sysdir; + return p / "cmd.exe"; +} + +inline boost::filesystem::path shell_path(boost::system::error_code &ec) +{ + TCHAR sysdir[MAX_PATH]; + UINT size = ::GetSystemDirectory(sysdir, sizeof(sysdir)); + boost::filesystem::path p; + if (!size) + { + BOOST_PROCESS_RETURN_LAST_SYSTEM_ERROR(ec); + } + else + { + ec.clear(); + p = sysdir; + p /= "cmd.exe"; + } + return p; +} + +}}} + +#endif diff --git a/dep/process/boost/process/windows/terminate.hpp b/dep/process/boost/process/windows/terminate.hpp new file mode 100644 index 00000000000..43afe250a6a --- /dev/null +++ b/dep/process/boost/process/windows/terminate.hpp @@ -0,0 +1,38 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_TERMINATE_HPP +#define BOOST_PROCESS_WINDOWS_TERMINATE_HPP + +#include <boost/process/config.hpp> +#include <boost/system/error_code.hpp> +#include <cstdlib> +#include <Windows.h> + +namespace boost { namespace process { namespace windows { + +template <class Process> +void terminate(const Process &p) +{ + if (!::TerminateProcess(p.process_handle(), EXIT_FAILURE)) + BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("TerminateProcess() failed"); +} + +template <class Process> +void terminate(const Process &p, boost::system::error_code &ec) +{ + if (!::TerminateProcess(p.process_handle(), EXIT_FAILURE)) + BOOST_PROCESS_RETURN_LAST_SYSTEM_ERROR(ec); + else + ec.clear(); +} + +}}} + +#endif diff --git a/dep/process/boost/process/windows/wait_for_exit.hpp b/dep/process/boost/process/windows/wait_for_exit.hpp new file mode 100644 index 00000000000..23a8b9a9f18 --- /dev/null +++ b/dep/process/boost/process/windows/wait_for_exit.hpp @@ -0,0 +1,49 @@ +// Copyright (c) 2006, 2007 Julio M. Merino Vidal +// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling +// Copyright (c) 2009 Boris Schaeling +// Copyright (c) 2010 Felipe Tanus, Boris Schaeling +// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_PROCESS_WINDOWS_WAIT_FOR_EXIT_HPP +#define BOOST_PROCESS_WINDOWS_WAIT_FOR_EXIT_HPP + +#include <boost/process/config.hpp> +#include <boost/system/error_code.hpp> +#include <Windows.h> + +namespace boost { namespace process { namespace windows { + +template <class Process> +inline DWORD wait_for_exit(const Process &p) +{ + if (::WaitForSingleObject(p.process_handle(), INFINITE) == WAIT_FAILED) + BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("WaitForSingleObject() failed"); + + DWORD exit_code; + if (!::GetExitCodeProcess(p.process_handle(), &exit_code)) + BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("GetExitCodeProcess() failed"); + + return exit_code; +} + +template <class Process> +inline DWORD wait_for_exit(const Process &p, boost::system::error_code &ec) +{ + DWORD exit_code = 1; + + if (::WaitForSingleObject(p.process_handle(), INFINITE) == WAIT_FAILED) + BOOST_PROCESS_RETURN_LAST_SYSTEM_ERROR(ec); + else if (!::GetExitCodeProcess(p.process_handle(), &exit_code)) + BOOST_PROCESS_RETURN_LAST_SYSTEM_ERROR(ec); + else + ec.clear(); + + return exit_code; +} + +}}} + +#endif diff --git a/revision.h.in.cmake b/revision.h.in.cmake index f50c8022062..c0eb651489f 100644 --- a/revision.h.in.cmake +++ b/revision.h.in.cmake @@ -3,6 +3,9 @@ #define _HASH "@rev_hash@" #define _DATE "@rev_date@" #define _BRANCH "@rev_branch@" + #define _SOURCE_DIRECTORY "@CMAKE_SOURCE_DIR@" + #define _MYSQL_EXECUTABLE "@MYSQL_EXECUTABLE@" + #define _FULL_DATABASE "TDB_full_6.00_2014_10_19.sql" #define VER_COMPANYNAME_STR "TrinityCore Developers" #define VER_LEGALCOPYRIGHT_STR "(c)2008-2015 TrinityCore" #define VER_FILEVERSION 0,0,0 diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql index 6fba92991d9..d4bc9246ed2 100644 --- a/sql/base/auth_database.sql +++ b/sql/base/auth_database.sql @@ -622,3 +622,60 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2014-12-28 23:10:07 + +-- Updates base tables +DROP TABLE IF EXISTS `updates`; +CREATE TABLE `updates` ( + `name` VARCHAR(200) NOT NULL COMMENT 'filename with extension of the update.', + `hash` CHAR(40) NULL DEFAULT '' COMMENT 'sha1 hash of the sql file.', + `state` ENUM('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if an update is released or archived.', + `timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'timestamp when the query was applied.', + `speed` INT(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'time the query takes to apply in ms.', + PRIMARY KEY (`name`) +) +COMMENT='List of all applied updates in this database.' +COLLATE='utf8_general_ci' +ENGINE=MyISAM; + +DROP TABLE IF EXISTS `updates_include`; +CREATE TABLE `updates_include` ( + `path` VARCHAR(200) NOT NULL COMMENT 'directory to include. $ means relative to the source directory.', + `state` ENUM('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if the directory contains released or archived updates.', + PRIMARY KEY (`path`) +) +COMMENT='List of directories where we want to include sql updates.' +COLLATE='utf8_general_ci' +ENGINE=MyISAM; + +-- Auth database update data +TRUNCATE TABLE `updates_include`; +INSERT INTO `updates_include` (`path`, `state`) VALUES +('$/sql/updates/auth', 'RELEASED'), +('$/sql/custom/auth', 'RELEASED'), +('$/sql/old/6.x/auth', 'ARCHIVED'); + +INSERT IGNORE INTO `updates` (`name`, `hash`) VALUES +('2014_10_04_00_auth.sql', 'C3BC70A6EC381474B7308F442346F1E721176BC6'), +('2014_10_19_00_auth.sql', '7472B490A4F86C9D3DA609CDD3197499CB80C87C'), +('2014_10_26_00_auth.sql', '75CC67ADE2A3B2E54FD57D6B0DCAA8FE50F4EE35'), +('2014_11_03_00_auth.sql', '5948C9F286CF0FEA8E241785C0259FF36B73BDC5'), +('2014_11_04_00_auth.sql', '3AFC68B2375C2A417DDEA94583C53AFF83DE50DF'), +('2014_11_09_00_auth.sql', 'B8DD1A7047C0FDDB80344B239343EC33BF1A0D97'), +('2014_11_10_00_auth.sql', '8FBA737A1D3FF4631A1E662A5B500A8BD304EC63'), +('2014_11_10_00_auth_from_335.sql', '0E3CB119442D09DD88E967015319BBC8DAFBBFE0'), +('2014_11_10_01_auth.sql', '327E77A1DA3546D5275AB249915DD57EDD6FDD3D'), +('2014_11_23_00_auth.sql', '0BBEB3EB3AED0FEF277A062819B6B2C00084A742'), +('2014_11_25_00_auth.sql', '4F45CDB26BDBB3EE83F1988E3D7818C5926ADC02'), +('2014_12_05_00_auth.sql', '6A7BBCEF43111C73A2D2C3CCB6911BE50DE7DD94'), +('2014_12_10_00_auth.sql', '821703A96D80F9080074852B5A46E2909C9562EA'), +('2014_12_19_00_auth.sql', '44D8E12FFF327AD07878FBDF8D9C16B6B7DCB122'), +('2014_12_20_00_auth.sql', '4DAA02AE285C02AE6C82EA2C8B97AC71990F1085'), +('2014_12_25_00_auth.sql', '61411930F482BC73FC7FD2C370C811E944F5FF92'), +('2014_12_27_00_auth.sql', 'CE2E5D2CD82E79C25294539ADED27A1429105B43'), +('2014_12_28_00_auth.sql', '0A913217610E76AFF119C27259737BBC523090E6'), +('2015_02_22_00_auth.sql', '21CCCF8B01252E16CA3D6C9E3E8DAA4C9B28ED6E'), +('2015_03_01_00_auth.sql', '911881E273207FF6182D1FDAC8C85FFAE8F1C852'), +('2015_03_10_00_auth.sql', '2CC8502C11412EFEB5C11BE166761A8754A59009'), +('2015_03_20_00_auth.sql', 'B761760804EA73BD297F296C5C1919687DF7191C'), +('2015_03_20_01_auth.sql', '5CCEDF20C8189FB1E8DF064A9F0DDC342841FBF0'), +('2015_03_20_02_auth.sql', ''); diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index b37dd5dffac..69c367a56c8 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -2986,3 +2986,58 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2015-01-27 22:41:44 + +-- Updates base tables +DROP TABLE IF EXISTS `updates`; +CREATE TABLE `updates` ( + `name` VARCHAR(200) NOT NULL COMMENT 'filename with extension of the update.', + `hash` CHAR(40) NULL DEFAULT '' COMMENT 'sha1 hash of the sql file.', + `state` ENUM('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if an update is released or archived.', + `timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'timestamp when the query was applied.', + `speed` INT(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'time the query takes to apply in ms.', + PRIMARY KEY (`name`) +) +COMMENT='List of all applied updates in this database.' +COLLATE='utf8_general_ci' +ENGINE=MyISAM; + +DROP TABLE IF EXISTS `updates_include`; +CREATE TABLE `updates_include` ( + `path` VARCHAR(200) NOT NULL COMMENT 'directory to include. $ means relative to the source directory.', + `state` ENUM('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if the directory contains released or archived updates.', + PRIMARY KEY (`path`) +) +COMMENT='List of directories where we want to include sql updates.' +COLLATE='utf8_general_ci' +ENGINE=MyISAM; + +-- Characters database update data +TRUNCATE TABLE `updates_include`; +INSERT INTO `updates_include` (`path`, `state`) VALUES +('$/sql/updates/characters', 'RELEASED'), +('$/sql/custom/characters', 'RELEASED'), +('$/sql/old/6.x/characters', 'ARCHIVED'); + +INSERT IGNORE INTO `updates` (`name`, `hash`) VALUES +('2014_10_20_00_characters.sql', 'A5882DA0979CF4DAE33DA011EBAA006C24BE7230'), +('2014_10_23_00_characters.sql', 'E2AC4758133EE19B7F08464A445802154D1261C8'), +('2014_10_23_01_characters.sql', '20029E6323D9773B32C34D84FFED1711CC60F09F'), +('2014_10_23_02_characters.sql', '8A7A16886EE71E7ACDDB3DDA6D0ECAC2FD2FDCA8'), +('2014_10_24_00_characters.sql', 'D008FE81AE844FCA686439D6ECC5108FB0DD1EB9'), +('2014_10_25_00_characters.sql', 'A39C7BE46686B54776BDAB9D7A882D91EDEC51A4'), +('2014_10_26_00_characters.sql', 'C787954CC35FE34B4101FDE6527F14C027F4947C'), +('2014_11_12_00_characters.sql', 'B160BB2313F1BD5F3B076A5A9279DC10D4796E34'), +('2014_12_23_00_characters.sql', '3D9D648B2387B357F4BD090B33F80682F7924882'), +('2014_12_28_00_characters.sql', '5362922FF4483A336311D73082A5727309CD9219'), +('2014_12_31_00_characters.sql', '498DDF2DD936CF156D74A8208DC93DCE9FCAB5AA'), +('2015_01_02_00_characters.sql', 'E5940BE836F253982E07930120422E598D08BDE1'), +('2015_01_10_00_characters.sql', '30796056C8623699B2FE1BF626A19D38262E9284'), +('2015_01_16_00_characters.sql', '96642760A54C8D799AAFE438049A63AA521656F2'), +('2015_01_27_00_characters.sql', 'EB710E3EB9F2CAFD84AB62CDC84E898403A80A4F'), +('2015_02_13_00_characters.sql', '405BEB4ED207DC6076442A37EE2AFB1F21E274A0'), +('2015_02_13_01_characters.sql', '35F582D4F33BF55D1685A1BA89273ED895FD09C5'), +('2015_02_17_00_characters.sql', '8D21FC5A55BF8B55D6DCDCE5F02CF2B640230E94'), +('2015_03_10_00_characters.sql', 'E565B89B145C340067742DFF2DEF1B74F5F1BD4E'), +('2015_03_20_00_characters.sql', 'B761760804EA73BD297F296C5C1919687DF7191C'), +('2015_03_20_01_characters.sql', '20BD68468C57FCF7E665B4DA185DCD52FACE8B3F'), +('2015_03_20_02_characters.sql', ''); diff --git a/sql/base/dev/hotfixes_database.sql b/sql/base/dev/hotfixes_database.sql deleted file mode 100644 index 0d5a5d2f23c..00000000000 --- a/sql/base/dev/hotfixes_database.sql +++ /dev/null @@ -1,18 +0,0 @@ --- MySQL dump 10.13 Distrib 5.6.9-rc, for Win64 (x86_64) --- --- Host: localhost Database: hotfixes --- ------------------------------------------------------ --- Server version 5.6.9-rc - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - --- Dump completed on 2014-10-19 23:50:46 diff --git a/sql/base/hotfixes_database.sql b/sql/base/hotfixes_database.sql new file mode 100644 index 00000000000..61ec102c295 --- /dev/null +++ b/sql/base/hotfixes_database.sql @@ -0,0 +1,56 @@ +-- MySQL dump 10.13 Distrib 5.6.9-rc, for Win64 (x86_64) +-- +-- Host: localhost Database: hotfixes +-- ------------------------------------------------------ +-- Server version 5.6.9-rc + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- Dump completed on 2014-10-19 23:50:46 + +-- Workaround for the update system +-- As long as no full hotfix db exists + +-- Updates base tables +DROP TABLE IF EXISTS `updates`; +CREATE TABLE `updates` ( + `name` VARCHAR(200) NOT NULL COMMENT 'filename with extension of the update.', + `hash` CHAR(40) NULL DEFAULT '' COMMENT 'sha1 hash of the sql file.', + `state` ENUM('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if an update is released or archived.', + `timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'timestamp when the query was applied.', + `speed` INT(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'time the query takes to apply in ms.', + PRIMARY KEY (`name`) +) +COMMENT='List of all applied updates in this database.' +COLLATE='utf8_general_ci' +ENGINE=MyISAM; + +DROP TABLE IF EXISTS `updates_include`; +CREATE TABLE `updates_include` ( + `path` VARCHAR(200) NOT NULL COMMENT 'directory to include. $ means relative to the source directory.', + `state` ENUM('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if the directory contains released or archived updates.', + PRIMARY KEY (`path`) +) +COMMENT='List of directories where we want to include sql updates.' +COLLATE='utf8_general_ci' +ENGINE=MyISAM; + +-- Hotfixes database update data +TRUNCATE TABLE `updates_include`; +INSERT INTO `updates_include` (`path`, `state`) VALUES +('$/sql/updates/hotfixes', 'RELEASED'), +('$/sql/custom/hotfixes', 'RELEASED'), +('$/sql/old/6.x/hotfixes', 'ARCHIVED'); + +INSERT IGNORE INTO `updates` (`name`, `hash`) VALUES +('2015_03_20_00_hotfixes.sql', 'B761760804EA73BD297F296C5C1919687DF7191C'), +('2015_03_20_01_hotfixes.sql', 'A79521F16AE82F0D7487495D0BF7A726D81F250D'); diff --git a/sql/custom/auth/.gitignore b/sql/custom/auth/.gitignore new file mode 100644 index 00000000000..d1b811b7de5 --- /dev/null +++ b/sql/custom/auth/.gitignore @@ -0,0 +1 @@ +*.sql diff --git a/sql/custom/characters/.gitignore b/sql/custom/characters/.gitignore new file mode 100644 index 00000000000..d1b811b7de5 --- /dev/null +++ b/sql/custom/characters/.gitignore @@ -0,0 +1 @@ +*.sql diff --git a/sql/custom/hotfixes/.gitignore b/sql/custom/hotfixes/.gitignore new file mode 100644 index 00000000000..d1b811b7de5 --- /dev/null +++ b/sql/custom/hotfixes/.gitignore @@ -0,0 +1 @@ +*.sql diff --git a/sql/custom/world/.gitignore b/sql/custom/world/.gitignore new file mode 100644 index 00000000000..d1b811b7de5 --- /dev/null +++ b/sql/custom/world/.gitignore @@ -0,0 +1 @@ +*.sql diff --git a/sql/old/6.x/auth/CREATE_SUBDIRECTORIES_HERE b/sql/old/6.x/auth/CREATE_SUBDIRECTORIES_HERE new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/sql/old/6.x/auth/CREATE_SUBDIRECTORIES_HERE diff --git a/sql/old/6.x/characters/CREATE_SUBDIRECTORIES_HERE b/sql/old/6.x/characters/CREATE_SUBDIRECTORIES_HERE new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/sql/old/6.x/characters/CREATE_SUBDIRECTORIES_HERE diff --git a/sql/old/6.x/hotfixes/CREATE_SUBDIRECTORIES_HERE b/sql/old/6.x/hotfixes/CREATE_SUBDIRECTORIES_HERE new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/sql/old/6.x/hotfixes/CREATE_SUBDIRECTORIES_HERE diff --git a/sql/old/6.x/world/CREATE_SUBDIRECTORIES_HERE b/sql/old/6.x/world/CREATE_SUBDIRECTORIES_HERE new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/sql/old/6.x/world/CREATE_SUBDIRECTORIES_HERE diff --git a/sql/updates/auth/2015_03_20_00_auth.sql b/sql/updates/auth/2015_03_20_00_auth.sql new file mode 100644 index 00000000000..05c120274da --- /dev/null +++ b/sql/updates/auth/2015_03_20_00_auth.sql @@ -0,0 +1,23 @@ +-- Updates base tables +DROP TABLE IF EXISTS `updates`; +CREATE TABLE `updates` ( + `name` VARCHAR(200) NOT NULL COMMENT 'filename with extension of the update.', + `hash` CHAR(40) NULL DEFAULT '' COMMENT 'sha1 hash of the sql file.', + `state` ENUM('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if an update is released or archived.', + `timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'timestamp when the query was applied.', + `speed` INT(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'time the query takes to apply in ms.', + PRIMARY KEY (`name`) +) +COMMENT='List of all applied updates in this database.' +COLLATE='utf8_general_ci' +ENGINE=MyISAM; + +DROP TABLE IF EXISTS `updates_include`; +CREATE TABLE `updates_include` ( + `path` VARCHAR(200) NOT NULL COMMENT 'directory to include. $ means relative to the source directory.', + `state` ENUM('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if the directory contains released or archived updates.', + PRIMARY KEY (`path`) +) +COMMENT='List of directories where we want to include sql updates.' +COLLATE='utf8_general_ci' +ENGINE=MyISAM; diff --git a/sql/updates/auth/2015_03_20_01_auth.sql b/sql/updates/auth/2015_03_20_01_auth.sql new file mode 100644 index 00000000000..ecee16a2274 --- /dev/null +++ b/sql/updates/auth/2015_03_20_01_auth.sql @@ -0,0 +1,6 @@ +-- Auth database update data +TRUNCATE TABLE `updates_include`; +INSERT INTO `updates_include` (`path`, `state`) VALUES +('$/sql/updates/auth', 'RELEASED'), +('$/sql/custom/auth', 'RELEASED'), +('$/sql/old/6.x/auth', 'ARCHIVED'); diff --git a/sql/updates/auth/2015_03_20_02_auth.sql b/sql/updates/auth/2015_03_20_02_auth.sql new file mode 100644 index 00000000000..12427489f01 --- /dev/null +++ b/sql/updates/auth/2015_03_20_02_auth.sql @@ -0,0 +1,25 @@ +INSERT IGNORE INTO `updates` (`name`, `hash`) VALUES +('2014_10_04_00_auth.sql', 'C3BC70A6EC381474B7308F442346F1E721176BC6'), +('2014_10_19_00_auth.sql', '7472B490A4F86C9D3DA609CDD3197499CB80C87C'), +('2014_10_26_00_auth.sql', '75CC67ADE2A3B2E54FD57D6B0DCAA8FE50F4EE35'), +('2014_11_03_00_auth.sql', '5948C9F286CF0FEA8E241785C0259FF36B73BDC5'), +('2014_11_04_00_auth.sql', '3AFC68B2375C2A417DDEA94583C53AFF83DE50DF'), +('2014_11_09_00_auth.sql', 'B8DD1A7047C0FDDB80344B239343EC33BF1A0D97'), +('2014_11_10_00_auth.sql', '8FBA737A1D3FF4631A1E662A5B500A8BD304EC63'), +('2014_11_10_00_auth_from_335.sql', '0E3CB119442D09DD88E967015319BBC8DAFBBFE0'), +('2014_11_10_01_auth.sql', '327E77A1DA3546D5275AB249915DD57EDD6FDD3D'), +('2014_11_23_00_auth.sql', '0BBEB3EB3AED0FEF277A062819B6B2C00084A742'), +('2014_11_25_00_auth.sql', '4F45CDB26BDBB3EE83F1988E3D7818C5926ADC02'), +('2014_12_05_00_auth.sql', '6A7BBCEF43111C73A2D2C3CCB6911BE50DE7DD94'), +('2014_12_10_00_auth.sql', '821703A96D80F9080074852B5A46E2909C9562EA'), +('2014_12_19_00_auth.sql', '44D8E12FFF327AD07878FBDF8D9C16B6B7DCB122'), +('2014_12_20_00_auth.sql', '4DAA02AE285C02AE6C82EA2C8B97AC71990F1085'), +('2014_12_25_00_auth.sql', '61411930F482BC73FC7FD2C370C811E944F5FF92'), +('2014_12_27_00_auth.sql', 'CE2E5D2CD82E79C25294539ADED27A1429105B43'), +('2014_12_28_00_auth.sql', '0A913217610E76AFF119C27259737BBC523090E6'), +('2015_02_22_00_auth.sql', '21CCCF8B01252E16CA3D6C9E3E8DAA4C9B28ED6E'), +('2015_03_01_00_auth.sql', '911881E273207FF6182D1FDAC8C85FFAE8F1C852'), +('2015_03_10_00_auth.sql', '2CC8502C11412EFEB5C11BE166761A8754A59009'), +('2015_03_20_00_auth.sql', 'B761760804EA73BD297F296C5C1919687DF7191C'), +('2015_03_20_01_auth.sql', '5CCEDF20C8189FB1E8DF064A9F0DDC342841FBF0'), +('2015_03_20_02_auth.sql', ''); diff --git a/sql/updates/characters/2015_03_20_00_characters.sql b/sql/updates/characters/2015_03_20_00_characters.sql new file mode 100644 index 00000000000..05c120274da --- /dev/null +++ b/sql/updates/characters/2015_03_20_00_characters.sql @@ -0,0 +1,23 @@ +-- Updates base tables +DROP TABLE IF EXISTS `updates`; +CREATE TABLE `updates` ( + `name` VARCHAR(200) NOT NULL COMMENT 'filename with extension of the update.', + `hash` CHAR(40) NULL DEFAULT '' COMMENT 'sha1 hash of the sql file.', + `state` ENUM('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if an update is released or archived.', + `timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'timestamp when the query was applied.', + `speed` INT(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'time the query takes to apply in ms.', + PRIMARY KEY (`name`) +) +COMMENT='List of all applied updates in this database.' +COLLATE='utf8_general_ci' +ENGINE=MyISAM; + +DROP TABLE IF EXISTS `updates_include`; +CREATE TABLE `updates_include` ( + `path` VARCHAR(200) NOT NULL COMMENT 'directory to include. $ means relative to the source directory.', + `state` ENUM('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if the directory contains released or archived updates.', + PRIMARY KEY (`path`) +) +COMMENT='List of directories where we want to include sql updates.' +COLLATE='utf8_general_ci' +ENGINE=MyISAM; diff --git a/sql/updates/characters/2015_03_20_01_characters.sql b/sql/updates/characters/2015_03_20_01_characters.sql new file mode 100644 index 00000000000..69c8767e239 --- /dev/null +++ b/sql/updates/characters/2015_03_20_01_characters.sql @@ -0,0 +1,6 @@ +-- Characters database update data +TRUNCATE TABLE `updates_include`; +INSERT INTO `updates_include` (`path`, `state`) VALUES +('$/sql/updates/characters', 'RELEASED'), +('$/sql/custom/characters', 'RELEASED'), +('$/sql/old/6.x/characters', 'ARCHIVED'); diff --git a/sql/updates/characters/2015_03_20_02_characters.sql b/sql/updates/characters/2015_03_20_02_characters.sql new file mode 100644 index 00000000000..32f7ecffb26 --- /dev/null +++ b/sql/updates/characters/2015_03_20_02_characters.sql @@ -0,0 +1,23 @@ +INSERT IGNORE INTO `updates` (`name`, `hash`) VALUES +('2014_10_20_00_characters.sql', 'A5882DA0979CF4DAE33DA011EBAA006C24BE7230'), +('2014_10_23_00_characters.sql', 'E2AC4758133EE19B7F08464A445802154D1261C8'), +('2014_10_23_01_characters.sql', '20029E6323D9773B32C34D84FFED1711CC60F09F'), +('2014_10_23_02_characters.sql', '8A7A16886EE71E7ACDDB3DDA6D0ECAC2FD2FDCA8'), +('2014_10_24_00_characters.sql', 'D008FE81AE844FCA686439D6ECC5108FB0DD1EB9'), +('2014_10_25_00_characters.sql', 'A39C7BE46686B54776BDAB9D7A882D91EDEC51A4'), +('2014_10_26_00_characters.sql', 'C787954CC35FE34B4101FDE6527F14C027F4947C'), +('2014_11_12_00_characters.sql', 'B160BB2313F1BD5F3B076A5A9279DC10D4796E34'), +('2014_12_23_00_characters.sql', '3D9D648B2387B357F4BD090B33F80682F7924882'), +('2014_12_28_00_characters.sql', '5362922FF4483A336311D73082A5727309CD9219'), +('2014_12_31_00_characters.sql', '498DDF2DD936CF156D74A8208DC93DCE9FCAB5AA'), +('2015_01_02_00_characters.sql', 'E5940BE836F253982E07930120422E598D08BDE1'), +('2015_01_10_00_characters.sql', '30796056C8623699B2FE1BF626A19D38262E9284'), +('2015_01_16_00_characters.sql', '96642760A54C8D799AAFE438049A63AA521656F2'), +('2015_01_27_00_characters.sql', 'EB710E3EB9F2CAFD84AB62CDC84E898403A80A4F'), +('2015_02_13_00_characters.sql', '405BEB4ED207DC6076442A37EE2AFB1F21E274A0'), +('2015_02_13_01_characters.sql', '35F582D4F33BF55D1685A1BA89273ED895FD09C5'), +('2015_02_17_00_characters.sql', '8D21FC5A55BF8B55D6DCDCE5F02CF2B640230E94'), +('2015_03_10_00_characters.sql', 'E565B89B145C340067742DFF2DEF1B74F5F1BD4E'), +('2015_03_20_00_characters.sql', 'B761760804EA73BD297F296C5C1919687DF7191C'), +('2015_03_20_01_characters.sql', '20BD68468C57FCF7E665B4DA185DCD52FACE8B3F'), +('2015_03_20_02_characters.sql', ''); diff --git a/sql/updates/hotfixes/2015_03_20_00_hotfixes.sql b/sql/updates/hotfixes/2015_03_20_00_hotfixes.sql new file mode 100644 index 00000000000..05c120274da --- /dev/null +++ b/sql/updates/hotfixes/2015_03_20_00_hotfixes.sql @@ -0,0 +1,23 @@ +-- Updates base tables +DROP TABLE IF EXISTS `updates`; +CREATE TABLE `updates` ( + `name` VARCHAR(200) NOT NULL COMMENT 'filename with extension of the update.', + `hash` CHAR(40) NULL DEFAULT '' COMMENT 'sha1 hash of the sql file.', + `state` ENUM('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if an update is released or archived.', + `timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'timestamp when the query was applied.', + `speed` INT(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'time the query takes to apply in ms.', + PRIMARY KEY (`name`) +) +COMMENT='List of all applied updates in this database.' +COLLATE='utf8_general_ci' +ENGINE=MyISAM; + +DROP TABLE IF EXISTS `updates_include`; +CREATE TABLE `updates_include` ( + `path` VARCHAR(200) NOT NULL COMMENT 'directory to include. $ means relative to the source directory.', + `state` ENUM('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if the directory contains released or archived updates.', + PRIMARY KEY (`path`) +) +COMMENT='List of directories where we want to include sql updates.' +COLLATE='utf8_general_ci' +ENGINE=MyISAM; diff --git a/sql/updates/hotfixes/2015_03_20_01_hotfixes.sql b/sql/updates/hotfixes/2015_03_20_01_hotfixes.sql new file mode 100644 index 00000000000..a56bf038472 --- /dev/null +++ b/sql/updates/hotfixes/2015_03_20_01_hotfixes.sql @@ -0,0 +1,6 @@ +-- Hotfixes database update data +TRUNCATE TABLE `updates_include`; +INSERT INTO `updates_include` (`path`, `state`) VALUES +('$/sql/updates/hotfixes', 'RELEASED'), +('$/sql/custom/hotfixes', 'RELEASED'), +('$/sql/old/6.x/hotfixes', 'ARCHIVED'); diff --git a/sql/updates/hotfixes/2015_03_20_02_hotfixes.sql b/sql/updates/hotfixes/2015_03_20_02_hotfixes.sql new file mode 100644 index 00000000000..87b5da36aec --- /dev/null +++ b/sql/updates/hotfixes/2015_03_20_02_hotfixes.sql @@ -0,0 +1,18 @@ +INSERT IGNORE INTO `updates` (`name`, `hash`) VALUES +('2014_10_19_01_hotfixes_area_poi.sql', 'BEE7AD2717D833074AAB0B7E50D17312D0018DEC'), +('2014_10_19_02_hotfixes_area_poi_state.sql', 'D70F413FF0EFFAFACF3B8A9B26D118F3D107E097'), +('2014_10_19_03_hotfixes_creature_difficulty.sql', 'F9FD065AC1A409580AE6E3C01BF8F74E45D31205'), +('2014_10_19_04_hotfixes_creature.sql', '0A7FD859535F648633449E5351F00257AE202838'), +('2014_10_19_05_hotfixes_broadcast_text.sql', '0A82925C0B0BC6BB3A4E2F7DDB40A410C24FFE15'), +('2014_10_19_06_hotfixes_broadcast_text.sql', '29982469F34CB06B6F413009DD761F361E56B3A1'), +('2014_10_20_00_hotfixes_gameobjects.sql', 'C9DCBE4A88074273CBB64FE568DEFCD2EF27DB8A'), +('2014_10_24_00_hotfixes_taxi_path_node.sql', 'F038CFD6E79649B6F7734F070BF2466505847E94'), +('2014_10_24_01_hotfixes_broadcast_text.sql', 'B1CA1B188092B17418D759903E066E0E6FA27420'), +('2014_12_25_00_hotfixes_locale_broadcast_text.sql', '7F5C494F33B216EBAD6A6C065A923CC71234A599'), +('2014_12_26_00_hotfixes_hotfix_data.sql', 'ACED65D62DDD9D56E182C6FD6E8001A2AD605118'), +('2015_02_22_00_hotfixes.sql', 'E15FB22A995AB26A0A0BC61EDE3D0258C394F8B3'), +('2015_03_04_00_hotfixes.sql', '0DC68F95CE1E6E808B9B2751617384CFCFD727D6'), +('2015_03_08_00_hotfixes.sql', '8287470D148051AFBCC7EECEAACBE87ABC65A09C'), +('2015_03_20_00_hotfixes.sql', 'B761760804EA73BD297F296C5C1919687DF7191C'), +('2015_03_20_01_hotfixes.sql', 'A79521F16AE82F0D7487495D0BF7A726D81F250D'), +('2015_03_20_02_hotfixes.sql', ''); diff --git a/sql/updates/world/2015_03_20_04_world.sql b/sql/updates/world/2015_03_20_04_world.sql new file mode 100644 index 00000000000..05c120274da --- /dev/null +++ b/sql/updates/world/2015_03_20_04_world.sql @@ -0,0 +1,23 @@ +-- Updates base tables +DROP TABLE IF EXISTS `updates`; +CREATE TABLE `updates` ( + `name` VARCHAR(200) NOT NULL COMMENT 'filename with extension of the update.', + `hash` CHAR(40) NULL DEFAULT '' COMMENT 'sha1 hash of the sql file.', + `state` ENUM('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if an update is released or archived.', + `timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'timestamp when the query was applied.', + `speed` INT(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'time the query takes to apply in ms.', + PRIMARY KEY (`name`) +) +COMMENT='List of all applied updates in this database.' +COLLATE='utf8_general_ci' +ENGINE=MyISAM; + +DROP TABLE IF EXISTS `updates_include`; +CREATE TABLE `updates_include` ( + `path` VARCHAR(200) NOT NULL COMMENT 'directory to include. $ means relative to the source directory.', + `state` ENUM('RELEASED','ARCHIVED') NOT NULL DEFAULT 'RELEASED' COMMENT 'defines if the directory contains released or archived updates.', + PRIMARY KEY (`path`) +) +COMMENT='List of directories where we want to include sql updates.' +COLLATE='utf8_general_ci' +ENGINE=MyISAM; diff --git a/sql/updates/world/2015_03_20_05_world.sql b/sql/updates/world/2015_03_20_05_world.sql new file mode 100644 index 00000000000..018e1929c34 --- /dev/null +++ b/sql/updates/world/2015_03_20_05_world.sql @@ -0,0 +1,6 @@ +-- World database update data +TRUNCATE TABLE `updates_include`; +INSERT INTO `updates_include` (`path`, `state`) VALUES +('$/sql/updates/world', 'RELEASED'), +('$/sql/custom/world', 'RELEASED'), +('$/sql/old/6.x/world', 'ARCHIVED'); diff --git a/sql/updates/world/2015_03_20_06_world.sql b/sql/updates/world/2015_03_20_06_world.sql new file mode 100644 index 00000000000..692381573eb --- /dev/null +++ b/sql/updates/world/2015_03_20_06_world.sql @@ -0,0 +1,170 @@ +INSERT IGNORE INTO `updates` (`name`, `hash`, `state`) VALUES +('2014_10_19_00_world.sql', 'C9D12A22A30EAA0E602D5DEF7E72BF2F18BC8546', 'ARCHIVED'), +('2014_10_19_01_world.sql', '140B2E47A3B997C03CE00B29E963900643FFB820', 'ARCHIVED'), +('2014_10_19_01_world_from_335.sql', '76D19F7888A41B1B4AB4A5F366AE98057F066128', 'ARCHIVED'), +('2014_10_19_02_world.sql', '58AB6AAAFC6FED71B66DF6A8DF279DB195BD0E2F', 'ARCHIVED'), +('2014_10_20_00_world.sql', 'BD3D440770748809709C002C3DD4FFD7399E045A', 'ARCHIVED'), +('2014_10_20_00_world_from_335.sql', 'E74390D42EF46218FE189C22A2A68BC454293F30', 'ARCHIVED'), +('2014_10_21_00_world.sql', '0E29A91E897F5EF08BFD09893475B483084F9BB9', 'ARCHIVED'), +('2014_10_22_00_world.sql', '73246FCC28EFA348C2345EDB092053A3D4AE2ECF', 'ARCHIVED'), +('2014_10_22_00_world_from_335.sql', '5C5268C959A22284F6E9E05D873EA153BFBBD835', 'ARCHIVED'), +('2014_10_22_01_world.sql', 'A93FE6F9BDA6D8DDD06303B1CF2D546ABAC31B00', 'ARCHIVED'), +('2014_10_23_00_world.sql', 'C4CE350F917717F646C074294DC21DFD4A531358', 'ARCHIVED'), +('2014_10_23_01_world.sql', 'A1B8C1E18FD43AE8D1A9A0E00C91804DA5391F33', 'ARCHIVED'), +('2014_10_24_01_world_from_335.sql', '5A6EFA81F56575F85B27709944371C3E0A75D5D6', 'ARCHIVED'), +('2014_10_24_02_world.sql', '7AADECF3AB832E8E7662917E5E42E8ED0B911EF9', 'ARCHIVED'), +('2014_10_24_03_world.sql', '1A3BE9C3443254E8040700014CD0553C60079C3E', 'ARCHIVED'), +('2014_10_24_04_world.sql', '31D594C935B0BDCD85381FCE710A08724C367988', 'ARCHIVED'), +('2014_10_25_00_world.sql', '9F251D021F9F15F33D60998C50779BE25566B7DF', 'ARCHIVED'), +('2014_10_26_00_world.sql', '171319C2ACDB3DB8B93C34C8FD8AF8741CA5FBCB', 'ARCHIVED'), +('2014_10_26_01_world.sql', 'E10E2EB04D4B2C332BB5EFEFE04F54FA3471B699', 'ARCHIVED'), +('2014_10_26_02_world.sql', '61DD9CCFBE84A87433EDBACF9657C9222D5DEC21', 'ARCHIVED'), +('2014_10_26_03_world.sql', '6CD3E46FB34BB74D563E98A8F0E6C3D158651CF5', 'ARCHIVED'), +('2014_10_26_04_world.sql', '664B0B4EC3338289B6CA60EEE999D8363D4E4A58', 'ARCHIVED'), +('2014_10_26_05_world.sql', '769D4D8E652A7E30B819633AAD01154BCDA73A63', 'ARCHIVED'), +('2014_10_26_06_world_from_335.sql', 'FA22609D1B1D0B56760595FEA7445B0724A44EE6', 'ARCHIVED'), +('2014_10_27_00_world.sql', '431C68103E11C4A7579EF62DC4CD27D254C4E47A', 'ARCHIVED'), +('2014_10_27_01_world.sql', '735AD9C0307926D7CF6AC6845FF27B67650CD935', 'ARCHIVED'), +('2014_10_27_02_world.sql', '3DAEB7EC510D924B37BFAC7D8CA06B8E38D60FEA', 'ARCHIVED'), +('2014_10_28_00_world.sql', 'C59E8BCC1A58FB150B08A6D2F4003E5EC151E696', 'ARCHIVED'), +('2014_10_29_00_world.sql', 'E7A909C7DC8B50DCFC2E737909540041A89AEE11', 'ARCHIVED'), +('2014_10_29_01_world.sql', 'F478D2AE25B9C36E3456DD35884357063556AA36', 'ARCHIVED'), +('2014_10_30_00_world.sql', '46D284FE1E2847CE99FE707ECC0BDAB4C9F7EE06', 'ARCHIVED'), +('2014_10_30_01_world.sql', 'B1C5B27B6D4984F7BBB40388E92DD46FB5E8BFF0', 'ARCHIVED'), +('2014_10_30_02_world.sql', '6F0FFB389D698B8AFFA723EF55895C6CF2CBF7D3', 'ARCHIVED'), +('2014_10_31_00_world.sql', '6406626D2883AEF64DEA38E2D88A71A46915B5B6', 'ARCHIVED'), +('2014_10_31_01_world.sql', 'D397CEFFE883BB910FEDCE5EA5EDFB537FB2370A', 'ARCHIVED'), +('2014_10_31_02_world.sql', '215FB85430078FE0AFB771F34B5CEC85D6D4C22A', 'ARCHIVED'), +('2014_10_31_03_world.sql', 'A9BE071C624ABF152BAE5A97452CC505CE100D98', 'ARCHIVED'), +('2014_11_01_00_world.sql', 'D05FB5907D59AE2520A8658064A1DFC3D256256C', 'ARCHIVED'), +('2014_11_02_00_world.sql', 'AC4CBDC7BB6A51927841EF2BD98045CCD56C6AED', 'ARCHIVED'), +('2014_11_02_01_world.sql', '48DC7D245D7A7019B3333BA8F598AB566A321EE4', 'ARCHIVED'), +('2014_11_02_02_world.sql', '856AE4A3990B38A68155845C6D68F28F4B075C41', 'ARCHIVED'), +('2014_11_04_00_world.sql', '517BE655C4F39EAAA3025F843B29A0F276559FEF', 'ARCHIVED'), +('2014_11_07_00_world.sql', '16A0E153EDE2AB8C63A3BA6656AD71BB237FBCF3', 'ARCHIVED'), +('2014_11_07_01_world.sql', '5DCE2E3A55185587AD2DF83D5FB146C7A7D794A3', 'ARCHIVED'), +('2014_11_08_00_world.sql', 'B3C5B811A1C4805EDE7D11740187048A79A2369A', 'ARCHIVED'), +('2014_11_08_01_world.sql', '0C1F022696DF96302AB62B4A215FC37FAD66FA35', 'ARCHIVED'), +('2014_11_08_02_world.sql', '136936E2E16955DCD4B0EEA34AA3D22B6852A031', 'ARCHIVED'), +('2014_11_10_00_world.sql', '13B0D432ABC18E32531C1C97ECC51AA45EC506C7', 'ARCHIVED'), +('2014_11_10_01_world.sql', 'B9FFFED95D327392EA5CB264F6712BAC766C84BD', 'ARCHIVED'), +('2014_11_10_02_world.sql', 'A8830AD02DD7DF119721A979E165ED3259ED420B', 'ARCHIVED'), +('2014_11_10_03_world.sql', '8734F326B496D24871E16809D167F055B10D6F93', 'ARCHIVED'), +('2014_11_10_04_world.sql', 'F22AB772400FB35B1BFF6F58534CA681BF769281', 'ARCHIVED'), +('2014_11_10_05_world.sql', '4DC43402104F8296FA992C40916036B76F35560C', 'ARCHIVED'), +('2014_11_16_00_world.sql', 'BEBE47FC0D0E499FB6DBED310985BD9516F2935B', 'ARCHIVED'), +('2014_11_16_01_world.sql', 'C036EC4786AF8D5E01F6A681B3B9F1953FE0F5B0', 'ARCHIVED'), +('2014_11_16_02_world.sql', '4F16F69F0AAAA23C0254D4B89CA3AC3FDEC6DA03', 'ARCHIVED'), +('2014_11_16_03_world.sql', '178BA69418C7784475F36518CEE6D3C0233A3A07', 'ARCHIVED'), +('2014_11_16_04_world.sql', '0F14EE0A04BB2C3E393265082C2B7600236B2F14', 'ARCHIVED'), +('2014_11_16_05_world.sql', 'F6F0D8A12F64CAE47530F77E53B31FE9BA685CB3', 'ARCHIVED'), +('2014_11_16_06_world.sql', 'FF7C64269FD4C26EF6FB79D1EE5774E13C3C20D1', 'ARCHIVED'), +('2014_11_19_00_world.sql', '6E1D3D0451297EAE3A85903D4901E824BB4B5E50', 'ARCHIVED'), +('2014_11_19_01_world.sql', '2E545A1875301B2622B59BEF0473E90BA56EC4FD', 'ARCHIVED'), +('2014_11_20_00_world.sql', '2C0E3B63F1572F584C8E0B134FA925814ACDFE95', 'ARCHIVED'), +('2014_11_20_01_world.sql', '2FC08035F0F09783E228788781D5D492452803F7', 'ARCHIVED'), +('2014_11_20_02_world.sql', 'BF817119E9F568CDD5BEA712FA5DAABE008DA9F7', 'ARCHIVED'), +('2014_11_30_00_world.sql', 'F70897BD3E34C87320A2E3E6C72C66C6877A13FB', 'ARCHIVED'), +('2014_12_01_00_world.sql', 'B370BBB22E09C233ABB2CB3999E2BDD9A49A35A1', 'ARCHIVED'), +('2014_12_04_00_world.sql', 'C22F9C77CEF8805FFCB950BB7038D1EF12D49731', 'ARCHIVED'), +('2014_12_04_01_world.sql', 'D8353D92E679FABEE7B1F978B5394F5A18F7D40F', 'ARCHIVED'), +('2014_12_12_00_world.sql', '3E31732550055B7EB72443C30EA2ED975862215D', 'ARCHIVED'), +('2014_12_12_01_world.sql', 'D52B5EF4374EE67FE77D3C1AF004E42E1425DB10', 'ARCHIVED'), +('2014_12_12_02_world.sql', 'F0E9DDCF540B58123811993D09F61A2EFA34BC8D', 'ARCHIVED'), +('2014_12_12_03_world.sql', 'BFB07C36367BD9A198BB9CC34103EC0C401A09E8', 'ARCHIVED'), +('2014_12_13_00_world.sql', '394CF64309B1BACD7BDF1A6BF7D88DE2A335FFEE', 'ARCHIVED'), +('2014_12_15_00_world.sql', '88FF35DC8B665070E96249CA01AA079DBE995BBB', 'ARCHIVED'), +('2014_12_17_00_world.sql', '545A3022BB1D85E8FCF9BC1086D5C3864BF1F0CA', 'ARCHIVED'), +('2014_12_19_00_world.sql', 'AF594EB0D80B3DEC01686597DF369BC34D7398E8', 'ARCHIVED'), +('2014_12_19_01_world.sql', '557FF34D129C6758A1CE66AAD7A1A3516631D36D', 'ARCHIVED'), +('2014_12_21_00_world.sql', '4F07D137F7628A7DABED5FDD8EDB1B1A83086C0B', 'ARCHIVED'), +('2014_12_24_00_world.sql', 'BCD9B5C90A35CA1BA9ACCC31B053DCFDD8B714B0', 'ARCHIVED'), +('2014_12_25_00_world.sql', '925F10E1D8D69502293D2EEDE2DFC3D448D23724', 'ARCHIVED'), +('2014_12_25_01_world.sql', 'E4BB18FEC17307D04EA1E314DD36D770242C049B', 'ARCHIVED'), +('2014_12_26_00_world.sql', '0829D8347CB6BFFE08E0F5DF82F46CA071566E50', 'ARCHIVED'), +('2014_12_26_01_world.sql', 'B5FDA0031AFCB729C6079FB7D9DE81E8768A8F14', 'ARCHIVED'), +('2014_12_26_02_world.sql', 'BDC397D2FCB3E737F6520ACEDB6836C88E0B84A5', 'ARCHIVED'), +('2014_12_26_03_world.sql', '89E0C5196DA72793FFA26F259BD602066CBBC31E', 'ARCHIVED'), +('2014_12_26_04_world.sql', '58564849E75F397C8E1C744692191ADE39DFA514', 'ARCHIVED'), +('2014_12_26_05_world.sql', 'D370DC75186601FCBABB63845922B294099DA13B', 'ARCHIVED'), +('2014_12_26_06_world.sql', 'BE8F3B85AB5F89EF081B984A2E4B66B3D88BB9E9', 'ARCHIVED'), +('2014_12_26_07_world.sql', '69792C539312FB965DEA2206D129314E6B411445', 'ARCHIVED'), +('2014_12_27_00_world.sql', 'C58A8454E3D39A2021C8D82BCCB621EE992E0ACF', 'ARCHIVED'), +('2014_12_27_01_world.sql', '841BF49D1D54E7C8BBD3AAD8E233E0A592AF903E', 'ARCHIVED'), +('2014_12_27_02_world.sql', '9440E74C6E2D07B50F747895E285C5AA3D6CE3D3', 'ARCHIVED'), +('2014_12_27_03_world.sql', '4BB55FF64EDD594B0062E7056666D1E1B5A559B9', 'ARCHIVED'), +('2014_12_27_04_world.sql', '7C8BFB2FE5F58288E98C6395B1D7952BA0D923A0', 'ARCHIVED'), +('2014_12_27_05_world.sql', '7FC53862CD96381DE5C15C404FE25935E1AC603D', 'ARCHIVED'), +('2014_12_27_06_world.sql', 'EDB26E7292183B8867BD3D22941B3A21B350A18C', 'ARCHIVED'), +('2014_12_27_07_world.sql', 'B9455E80DEF0ADADE466632AC6206F43B8CF98EE', 'ARCHIVED'), +('2014_12_27_08_world.sql', '135C58B097B834FF4D195C9B13E9C462E5A12070', 'ARCHIVED'), +('2014_12_28_00_world.sql', '855E107ADD7D3078B2ED37D77BE8CDCD2E76D9E5', 'ARCHIVED'), +('2014_12_28_01_world.sql', '46ED66ED9F997555CFFF0ABF48712D4B54A015AF', 'ARCHIVED'), +('2014_12_28_02_world.sql', '8DE39EDA6246CF885B04BBE3C403A984A7947EB7', 'ARCHIVED'), +('2014_12_28_03_world.sql', '53E8B3A24AEB4467C5765FFF2B99CB646CC77319', 'ARCHIVED'), +('2014_12_28_04_world.sql', '67B7936CA2DB03E64380E61C520FE808EC900687', 'ARCHIVED'), +('2014_12_28_05_world.sql', '28542CF3F4EFCAF60E96B61740A7755CE4189FD9', 'ARCHIVED'), +('2014_12_28_06_world.sql', '277DFC82FE17489C519001A778ABE17F0FBCC605', 'ARCHIVED'), +('2014_12_28_07_world.sql', '717CF0E7F4795A972096EDFECCAAB561FBD8E987', 'ARCHIVED'), +('2014_12_29_00_world.sql', 'EF70B832664A0822CEA30EF51B4BEEDF185EC53D', 'ARCHIVED'), +('2014_12_30_00_world.sql', '468E05F2FB5B73647F77DDF375C1D10B5B5F35B1', 'ARCHIVED'), +('2015_01_10_00_world.sql', '9F93ABE80EBAA370971F61C094713CC73448DD74', 'ARCHIVED'), +('2015_01_10_01_world.sql', 'EDDA230907DE93B2E23171DBE757A8831F3EF0B3', 'ARCHIVED'), +('2015_01_10_02_world.sql', 'C6CC35B2021CA60C0BF43D3C88FCD323FF0D39F8', 'ARCHIVED'), +('2015_01_10_03_world.sql', '135690CAC7B6F786F00EBB8F5B385B815CFE9BFD', 'ARCHIVED'), +('2015_01_10_04_world.sql', 'F6098B3B1E2ED9484A15FE27E5ABE4960EFA3A28', 'ARCHIVED'), +('2015_01_10_05_world.sql', '9ADBEE777B28618822269D5D5923056D86194867', 'ARCHIVED'), +('2015_01_10_06_world.sql', 'D3CB658D8C880BF5988E31D2789DC1188AF12244', 'ARCHIVED'), +('2015_01_10_07_world.sql', '11FC9708637F44455A1EEB2D920652C11AF73204', 'ARCHIVED'), +('2015_01_11_01_world.sql', '880F9053836285B014E4F85787BB17B035ACA2BD', 'ARCHIVED'), +('2015_01_11_02_world.sql', '652501E5CC18ABAD377AF825667ACC91D07EA9AB', 'ARCHIVED'), +('2015_01_11_03_world.sql', '1D3AB865CC7C6241E43053B85B7289100F112A1E', 'ARCHIVED'), +('2015_01_12_00_world.sql', '6D97DF64ED2BA6668E1BBD20869B5D00A83AB6DC', 'ARCHIVED'), +('2015_01_15_00_world.sql', '9E1CB22E3F128A6597842DCA85E4A08C8E6A3B00', 'ARCHIVED'), +('2015_01_16_00_world.sql', '81959173F25898F3EDFC94A9BD40800B7459434D', 'ARCHIVED'), +('2015_01_18_00_world.sql', '7CA65728C59A00BECFAFC5585A79ED4B4AF5FAA3', 'ARCHIVED'), +('2015_01_30_00_world.sql', '0200615B833CB70E82C9B6D50BA6ED6F37C5A046', 'ARCHIVED'), +('2015_01_30_01_world.sql', '56DC1B47EE659D5B2C0740A3710B6BA9168C0A8D', 'ARCHIVED'), +('2015_02_02_00_world.sql', '3210E3CD12FCEE5E505D293113A0B77071FAA41B', 'ARCHIVED'), +('2015_02_02_00_world_from_335.sql', '4A7F644212D0BC1D8B4BDC7E27BA70BBBCF5C1A8', 'ARCHIVED'), +('2015_02_02_01_world.sql', '56FFF84EC62A9A8647C94B535EB6A0A2BAA4EECA', 'ARCHIVED'), +('2015_02_06_00_world.sql', '8D965E6D688C50DEB197E4B5B6D3F911264FF00B', 'ARCHIVED'), +('2015_02_08_00_world.sql', 'B64B75BC708A959CB370557949671CB75BBB87D9', 'ARCHIVED'), +('2015_02_11_00_world.sql', '50B5E9DAFC4BF3260DF78DA4D9A874728C11D589', 'ARCHIVED'), +('2015_02_12_00_world.sql', 'AA1E0BFE3C23ABAECE17E151EE9F74C86FDB32C2', 'ARCHIVED'), +('2015_02_13_00_world.sql', '4A552FFBB0218FB2E7E54429DD27F9F6B3C71DBA', 'ARCHIVED'), +('2015_02_18_00_world.sql', '9224197FD3427974D942FEBCCEDE7ABD40300E23', 'ARCHIVED'), +('2015_02_19_00_world.sql', '4E9ED1DC0DF1FD173CD15FA35A79353E08455A30', 'ARCHIVED'), +('2015_02_20_00_world.sql', '52BA5B5A6F386B852E1A115F2C39B66108314A5F', 'ARCHIVED'), +('2015_02_20_01_world.sql', '1C0C6A74212690BB07BA50524A8BB54D3AEC7708', 'ARCHIVED'), +('2015_02_20_02_world.sql', '77DE8E0108E079741E0C3CED01AB4FD60260C57A', 'ARCHIVED'), +('2015_02_22_00_world.sql', '8CC806EC21F9F194CE06DC80F0C8F5A4509EFBDA', 'ARCHIVED'), +('2015_02_22_01_world.sql', 'A2AD10247D226951FEE769F3872194F0E1D9C44A', 'ARCHIVED'), +('2015_03_07_00_world.sql', '9DA807070CA63F4342884DF65C7FE409EEEBAE49', 'ARCHIVED'), +('2015_03_07_01_world.sql', '60835178B525B1E2A842A7AB660AD7B6F0832063', 'ARCHIVED'), +('2015_03_07_02_world.sql', '3FBA2EDD2A3641A697CA71D0E0C5E716A057C13E', 'ARCHIVED'), +('2015_03_07_03_world.sql', '560D71607A4E444B5C51D7E2B333D2064AD55D75', 'ARCHIVED'), +('2015_03_10_00_world.sql', 'E9B5D25DF80B70998336A580E419AF3E78266597', 'ARCHIVED'), +('2015_03_16_00_world.sql', 'E386644A485C16DDA4EE83415808BB6C77DC1E87', 'ARCHIVED'), +('2015_03_16_01_world.sql', 'D8018D2645F6A21308F7AB2EA12F09474B5BFF46', 'ARCHIVED'), +('2015_03_16_02_world.sql', '68914E093312389F0AADEDFEF0BD190117965AC4', 'ARCHIVED'), +('2015_03_16_03_world.sql', '673267031A5450A7C010B28D99E4CCC3A90B778D', 'ARCHIVED'), +('2015_03_16_04_world.sql', '74275F00F6C5168870F7A01CEF19DD3D06572734', 'ARCHIVED'), +('2015_03_16_05_world.sql', '6E44CFA09EF45C7FA2D63F0679F2B216B620D7C7', 'ARCHIVED'), +('2015_03_16_06_world.sql', '44C2A4C393AB3E5401FBD122784E6E56B28942B6', 'ARCHIVED'), +('2015_03_16_07_world.sql', '83D3171C249FA95CB2576EABE7EB469F34DEAB2D', 'ARCHIVED'), +('2015_03_16_08_world.sql', '96C9E201D6F5F896C96A06E94228F1067C19D7CE', 'ARCHIVED'), +('2015_03_16_09_world.sql', 'AE99495134C2AA1762047853A48193E1E2B7E240', 'ARCHIVED'), +('2015_03_16_10_world.sql', '6166BEE0E14FE9F15777F041747230AF546ED99E', 'ARCHIVED'), +('2015_03_17_00_world.sql', 'F71FE9758B3AFFD80E391209A743D43B04E6F93A', 'ARCHIVED'), +('2015_03_17_02_world.sql', '6212A1CF186600907CBAE1000B9D6AF2026B6E7D', 'ARCHIVED'), +('2015_03_18_00_world.sql', '1103C059C8FE207DAC6F3E1D629852968EB6F917', 'ARCHIVED'), +('2015_03_18_01_world.sql', '3BC3E66ECFABCCDCFF43ABAFBE4381AD0ED4228A', 'ARCHIVED'), +('2015_03_19_00_world.sql', '45B0A3D93365CE324AD25C72554B13AE47356F43', 'ARCHIVED'), +('2015_03_20_00_world.sql', '8E7C56D7C5F6FC85C291BEEFCEDF036431A399E9', 'ARCHIVED'), +('2015_03_20_01_world.sql', '618093A729BC0FE4FC141AF79F702C28D370E70B', 'ARCHIVED'), +('2015_03_20_02_world.sql', 'A0FF748366FEA70998B6F9639355C67EBCA95572', 'ARCHIVED'), +('2015_03_20_03_world.sql', '062DA1A1DE0186948FD9A8958BD6D7EA8CE5507D', 'ARCHIVED'), +('2015_03_20_04_world.sql', 'B761760804EA73BD297F296C5C1919687DF7191C', 'ARCHIVED'), +('2015_03_20_05_world.sql', '8481BE9B805704C97D2D8D54272F1E443184B3B2', 'ARCHIVED'), +('2015_03_20_06_world.sql', '', 'ARCHIVED'); diff --git a/src/server/bnetserver/CMakeLists.txt b/src/server/bnetserver/CMakeLists.txt index c9f83cc528d..4ea4f697cf7 100644 --- a/src/server/bnetserver/CMakeLists.txt +++ b/src/server/bnetserver/CMakeLists.txt @@ -47,6 +47,7 @@ include_directories( ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/dep/cppformat ${CMAKE_SOURCE_DIR}/dep/zmqpp + ${CMAKE_SOURCE_DIR}/dep/process ${CMAKE_SOURCE_DIR}/src/server/shared ${CMAKE_SOURCE_DIR}/src/server/shared/Configuration ${CMAKE_SOURCE_DIR}/src/server/shared/Database @@ -58,6 +59,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/shared/Networking ${CMAKE_SOURCE_DIR}/src/server/shared/Realm ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Updater ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities ${CMAKE_SOURCE_DIR}/src/server/ipc ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/src/server/bnetserver/Main.cpp b/src/server/bnetserver/Main.cpp index 5f4f63287e5..678e24c4682 100644 --- a/src/server/bnetserver/Main.cpp +++ b/src/server/bnetserver/Main.cpp @@ -36,6 +36,7 @@ #include "SystemConfig.h" #include "Util.h" #include "ZmqContext.h" +#include "DatabaseLoader.h" #include <cstdlib> #include <iostream> #include <boost/date_time/posix_time/posix_time.hpp> @@ -162,32 +163,13 @@ bool StartDB() { MySQL::Library_Init(); - std::string dbstring = sConfigMgr->GetStringDefault("LoginDatabaseInfo", ""); - if (dbstring.empty()) - { - TC_LOG_ERROR("server.bnetserver", "Database not specified"); - return false; - } - - int32 worker_threads = sConfigMgr->GetIntDefault("LoginDatabase.WorkerThreads", 1); - if (worker_threads < 1 || worker_threads > 32) - { - TC_LOG_ERROR("server.bnetserver", "Improper value specified for LoginDatabase.WorkerThreads, defaulting to 1."); - worker_threads = 1; - } + // Load databases + DatabaseLoader loader("server.bnetserver", DatabaseLoader::DATABASE_NONE); + loader + .AddDatabase(LoginDatabase, "Login"); - int32 synch_threads = sConfigMgr->GetIntDefault("LoginDatabase.SynchThreads", 1); - if (synch_threads < 1 || synch_threads > 32) - { - TC_LOG_ERROR("server.bnetserver", "Improper value specified for LoginDatabase.SynchThreads, defaulting to 1."); - synch_threads = 1; - } - - if (!LoginDatabase.Open(dbstring, uint8(worker_threads), uint8(synch_threads))) - { - TC_LOG_ERROR("server.bnetserver", "Cannot connect to database"); + if (!loader.Load()) return false; - } TC_LOG_INFO("server.bnetserver", "Started auth database connection pool."); sLog->SetRealmId(0); // Enables DB appenders when realm is set. diff --git a/src/server/bnetserver/bnetserver.conf.dist b/src/server/bnetserver/bnetserver.conf.dist index 462bb0cd075..804ce51ef2a 100644 --- a/src/server/bnetserver/bnetserver.conf.dist +++ b/src/server/bnetserver/bnetserver.conf.dist @@ -9,6 +9,7 @@ # EXAMPLE CONFIG # AUTH SERVER SETTINGS # MYSQL SETTINGS +# UPDATE SETTINGS # LOGGING SYSTEM SETTINGS # ################################################################################################### @@ -165,6 +166,86 @@ Wrong.Password.Login.Logging = 0 ################################################################################################### ################################################################################################### +# UPDATE SETTINGS +# +# Updates.EnableDatabases +# Description: A mask that describes which databases shall be updated. +# +# Following flags are available +# DATABASE_LOGIN = 1, // Auth database +# +# Default: 0 - (All Disabled) +# 1 - (All Enabled) + +Updates.EnableDatabases = 0 + +# +# Updates.SourcePath +# Description: The path to your TrinityCore source directory. +# If the path is left empty, built-in CMAKE_SOURCE_DIR is used. +# Example: "../TrinityCore" +# Default: "" + +Updates.SourcePath = "" + +# +# Updates.SourcePath +# Description: The path to your mysql cli binary. +# If the path is left empty, built-in path from cmake is used. +# Example: "C:/Program Files/MySQL/MySQL Server 5.6/bin/mysql.exe" +# "mysql.exe" +# "/usr/bin/mysql" +# Default: "" + +Updates.MySqlCLIPath = "" + +# +# Updates.AutoSetup +# Description: Auto populate empty databases. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.AutoSetup = 1 + +# +# Updates.Redundancy +# Description: Perform data redundancy checks through hashing +# to detect changes on sql updates and reapply it. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.Redundancy = 1 + +# +# Updates.ArchivedRedundancy +# Description: Check hashes of archived updates (slows down startup). +# Default: 0 - (Disabled) +# 1 - (Enabled) + +Updates.ArchivedRedundancy = 0 + +# +# Updates.AllowRehash +# Description: Inserts the current file hash in the database if it is left empty. +# Useful if you want to mark a file as applied but you don't know its hash. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.AllowRehash = 1 + +# +# Updates.CleanDeadRef +# Description: Cleans dead/ orphaned references that occure if a update was deleted or renamed and edited. +# Disable this if you want to know if the database is in a possible "dirty state". +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.CleanDeadRef = 1 + +# +################################################################################################### + +################################################################################################### # # LOGGING SYSTEM SETTINGS # @@ -255,6 +336,7 @@ Logger.root=3,Console Bnet Logger.realmlist=3,Console Bnet Logger.session=3,Console Bnet Logger.session.packets=3,Console Bnet +Logger.sql.updates=3,Console Bnet # ################################################################################################### diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt index ab54efab1fd..55792856eb4 100644 --- a/src/server/game/CMakeLists.txt +++ b/src/server/game/CMakeLists.txt @@ -131,6 +131,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/shared/Packets ${CMAKE_SOURCE_DIR}/src/server/shared/Realm ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Updater ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities ${CMAKE_SOURCE_DIR}/src/server/ipc ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt index 13026b56fc2..79d3cea0868 100644 --- a/src/server/scripts/CMakeLists.txt +++ b/src/server/scripts/CMakeLists.txt @@ -64,6 +64,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/shared/Logging ${CMAKE_SOURCE_DIR}/src/server/shared/Packets ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Updater ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities ${CMAKE_SOURCE_DIR}/src/server/ipc ${CMAKE_SOURCE_DIR}/src/server/collision diff --git a/src/server/shared/CMakeLists.txt b/src/server/shared/CMakeLists.txt index b6ac8b03099..657b3fde349 100644 --- a/src/server/shared/CMakeLists.txt +++ b/src/server/shared/CMakeLists.txt @@ -22,6 +22,7 @@ file(GLOB_RECURSE sources_Networking Networking/*.cpp Networking/*.h) file(GLOB_RECURSE sources_Packets Packets/*.cpp Packets/*.h) file(GLOB_RECURSE sources_Realm Realm/*.cpp Realm/*.h) file(GLOB_RECURSE sources_Threading Threading/*.cpp Threading/*.h) +file(GLOB_RECURSE sources_Updater Updater/*.cpp Updater/*.h) file(GLOB_RECURSE sources_Utilities Utilities/*.cpp Utilities/*.h) file(GLOB sources_localdir *.cpp *.h) @@ -53,6 +54,7 @@ set(shared_STAT_SRCS ${sources_Packets} ${sources_Realm} ${sources_Threading} + ${sources_Updater} ${sources_Utilities} ${sources_localdir} ) @@ -63,6 +65,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/dep/SFMT ${CMAKE_SOURCE_DIR}/dep/cppformat ${CMAKE_SOURCE_DIR}/dep/utf8cpp + ${CMAKE_SOURCE_DIR}/dep/process ${CMAKE_SOURCE_DIR}/src/server ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/Configuration @@ -77,6 +80,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/Realm ${CMAKE_CURRENT_SOURCE_DIR}/Threading ${CMAKE_CURRENT_SOURCE_DIR}/Utilities + ${CMAKE_CURRENT_SOURCE_DIR}/Updater ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Object ${MYSQL_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} diff --git a/src/server/shared/Database/DatabaseLoader.cpp b/src/server/shared/Database/DatabaseLoader.cpp new file mode 100644 index 00000000000..25c400fdfa8 --- /dev/null +++ b/src/server/shared/Database/DatabaseLoader.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.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, see <http://www.gnu.org/licenses/>. + */ + +#include "DatabaseLoader.h" +#include "DBUpdater.h" +#include "Config.h" + +#include <mysqld_error.h> + +DatabaseLoader::DatabaseLoader(std::string const& logger, uint32 const defaultUpdateMask) + : _logger(logger), _autoSetup(sConfigMgr->GetBoolDefault("Updates.AutoSetup", true)), + _updateFlags(sConfigMgr->GetIntDefault("Updates.EnableDatabases", defaultUpdateMask)) +{ +} + +template <class T> +DatabaseLoader& DatabaseLoader::AddDatabase(DatabaseWorkerPool<T>& pool, std::string const& name) +{ + bool const updatesEnabledForThis = DBUpdater<T>::IsEnabled(_updateFlags); + + _open.push(std::make_pair([this, name, updatesEnabledForThis, &pool]() -> bool + { + std::string const dbString = sConfigMgr->GetStringDefault(name + "DatabaseInfo", ""); + if (dbString.empty()) + { + TC_LOG_ERROR(_logger.c_str(), "Database %s not specified in configuration file!", name.c_str()); + return false; + } + + uint8 const asyncThreads = uint8(sConfigMgr->GetIntDefault(name + "Database.WorkerThreads", 1)); + if (asyncThreads < 1 || asyncThreads > 32) + { + TC_LOG_ERROR(_logger.c_str(), "%s database: invalid number of worker threads specified. " + "Please pick a value between 1 and 32.", name.c_str()); + return false; + } + + uint8 const synchThreads = uint8(sConfigMgr->GetIntDefault(name + "Database.SynchThreads", 1)); + + pool.SetConnectionInfo(dbString, asyncThreads, synchThreads); + if (uint32 error = pool.Open()) + { + // Database does not exist + if ((error == ER_BAD_DB_ERROR) && updatesEnabledForThis && _autoSetup) + { + // Try to create the database and connect again if auto setup is enabled + if (DBUpdater<T>::Create(pool) && (!pool.Open())) + error = 0; + } + + // If the error wasn't handled quit + if (error) + { + TC_LOG_ERROR("sql.driver", "\nDatabasePool %s NOT opened. There were errors opening the MySQL connections. Check your SQLDriverLogFile " + "for specific errors. Read wiki at http://collab.kpsn.org/display/tc/TrinityCore+Home", name.c_str()); + + return false; + } + } + return true; + }, + [&pool]() + { + pool.Close(); + })); + + // Populate and update only if updates are enabled for this pool + if (updatesEnabledForThis) + { + _populate.push([this, name, &pool]() -> bool + { + if (!DBUpdater<T>::Populate(pool)) + { + TC_LOG_ERROR(_logger.c_str(), "Could not populate the %s database, see log for details.", name.c_str()); + return false; + } + return true; + }); + + _update.push([this, name, &pool]() -> bool + { + if (!DBUpdater<T>::Update(pool)) + { + TC_LOG_ERROR(_logger.c_str(), "Could not update the %s database, see log for details.", name.c_str()); + return false; + } + return true; + }); + } + + _prepare.push([this, name, &pool]() -> bool + { + if (!pool.PrepareStatements()) + { + TC_LOG_ERROR(_logger.c_str(), "Could not prepare statements of the %s database, see log for details.", name.c_str()); + return false; + } + return true; + }); + + return *this; +} + +bool DatabaseLoader::Load() +{ + if (!OpenDatabases()) + return false; + + if (!PopulateDatabases()) + return false; + + if (!UpdateDatabases()) + return false; + + if (!PrepareStatements()) + return false; + + return true; +} + +bool DatabaseLoader::OpenDatabases() +{ + while (!_open.empty()) + { + std::pair<Predicate, std::function<void()>> const load = _open.top(); + if (load.first()) + _close.push(load.second); + else + { + // Close all loaded databases + while (!_close.empty()) + { + _close.top()(); + _close.pop(); + } + return false; + } + + _open.pop(); + } + return true; +} + +// Processes the elements of the given stack until a predicate returned false. +bool DatabaseLoader::Process(std::stack<Predicate>& stack) +{ + while (!stack.empty()) + { + if (!stack.top()()) + return false; + + stack.pop(); + } + return true; +} + +bool DatabaseLoader::PopulateDatabases() +{ + return Process(_populate); +} + +bool DatabaseLoader::UpdateDatabases() +{ + return Process(_update); +} + +bool DatabaseLoader::PrepareStatements() +{ + return Process(_prepare); +} + +template +DatabaseLoader& DatabaseLoader::AddDatabase<LoginDatabaseConnection>(DatabaseWorkerPool<LoginDatabaseConnection>& pool, std::string const& name); +template +DatabaseLoader& DatabaseLoader::AddDatabase<WorldDatabaseConnection>(DatabaseWorkerPool<WorldDatabaseConnection>& pool, std::string const& name); +template +DatabaseLoader& DatabaseLoader::AddDatabase<CharacterDatabaseConnection>(DatabaseWorkerPool<CharacterDatabaseConnection>& pool, std::string const& name); +template +DatabaseLoader& DatabaseLoader::AddDatabase<HotfixDatabaseConnection>(DatabaseWorkerPool<HotfixDatabaseConnection>& pool, std::string const& name); diff --git a/src/server/shared/Database/DatabaseLoader.h b/src/server/shared/Database/DatabaseLoader.h new file mode 100644 index 00000000000..0d31ef1686c --- /dev/null +++ b/src/server/shared/Database/DatabaseLoader.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef DatabaseLoader_h__ +#define DatabaseLoader_h__ + +#include "DatabaseWorkerPool.h" +#include "DatabaseEnv.h" + +#include <stack> +#include <functional> + +// A helper class to initiate all database worker pools, +// handles updating, delays preparing of statements and cleans up on failure. +class DatabaseLoader +{ +public: + DatabaseLoader(std::string const& logger, uint32 const defaultUpdateMask); + + // Register a database to the loader (lazy implemented) + template <class T> + DatabaseLoader& AddDatabase(DatabaseWorkerPool<T>& pool, std::string const& name); + + // Load all databases + bool Load(); + + enum DatabaseTypeFlags + { + DATABASE_NONE = 0, + + DATABASE_LOGIN = 1, + DATABASE_CHARACTER = 2, + DATABASE_WORLD = 4, + DATABASE_HOTFIX = 8, + + DATABASE_MASK_ALL = DATABASE_LOGIN | DATABASE_CHARACTER | DATABASE_WORLD | DATABASE_HOTFIX + }; + +private: + bool OpenDatabases(); + bool PopulateDatabases(); + bool UpdateDatabases(); + bool PrepareStatements(); + + using Predicate = std::function<bool()>; + + static bool Process(std::stack<Predicate>& stack); + + bool const _autoSetup; + uint32 const _updateFlags; + std::string const _logger; + + std::stack<std::pair<Predicate, std::function<void()>>> _open; + std::stack<std::function<void()>> _close; + std::stack<Predicate> _populate, _update, _prepare; +}; + +#endif // DatabaseLoader_h__ diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h index f1c6a7acbf5..fa142c9020c 100644 --- a/src/server/shared/Database/DatabaseWorkerPool.h +++ b/src/server/shared/Database/DatabaseWorkerPool.h @@ -30,6 +30,7 @@ #include "AdhocStatement.h" #include <mysqld_error.h> +#include <memory> #define MIN_MYSQL_SERVER_VERSION 50100u #define MIN_MYSQL_CLIENT_VERSION 50100u @@ -57,9 +58,9 @@ class DatabaseWorkerPool public: /* Activity state */ - DatabaseWorkerPool() : _connectionInfo(NULL) + DatabaseWorkerPool() : _connectionInfo(nullptr), _queue(new ProducerConsumerQueue<SQLOperation*>()), + _async_threads(0), _synch_threads(0) { - _queue = new ProducerConsumerQueue<SQLOperation*>(); memset(_connectionCount, 0, sizeof(_connectionCount)); _connections.resize(IDX_SIZE); @@ -70,31 +71,37 @@ class DatabaseWorkerPool ~DatabaseWorkerPool() { _queue->Cancel(); + } - delete _queue; + void SetConnectionInfo(std::string const& infoString, uint8 const asyncThreads, uint8 const synchThreads) + { + _connectionInfo.reset(new MySQLConnectionInfo(infoString)); - delete _connectionInfo; + _async_threads = asyncThreads; + _synch_threads = synchThreads; } - bool Open(const std::string& infoString, uint8 async_threads, uint8 synch_threads) + uint32 Open() { - _connectionInfo = new MySQLConnectionInfo(infoString); + WPFatal(_connectionInfo.get(), "Connection info was not set!"); TC_LOG_INFO("sql.driver", "Opening DatabasePool '%s'. Asynchronous connections: %u, synchronous connections: %u.", - GetDatabaseName(), async_threads, synch_threads); + GetDatabaseName(), _async_threads, _synch_threads); - bool res = OpenConnections(IDX_ASYNC, async_threads); + uint32 error = OpenConnections(IDX_ASYNC, _async_threads); - if (!res) - return res; + if (error) + return error; - res = OpenConnections(IDX_SYNCH, synch_threads); + error = OpenConnections(IDX_SYNCH, _synch_threads); - if (res) + if (!error) + { TC_LOG_INFO("sql.driver", "DatabasePool '%s' opened successfully. %u total connections running.", GetDatabaseName(), (_connectionCount[IDX_SYNCH] + _connectionCount[IDX_ASYNC])); + } - return res; + return error; } void Close() @@ -120,6 +127,32 @@ class DatabaseWorkerPool TC_LOG_INFO("sql.driver", "All connections on DatabasePool '%s' closed.", GetDatabaseName()); } + //! Prepares all prepared statements + bool PrepareStatements() + { + for (uint8 i = 0; i < IDX_SIZE; ++i) + for (uint32 c = 0; c < _connectionCount[i]; ++c) + { + T* t = _connections[i][c]; + t->LockIfReady(); + if (!t->PrepareStatements()) + { + t->Unlock(); + Close(); + return false; + } + else + t->Unlock(); + } + + return true; + } + + inline MySQLConnectionInfo const* GetConnectionInfo() const + { + return _connectionInfo.get(); + } + /** Delayed one-way statement methods. */ @@ -461,7 +494,7 @@ class DatabaseWorkerPool } private: - bool OpenConnections(InternalIndex type, uint8 numConnections) + uint32 OpenConnections(InternalIndex type, uint8 numConnections) { _connections[type].resize(numConnections); for (uint8 i = 0; i < numConnections; ++i) @@ -469,7 +502,7 @@ class DatabaseWorkerPool T* t; if (type == IDX_ASYNC) - t = new T(_queue, *_connectionInfo); + t = new T(_queue.get(), *_connectionInfo); else if (type == IDX_SYNCH) t = new T(*_connectionInfo); else @@ -478,35 +511,32 @@ class DatabaseWorkerPool _connections[type][i] = t; ++_connectionCount[type]; - bool res = t->Open(); + uint32 error = t->Open(); - if (res) + if (!error) { if (mysql_get_server_version(t->GetHandle()) < MIN_MYSQL_SERVER_VERSION) { TC_LOG_ERROR("sql.driver", "TrinityCore does not support MySQL versions below 5.1"); - res = false; + error = 1; } } // Failed to open a connection or invalid version, abort and cleanup - if (!res) + if (error) { - TC_LOG_ERROR("sql.driver", "DatabasePool %s NOT opened. There were errors opening the MySQL connections. Check your SQLDriverLogFile " - "for specific errors. Read wiki at http://collab.kpsn.org/display/tc/TrinityCore+Home", GetDatabaseName()); - while (_connectionCount[type] != 0) { T* t = _connections[type][i--]; delete t; --_connectionCount[type]; } - - return false; + return error; } } - return true; + // Everything is fine + return 0; } unsigned long EscapeString(char *to, const char *from, unsigned long length) @@ -546,10 +576,13 @@ class DatabaseWorkerPool return _connectionInfo->database.c_str(); } - ProducerConsumerQueue<SQLOperation*>* _queue; //! Queue shared by async worker threads. - std::vector< std::vector<T*> > _connections; - uint32 _connectionCount[2]; //! Counter of MySQL connections; - MySQLConnectionInfo* _connectionInfo; + //! Queue shared by async worker threads. + std::unique_ptr<ProducerConsumerQueue<SQLOperation*>> _queue; + std::vector<std::vector<T*>> _connections; + //! Counter of MySQL connections; + uint32 _connectionCount[IDX_SIZE]; + std::unique_ptr<MySQLConnectionInfo> _connectionInfo; + uint8 _async_threads, _synch_threads; }; #endif diff --git a/src/server/shared/Database/MySQLConnection.cpp b/src/server/shared/Database/MySQLConnection.cpp index 1a9f973d47b..1fa3f01a5e1 100644 --- a/src/server/shared/Database/MySQLConnection.cpp +++ b/src/server/shared/Database/MySQLConnection.cpp @@ -72,7 +72,7 @@ void MySQLConnection::Close() delete this; } -bool MySQLConnection::Open() +uint32 MySQLConnection::Open() { MYSQL *mysqlInit; mysqlInit = mysql_init(NULL); @@ -137,13 +137,13 @@ bool MySQLConnection::Open() // set connection properties to UTF8 to properly handle locales for different // server configs - core sends data in UTF8, so MySQL must expect UTF8 too mysql_set_character_set(m_Mysql, "utf8"); - return PrepareStatements(); + return 0; } else { - TC_LOG_ERROR("sql.sql", "Could not connect to MySQL database at %s: %s\n", m_connectionInfo.host.c_str(), mysql_error(mysqlInit)); + TC_LOG_ERROR("sql.sql", "Could not connect to MySQL database at %s: %s", m_connectionInfo.host.c_str(), mysql_error(mysqlInit)); mysql_close(mysqlInit); - return false; + return mysql_errno(mysqlInit); } } diff --git a/src/server/shared/Database/MySQLConnection.h b/src/server/shared/Database/MySQLConnection.h index d486f5b4679..78d8d2fb5dd 100644 --- a/src/server/shared/Database/MySQLConnection.h +++ b/src/server/shared/Database/MySQLConnection.h @@ -72,9 +72,11 @@ class MySQLConnection MySQLConnection(ProducerConsumerQueue<SQLOperation*>* queue, MySQLConnectionInfo& connInfo); //! Constructor for asynchronous connections. virtual ~MySQLConnection(); - virtual bool Open(); + virtual uint32 Open(); void Close(); + bool PrepareStatements(); + public: bool Execute(const char* sql); bool Execute(PreparedStatement* stmt); @@ -111,7 +113,6 @@ class MySQLConnection MySQLPreparedStatement* GetPreparedStatement(uint32 index); void PrepareStatement(uint32 index, const char* sql, ConnectionFlags flags); - bool PrepareStatements(); virtual void DoPrepareStatements() = 0; protected: diff --git a/src/server/shared/Updater/DBUpdater.cpp b/src/server/shared/Updater/DBUpdater.cpp new file mode 100644 index 00000000000..68c8b76e3f7 --- /dev/null +++ b/src/server/shared/Updater/DBUpdater.cpp @@ -0,0 +1,408 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.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, see <http://www.gnu.org/licenses/>. + */ + +#include "DBUpdater.h" +#include "Log.h" +#include "revision.h" +#include "UpdateFetcher.h" +#include "DatabaseLoader.h" +#include "Config.h" + +#include <fstream> +#include <iostream> +#include <unordered_map> +#include <boost/process.hpp> +#include <boost/process/mitigate.hpp> +#include <boost/iostreams/device/file_descriptor.hpp> +#include <boost/system/system_error.hpp> + +using namespace boost::process; +using namespace boost::process::initializers; +using namespace boost::iostreams; + +template<class T> +std::string DBUpdater<T>::GetSourceDirectory() +{ + std::string const entry = sConfigMgr->GetStringDefault("Updates.SourcePath", ""); + if (!entry.empty()) + return entry; + else + return _SOURCE_DIRECTORY; +} + +template<class T> +std::string DBUpdater<T>::GetMySqlCli() +{ + std::string const entry = sConfigMgr->GetStringDefault("Updates.MySqlCLIPath", ""); + if (!entry.empty()) + return entry; + else + return _MYSQL_EXECUTABLE; +} + +// Auth Database +template<> +std::string DBUpdater<LoginDatabaseConnection>::GetConfigEntry() +{ + return "Updates.Auth"; +} + +template<> +std::string DBUpdater<LoginDatabaseConnection>::GetTableName() +{ + return "Auth"; +} + +template<> +std::string DBUpdater<LoginDatabaseConnection>::GetBaseFile() +{ + return DBUpdater<LoginDatabaseConnection>::GetSourceDirectory() + "/sql/base/auth_database.sql"; +} + +template<> +bool DBUpdater<LoginDatabaseConnection>::IsEnabled(uint32 const updateMask) +{ + // This way silences warnings under msvc + return (updateMask & DatabaseLoader::DATABASE_LOGIN) ? true : false; +} + +// World Database +template<> +std::string DBUpdater<WorldDatabaseConnection>::GetConfigEntry() +{ + return "Updates.World"; +} + +template<> +std::string DBUpdater<WorldDatabaseConnection>::GetTableName() +{ + return "World"; +} + +template<> +std::string DBUpdater<WorldDatabaseConnection>::GetBaseFile() +{ + return _FULL_DATABASE; +} + +template<> +bool DBUpdater<WorldDatabaseConnection>::IsEnabled(uint32 const updateMask) +{ + // This way silences warnings under msvc + return (updateMask & DatabaseLoader::DATABASE_WORLD) ? true : false; +} + +template<> +BaseLocation DBUpdater<WorldDatabaseConnection>::GetBaseLocationType() +{ + return LOCATION_DOWNLOAD; +} + +// Character Database +template<> +std::string DBUpdater<CharacterDatabaseConnection>::GetConfigEntry() +{ + return "Updates.Character"; +} + +template<> +std::string DBUpdater<CharacterDatabaseConnection>::GetTableName() +{ + return "Character"; +} + +template<> +std::string DBUpdater<CharacterDatabaseConnection>::GetBaseFile() +{ + return DBUpdater<CharacterDatabaseConnection>::GetSourceDirectory() + "/sql/base/characters_database.sql"; +} + +template<> +bool DBUpdater<CharacterDatabaseConnection>::IsEnabled(uint32 const updateMask) +{ + // This way silences warnings under msvc + return (updateMask & DatabaseLoader::DATABASE_CHARACTER) ? true : false; +} + +// Hotfix Database +template<> +std::string DBUpdater<HotfixDatabaseConnection>::GetConfigEntry() +{ + return "Updates.Hotfix"; +} + +template<> +std::string DBUpdater<HotfixDatabaseConnection>::GetTableName() +{ + return "Hotfixes"; +} + +template<> +std::string DBUpdater<HotfixDatabaseConnection>::GetBaseFile() +{ + return DBUpdater<HotfixDatabaseConnection>::GetSourceDirectory() + "/sql/base/hotfixes_database.sql"; +} + +template<> +bool DBUpdater<HotfixDatabaseConnection>::IsEnabled(uint32 const updateMask) +{ + // This way silences warnings under msvc + return (updateMask & DatabaseLoader::DATABASE_HOTFIX) ? true : false; +} + +// All +template<class T> +BaseLocation DBUpdater<T>::GetBaseLocationType() +{ + return LOCATION_REPOSITORY; +} + +template<class T> +bool DBUpdater<T>::CheckExecutable() +{ + DBUpdater<T>::Path const exe(DBUpdater<T>::GetMySqlCli()); + if (!exists(exe)) + { + // Check for mysql in path + std::vector<std::string> args = {"--version"}; + uint32 ret; + try + { + child c = execute(run_exe("mysql"), set_args(args), throw_on_error(), close_stdout()); + ret = wait_for_exit(c); + } + catch (boost::system::system_error&) + { + ret = EXIT_FAILURE; + } + + if (ret == EXIT_FAILURE) + { + TC_LOG_FATAL("sql.updates", "Didn't find executeable mysql binary at \'%s\', correct the path in the *.conf (\"Updates.MySqlCLIPath\").", + absolute(exe).generic_string().c_str()); + + return false; + } + } + return true; +} + +template<class T> +bool DBUpdater<T>::Create(DatabaseWorkerPool<T>& pool) +{ + TC_LOG_INFO("sql.updates", "Database \"%s\" does not exist, do you want to create it? [yes (default) / no]: ", + pool.GetConnectionInfo()->database.c_str()); + + std::string answer; + std::getline(std::cin, answer); + if (!answer.empty() && !(answer.substr(0, 1) == "y")) + return false; + + TC_LOG_INFO("sql.updates", "Creating database \"%s\"...", pool.GetConnectionInfo()->database.c_str()); + + // Path of temp file + static Path const temp("create_table.sql"); + + // Create temporary query to use external mysql cli + std::ofstream file(temp.generic_string()); + if (!file.is_open()) + { + TC_LOG_FATAL("sql.updates", "Failed to create temporary query file \"%s\"!", temp.generic_string().c_str()); + return false; + } + + file << "CREATE DATABASE `" << pool.GetConnectionInfo()->database << "` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci\n\n"; + + file.close(); + + try + { + DBUpdater<T>::ApplyFile(pool, pool.GetConnectionInfo()->host, pool.GetConnectionInfo()->user, pool.GetConnectionInfo()->password, + pool.GetConnectionInfo()->port_or_socket, "", temp); + } + catch (UpdateException&) + { + TC_LOG_FATAL("sql.updates", "Failed to create database %s! Has the user `CREATE` priviliges?", pool.GetConnectionInfo()->database.c_str()); + boost::filesystem::remove(temp); + return false; + } + + TC_LOG_INFO("sql.updates", "Done."); + boost::filesystem::remove(temp); + return true; +} + +template<class T> +bool DBUpdater<T>::Update(DatabaseWorkerPool<T>& pool) +{ + if (!DBUpdater<T>::CheckExecutable()) + return false; + + TC_LOG_INFO("sql.updates", "Updating %s database...", DBUpdater<T>::GetTableName().c_str()); + + Path const sourceDirectory(GetSourceDirectory()); + + if (!is_directory(sourceDirectory)) + { + TC_LOG_ERROR("sql.updates", "DBUpdater: Given source directory %s does not exist, skipped!", sourceDirectory.generic_string().c_str()); + return false; + } + + UpdateFetcher updateFetcher(sourceDirectory, [&](std::string const& query) { DBUpdater<T>::Apply(pool, query); }, + [&](Path const& file) { DBUpdater<T>::ApplyFile(pool, file); }, + [&](std::string const& query) -> QueryResult { return DBUpdater<T>::Retrieve(pool, query); }); + + uint32 const count = updateFetcher.Update( + sConfigMgr->GetBoolDefault("Updates.Redundancy", true), + sConfigMgr->GetBoolDefault("Updates.AllowRehash", true), + sConfigMgr->GetBoolDefault("Updates.ArchivedRedundancy", false), + sConfigMgr->GetBoolDefault("Updates.CleanDeadRef", true)); + + if (!count) + TC_LOG_INFO("sql.updates", ">> %s database is up-to-date!", DBUpdater<T>::GetTableName().c_str()); + else + TC_LOG_INFO("sql.updates", ">> Applied %d %s.", count, count == 1 ? "query" : "queries"); + + return true; +} + +template<class T> +bool DBUpdater<T>::Populate(DatabaseWorkerPool<T>& pool) +{ + { + QueryResult const result = Retrieve(pool, "SHOW TABLES"); + if (result && (result->GetRowCount() > 0)) + return true; + } + + if (!DBUpdater<T>::CheckExecutable()) + return false; + + TC_LOG_INFO("sql.updates", "Database %s is empty, auto populating it...", DBUpdater<T>::GetTableName().c_str()); + + std::string const p = DBUpdater<T>::GetBaseFile(); + if (p.empty()) + { + TC_LOG_INFO("sql.updates", ">> No base file provided, skipped!"); + return true; + } + + Path const base(p); + if (!exists(base)) + { + switch (DBUpdater<T>::GetBaseLocationType()) + { + case LOCATION_REPOSITORY: + { + TC_LOG_ERROR("sql.updates", ">> Base file \"%s\" is missing, try to clone the source again.", + base.generic_string().c_str(), base.filename().generic_string().c_str()); + + break; + } + case LOCATION_DOWNLOAD: + { + TC_LOG_ERROR("sql.updates", ">> File \"%s\" is missing, download it from \"http://www.trinitycore.org/f/files/category/1-database/\"" \ + " and place it in your server directory.", base.filename().generic_string().c_str()); + break; + } + } + return false; + } + + // Update database + TC_LOG_INFO("sql.updates", ">> Applying \'%s\'...", base.generic_string().c_str()); + ApplyFile(pool, base); + + TC_LOG_INFO("sql.updates", ">> Done!"); + return true; +} + +template<class T> +QueryResult DBUpdater<T>::Retrieve(DatabaseWorkerPool<T>& pool, std::string const& query) +{ + return pool.PQuery(query.c_str()); +} + +template<class T> +void DBUpdater<T>::Apply(DatabaseWorkerPool<T>& pool, std::string const& query) +{ + pool.DirectExecute(query.c_str()); +} + +template<class T> +void DBUpdater<T>::ApplyFile(DatabaseWorkerPool<T>& pool, Path const& path) +{ + DBUpdater<T>::ApplyFile(pool, pool.GetConnectionInfo()->host, pool.GetConnectionInfo()->user, pool.GetConnectionInfo()->password, + pool.GetConnectionInfo()->port_or_socket, pool.GetConnectionInfo()->database, path); +} + +template<class T> +void DBUpdater<T>::ApplyFile(DatabaseWorkerPool<T>& pool, std::string const& host, std::string const& user, + std::string const& password, std::string const& port_or_socket, std::string const& database, Path const& path) +{ + std::vector<std::string> args; + args.reserve(7); + + // CLI Client connection info + args.push_back("-h" + host); + args.push_back("-u" + user); + args.push_back("-p" + password); + args.push_back("-P" + port_or_socket); + + // Set the default charset to utf8 + args.push_back("--default-character-set=utf8"); + + // Set max allowed packet to 1 GB + args.push_back("--max-allowed-packet=1GB"); + + // Database + if (!database.empty()) + args.push_back(database); + + // ToDo: use the existing query in memory as virtual file if possible + file_descriptor_source source(path); + + uint32 ret; + try + { + child c = execute(run_exe(DBUpdater<T>::GetMySqlCli().empty() ? "mysql" : + boost::filesystem::absolute(DBUpdater<T>::GetMySqlCli()).generic_string()), + set_args(args), bind_stdin(source), throw_on_error()); + + ret = wait_for_exit(c); + } + catch (boost::system::system_error&) + { + ret = EXIT_FAILURE; + } + + source.close(); + + if (ret != EXIT_SUCCESS) + { + TC_LOG_FATAL("sql.updates", "Applying of file \'%s\' to database \'%s\' failed!" \ + " If you are an user pull the latest revision from the repository. If you are a developer fix your sql query.", + path.generic_string().c_str(), pool.GetConnectionInfo()->database.c_str()); + + throw UpdateException("update failed"); + } +} + +template class DBUpdater<LoginDatabaseConnection>; +template class DBUpdater<WorldDatabaseConnection>; +template class DBUpdater<CharacterDatabaseConnection>; +template class DBUpdater<HotfixDatabaseConnection>; diff --git a/src/server/shared/Updater/DBUpdater.h b/src/server/shared/Updater/DBUpdater.h new file mode 100644 index 00000000000..0caf8a438fb --- /dev/null +++ b/src/server/shared/Updater/DBUpdater.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef DBUpdater_h__ +#define DBUpdater_h__ + +#include "DatabaseEnv.h" + +#include <string> +#include <boost/filesystem.hpp> + +class UpdateException : public std::exception +{ +public: + UpdateException(std::string const& msg) : _msg(msg) { } + ~UpdateException() throw() { } + + char const* what() const throw() override { return _msg.c_str(); } + +private: + std::string const _msg; +}; + +enum BaseLocation +{ + LOCATION_REPOSITORY, + LOCATION_DOWNLOAD +}; + +template <class T> +class DBUpdater +{ +public: + using Path = boost::filesystem::path; + + static std::string GetSourceDirectory(); + + static inline std::string GetConfigEntry(); + + static inline std::string GetTableName(); + + static std::string GetBaseFile(); + + static bool IsEnabled(uint32 const updateMask); + + static BaseLocation GetBaseLocationType(); + + static bool Create(DatabaseWorkerPool<T>& pool); + + static bool Update(DatabaseWorkerPool<T>& pool); + + static bool Populate(DatabaseWorkerPool<T>& pool); + +private: + static std::string GetMySqlCli(); + static bool CheckExecutable(); + + static QueryResult Retrieve(DatabaseWorkerPool<T>& pool, std::string const& query); + static void Apply(DatabaseWorkerPool<T>& pool, std::string const& query); + static void ApplyFile(DatabaseWorkerPool<T>& pool, Path const& path); + static void ApplyFile(DatabaseWorkerPool<T>& pool, std::string const& host, std::string const& user, + std::string const& password, std::string const& port_or_socket, std::string const& database, Path const& path); +}; + +#endif // DBUpdater_h__ diff --git a/src/server/shared/Updater/UpdateFetcher.cpp b/src/server/shared/Updater/UpdateFetcher.cpp new file mode 100644 index 00000000000..8084c6ba37f --- /dev/null +++ b/src/server/shared/Updater/UpdateFetcher.cpp @@ -0,0 +1,387 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.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, see <http://www.gnu.org/licenses/>. + */ + +#include "UpdateFetcher.h" +#include "Log.h" +#include "Util.h" + +#include <fstream> +#include <chrono> +#include <vector> +#include <sstream> +#include <exception> +#include <unordered_map> +#include <openssl/sha.h> + +using namespace boost::filesystem; + +UpdateFetcher::UpdateFetcher(Path const& sourceDirectory, + std::function<void(std::string const&)> const& apply, + std::function<void(Path const& path)> const& applyFile, + std::function<QueryResult(std::string const&)> const& retrieve) : + _sourceDirectory(sourceDirectory), _apply(apply), _applyFile(applyFile), + _retrieve(retrieve) +{ +} + +UpdateFetcher::LocaleFileStorage UpdateFetcher::GetFileList() const +{ + LocaleFileStorage files; + DirectoryStorage directories = ReceiveIncludedDirectories(); + for (auto const& entry : directories) + FillFileListRecursively(entry.path, files, entry.state, 1); + + return files; +} + +void UpdateFetcher::FillFileListRecursively(Path const& path, LocaleFileStorage& storage, State const state, uint32 const depth) const +{ + static uint32 const MAX_DEPTH = 10; + static directory_iterator const end; + + for (directory_iterator itr(path); itr != end; ++itr) + { + if (is_directory(itr->path())) + { + if (depth < MAX_DEPTH) + FillFileListRecursively(itr->path(), storage, state, depth + 1); + } + else if (itr->path().extension() == ".sql") + { + TC_LOG_TRACE("sql.updates", "Added locale file \"%s\".", itr->path().filename().generic_string().c_str()); + + LocaleFileEntry const entry = { itr->path(), state }; + + // Check for doubled filenames + // Since elements are only compared through their filenames this is ok + if (storage.find(entry) != storage.end()) + { + TC_LOG_FATAL("sql.updates", "Duplicated filename occurred \"%s\", since updates are ordered " \ + "through its filename every name needs to be unique!", itr->path().generic_string().c_str()); + + throw UpdateException("Updating failed, see the log for details."); + } + + storage.insert(entry); + } + } +} + +UpdateFetcher::DirectoryStorage UpdateFetcher::ReceiveIncludedDirectories() const +{ + DirectoryStorage directories; + + QueryResult const result = _retrieve("SELECT `path`, `state` FROM `updates_include`"); + if (!result) + return directories; + + do + { + Field* fields = result->Fetch(); + + std::string path = fields[0].GetString(); + if (path.substr(0, 1) == "$") + path = _sourceDirectory.generic_string() + path.substr(1); + + Path const p(path); + + if (!is_directory(p)) + { + TC_LOG_ERROR("sql.updates", "DBUpdater: Given update include directory \"%s\" isn't existing, skipped!", p.generic_string().c_str()); + continue; + } + + DirectoryEntry const entry = { p, AppliedFileEntry::StateConvert(fields[1].GetString()) }; + directories.push_back(entry); + + TC_LOG_TRACE("sql.updates", "Added applied file \"%s\" from remote.", p.filename().generic_string().c_str()); + + } while (result->NextRow()); + + return directories; +} + +UpdateFetcher::AppliedFileStorage UpdateFetcher::ReceiveAppliedFiles() const +{ + AppliedFileStorage map; + + QueryResult result = _retrieve("SELECT `name`, `hash`, `state`, `timestamp` FROM `updates` ORDER BY `name` ASC"); + if (!result) + return map; + + do + { + Field* fields = result->Fetch(); + + AppliedFileEntry const entry = { fields[0].GetString(), fields[1].GetString(), + AppliedFileEntry::StateConvert(fields[2].GetString()), fields[3].GetUInt32() }; + + map.insert(std::make_pair(entry.name, entry)); + } + while (result->NextRow()); + + return map; +} + +UpdateFetcher::SQLUpdate UpdateFetcher::ReadSQLUpdate(boost::filesystem::path const& file) const +{ + std::ifstream in(file.c_str()); + WPFatal(in.is_open(), "Could not read an update file."); + + auto const start_pos = in.tellg(); + in.ignore(std::numeric_limits<std::streamsize>::max()); + auto const char_count = in.gcount(); + in.seekg(start_pos); + + SQLUpdate const update(new std::string(char_count, char{})); + + in.read(&(*update)[0], update->size()); + in.close(); + return update; +} + +uint32 UpdateFetcher::Update(bool const redundancyChecks, bool const allowRehash, bool const archivedRedundancy, bool const cleanDeadReferences) const +{ + LocaleFileStorage const available = GetFileList(); + AppliedFileStorage applied = ReceiveAppliedFiles(); + + // Fill hash to name cache + HashToFileNameStorage hashToName; + for (auto entry : applied) + hashToName.insert(std::make_pair(entry.second.hash, entry.first)); + + uint32 importedUpdates = 0; + + for (auto const& availableQuery : available) + { + TC_LOG_DEBUG("sql.updates", "Checking update \"%s\"...", availableQuery.first.filename().generic_string().c_str()); + + AppliedFileStorage::const_iterator iter = applied.find(availableQuery.first.filename().string()); + if (iter != applied.end()) + { + // If redundancy is disabled skip it since the update is already applied. + if (!redundancyChecks) + { + TC_LOG_DEBUG("sql.updates", ">> Update is already applied, skipping redundancy checks."); + applied.erase(iter); + continue; + } + + // If the update is in an archived directory and is marked as archived in our database skip redundancy checks (archived updates never change). + if (!archivedRedundancy && (iter->second.state == ARCHIVED) && (availableQuery.second == ARCHIVED)) + { + TC_LOG_DEBUG("sql.updates", ">> Update is archived and marked as archived in database, skipping redundancy checks."); + applied.erase(iter); + continue; + } + } + + // Read update from file + SQLUpdate const update = ReadSQLUpdate(availableQuery.first); + + // Calculate hash + std::string const hash = CalculateHash(update); + + UpdateMode mode = MODE_APPLY; + + // Update is not in our applied list + if (iter == applied.end()) + { + // Catch renames (different filename but same hash) + HashToFileNameStorage::const_iterator const hashIter = hashToName.find(hash); + if (hashIter != hashToName.end()) + { + // Check if the original file was removed if not we've got a problem. + LocaleFileStorage::const_iterator localeIter; + // Push localeIter forward + for (localeIter = available.begin(); (localeIter != available.end()) && + (localeIter->first.filename().string() != hashIter->second); ++localeIter); + + // Conflict! + if (localeIter != available.end()) + { + TC_LOG_WARN("sql.updates", ">> Seems like update \"%s\" \'%s\' was renamed, but the old file is still there! " \ + "Trade it as a new file! (Probably its an unmodified copy of file \"%s\")", + availableQuery.first.filename().string().c_str(), hash.substr(0, 7).c_str(), + localeIter->first.filename().string().c_str()); + } + // Its save to trade the file as renamed here + else + { + TC_LOG_INFO("sql.updates", ">> Renaming update \"%s\" to \"%s\" \'%s\'.", + hashIter->second.c_str(), availableQuery.first.filename().string().c_str(), hash.substr(0, 7).c_str()); + + RenameEntry(hashIter->second, availableQuery.first.filename().string()); + applied.erase(hashIter->second); + continue; + } + } + // Apply the update if it was never seen before. + else + { + TC_LOG_INFO("sql.updates", ">> Applying update \"%s\" \'%s\'...", + availableQuery.first.filename().string().c_str(), hash.substr(0, 7).c_str()); + } + } + // Rehash the update entry if it is contained in our database but with an empty hash. + else if (allowRehash && iter->second.hash.empty()) + { + mode = MODE_REHASH; + + TC_LOG_INFO("sql.updates", ">> Re-hashing update \"%s\" \'%s\'...", availableQuery.first.filename().string().c_str(), + hash.substr(0, 7).c_str()); + } + else + { + // If the hash of the files differs from the one stored in our database reapply the update (because it was changed). + if (iter->second.hash != hash) + { + TC_LOG_INFO("sql.updates", ">> Reapplying update \"%s\" \'%s\' -> \'%s\' (it changed)...", availableQuery.first.filename().string().c_str(), + iter->second.hash.substr(0, 7).c_str(), hash.substr(0, 7).c_str()); + } + else + { + // If the file wasn't changed and just moved update its state if necessary. + if (iter->second.state != availableQuery.second) + { + TC_LOG_DEBUG("sql.updates", ">> Updating state of \"%s\" to \'%s\'...", + availableQuery.first.filename().string().c_str(), AppliedFileEntry::StateConvert(availableQuery.second).c_str()); + + UpdateState(availableQuery.first.filename().string(), availableQuery.second); + } + + TC_LOG_DEBUG("sql.updates", ">> Update is already applied and is matching hash \'%s\'.", hash.substr(0, 7).c_str()); + + applied.erase(iter); + continue; + } + } + + uint32 speed = 0; + AppliedFileEntry const file = { availableQuery.first.filename().string(), hash, availableQuery.second, 0 }; + + switch (mode) + { + case MODE_APPLY: + speed = Apply(availableQuery.first); + /*no break*/ + case MODE_REHASH: + UpdateEntry(file, speed); + break; + } + + if (iter != applied.end()) + applied.erase(iter); + + if (mode == MODE_APPLY) + ++importedUpdates; + } + + for (auto const& entry : applied) + { + TC_LOG_WARN("sql.updates", ">> File \'%s\' was applied to the database but is missing in" \ + " your update directory now!%s", entry.first.c_str(), cleanDeadReferences ? " Deleting orphaned entry..." : ""); + } + + if (cleanDeadReferences) + CleanUp(applied); + + return importedUpdates; +} + +std::string UpdateFetcher::CalculateHash(SQLUpdate const& query) const +{ + // Calculate a Sha1 hash based on query content. + unsigned char digest[SHA_DIGEST_LENGTH]; + SHA1((unsigned char*)query->c_str(), query->length(), (unsigned char*)&digest); + + return ByteArrayToHexStr(digest, SHA_DIGEST_LENGTH); +} + +uint32 UpdateFetcher::Apply(Path const& path) const +{ + using Time = std::chrono::high_resolution_clock; + using ms = std::chrono::milliseconds; + + // Benchmark query speed + auto const begin = Time::now(); + + // Update database + _applyFile(path); + + // Return time the query took to apply + return std::chrono::duration_cast<ms>(Time::now() - begin).count(); +} + +void UpdateFetcher::UpdateEntry(AppliedFileEntry const& entry, uint32 const speed) const +{ + std::string const update = "REPLACE INTO `updates` (`name`, `hash`, `state`, `speed`) VALUES (\"" + + entry.name + "\", \"" + entry.hash + "\", \'" + entry.GetStateAsString() + "\', " + std::to_string(speed) + ")"; + + // Update database + _apply(update); +} + +void UpdateFetcher::RenameEntry(std::string const& from, std::string const& to) const +{ + // Delete target if it exists + { + std::string const update = "DELETE FROM `updates` WHERE `name`=\"" + to + "\""; + + // Update database + _apply(update); + } + + // Rename + { + std::string const update = "UPDATE `updates` SET `name`=\"" + to + "\" WHERE `name`=\"" + from + "\""; + + // Update database + _apply(update); + } +} + +void UpdateFetcher::CleanUp(AppliedFileStorage const& storage) const +{ + if (storage.empty()) + return; + + std::stringstream update; + size_t remaining = storage.size(); + + update << "DELETE FROM `updates` WHERE `name` IN("; + + for (auto const& entry : storage) + { + update << "\"" << entry.first << "\""; + if ((--remaining) > 0) + update << ", "; + } + + update << ")"; + + // Update database + _apply(update.str()); +} + +void UpdateFetcher::UpdateState(std::string const& name, State const state) const +{ + std::string const update = "UPDATE `updates` SET `state`=\'" + AppliedFileEntry::StateConvert(state) + "\' WHERE `name`=\"" + name + "\""; + + // Update database + _apply(update); +} diff --git a/src/server/shared/Updater/UpdateFetcher.h b/src/server/shared/Updater/UpdateFetcher.h new file mode 100644 index 00000000000..b348eecf4e1 --- /dev/null +++ b/src/server/shared/Updater/UpdateFetcher.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef UpdateFetcher_h__ +#define UpdateFetcher_h__ + +#include <DBUpdater.h> + +#include <functional> +#include <string> +#include <memory> +#include <vector> +#include <boost/container/flat_set.hpp> + +class UpdateFetcher +{ + using Path = boost::filesystem::path; + +public: + UpdateFetcher(Path const& updateDirectory, + std::function<void(std::string const&)> const& apply, + std::function<void(Path const& path)> const& applyFile, + std::function<QueryResult(std::string const&)> const& retrieve); + + uint32 Update(bool const redundancyChecks, bool const allowRehash, + bool const archivedRedundancy, bool const cleanDeadReferences) const; + +private: + enum UpdateMode + { + MODE_APPLY, + MODE_REHASH + }; + + enum State + { + RELEASED, + ARCHIVED + }; + + struct AppliedFileEntry + { + std::string const name; + + std::string const hash; + + State const state; + + uint32 const timestamp; + + static inline State StateConvert(std::string const& state) + { + return (state == "RELEASED") ? RELEASED : ARCHIVED; + } + + static inline std::string StateConvert(State const state) + { + return (state == RELEASED) ? "RELEASED" : "ARCHIVED"; + } + + std::string GetStateAsString() const + { + return StateConvert(state); + } + }; + + struct DirectoryEntry + { + Path const path; + + State const state; + }; + + using LocaleFileEntry = std::pair<Path, State>; + + struct PathCompare + { + inline bool operator() (LocaleFileEntry const& left, LocaleFileEntry const& right) const + { + return left.first.filename().string() < right.first.filename().string(); + } + }; + + using LocaleFileStorage = boost::container::flat_set<LocaleFileEntry, PathCompare>; + using HashToFileNameStorage = std::unordered_map<std::string, std::string>; + using AppliedFileStorage = std::unordered_map<std::string, AppliedFileEntry>; + using DirectoryStorage = std::vector<UpdateFetcher::DirectoryEntry>; + using SQLUpdate = std::shared_ptr<std::string>; + + LocaleFileStorage GetFileList() const; + void FillFileListRecursively(Path const& path, LocaleFileStorage& storage, State const state, uint32 const depth) const; + + DirectoryStorage ReceiveIncludedDirectories() const; + AppliedFileStorage ReceiveAppliedFiles() const; + + SQLUpdate ReadSQLUpdate(Path const& file) const; + std::string CalculateHash(SQLUpdate const& query) const; + + uint32 Apply(Path const& path) const; + + void UpdateEntry(AppliedFileEntry const& entry, uint32 const speed = 0) const; + void RenameEntry(std::string const& from, std::string const& to) const; + void CleanUp(AppliedFileStorage const& storage) const; + + void UpdateState(std::string const& name, State const state) const; + + Path const _sourceDirectory; + + std::function<void(std::string const&)> const _apply; + std::function<void(Path const& path)> const _applyFile; + std::function<QueryResult(std::string const&)> const _retrieve; +}; + +#endif // UpdateFetcher_h__ diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt index 683c4de8eb8..63da20df2c7 100644 --- a/src/server/worldserver/CMakeLists.txt +++ b/src/server/worldserver/CMakeLists.txt @@ -49,6 +49,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/dep/SFMT ${CMAKE_SOURCE_DIR}/dep/cppformat ${CMAKE_SOURCE_DIR}/dep/zmqpp + ${CMAKE_SOURCE_DIR}/dep/process ${CMAKE_SOURCE_DIR}/src/server/collision ${CMAKE_SOURCE_DIR}/src/server/collision/Management ${CMAKE_SOURCE_DIR}/src/server/collision/Models @@ -65,6 +66,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/shared/Networking ${CMAKE_SOURCE_DIR}/src/server/shared/Packets ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Updater ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities ${CMAKE_SOURCE_DIR}/src/server/ipc ${CMAKE_SOURCE_DIR}/src/server/game diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index 15d08a903b9..032c8428445 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -44,6 +44,7 @@ #include "WorldSocketMgr.h" #include "BattlenetServerManager.h" #include "Realm/Realm.h" +#include "DatabaseLoader.h" #include <openssl/opensslv.h> #include <openssl/crypto.h> #include <boost/asio/io_service.hpp> @@ -520,105 +521,16 @@ bool StartDB() { MySQL::Library_Init(); - std::string dbString; - uint8 asyncThreads, synchThreads; + // Load databases + DatabaseLoader loader("server.worldserver", DatabaseLoader::DATABASE_MASK_ALL); + loader + .AddDatabase(HotfixDatabase, "Hotfix") + .AddDatabase(WorldDatabase, "World") + .AddDatabase(CharacterDatabase, "Character") + .AddDatabase(LoginDatabase, "Login"); - dbString = sConfigMgr->GetStringDefault("WorldDatabaseInfo", ""); - if (dbString.empty()) - { - TC_LOG_ERROR("server.worldserver", "World database not specified in configuration file"); - return false; - } - - asyncThreads = uint8(sConfigMgr->GetIntDefault("WorldDatabase.WorkerThreads", 1)); - if (asyncThreads < 1 || asyncThreads > 32) - { - TC_LOG_ERROR("server.worldserver", "World database: invalid number of worker threads specified. " - "Please pick a value between 1 and 32."); - return false; - } - - synchThreads = uint8(sConfigMgr->GetIntDefault("WorldDatabase.SynchThreads", 1)); - ///- Initialize the world database - if (!WorldDatabase.Open(dbString, asyncThreads, synchThreads)) - { - TC_LOG_ERROR("server.worldserver", "Cannot connect to world database %s", dbString.c_str()); - return false; - } - - ///- Get character database info from configuration file - dbString = sConfigMgr->GetStringDefault("CharacterDatabaseInfo", ""); - if (dbString.empty()) - { - TC_LOG_ERROR("server.worldserver", "Character database not specified in configuration file"); - return false; - } - - asyncThreads = uint8(sConfigMgr->GetIntDefault("CharacterDatabase.WorkerThreads", 1)); - if (asyncThreads < 1 || asyncThreads > 32) - { - TC_LOG_ERROR("server.worldserver", "Character database: invalid number of worker threads specified. " - "Please pick a value between 1 and 32."); - return false; - } - - synchThreads = uint8(sConfigMgr->GetIntDefault("CharacterDatabase.SynchThreads", 2)); - - ///- Initialize the Character database - if (!CharacterDatabase.Open(dbString, asyncThreads, synchThreads)) - { - TC_LOG_ERROR("server.worldserver", "Cannot connect to Character database %s", dbString.c_str()); - return false; - } - - ///- Get hotfixes database info from configuration file - dbString = sConfigMgr->GetStringDefault("HotfixDatabaseInfo", ""); - if (dbString.empty()) - { - TC_LOG_ERROR("server.worldserver", "Hotfixes database not specified in configuration file"); - return false; - } - - asyncThreads = uint8(sConfigMgr->GetIntDefault("HotfixDatabase.WorkerThreads", 1)); - if (asyncThreads < 1 || asyncThreads > 32) - { - TC_LOG_ERROR("server.worldserver", "Hotfixes database: invalid number of worker threads specified. " - "Please pick a value between 1 and 32."); - return false; - } - - synchThreads = uint8(sConfigMgr->GetIntDefault("HotfixDatabase.SynchThreads", 2)); - - ///- Initialize the hotfixes database - if (!HotfixDatabase.Open(dbString, asyncThreads, synchThreads)) - { - TC_LOG_ERROR("server.worldserver", "Cannot connect to the hotfix database %s", dbString.c_str()); - return false; - } - - ///- Get login database info from configuration file - dbString = sConfigMgr->GetStringDefault("LoginDatabaseInfo", ""); - if (dbString.empty()) - { - TC_LOG_ERROR("server.worldserver", "Login database not specified in configuration file"); - return false; - } - - asyncThreads = uint8(sConfigMgr->GetIntDefault("LoginDatabase.WorkerThreads", 1)); - if (asyncThreads < 1 || asyncThreads > 32) - { - TC_LOG_ERROR("server.worldserver", "Login database: invalid number of worker threads specified. " - "Please pick a value between 1 and 32."); - return false; - } - - synchThreads = uint8(sConfigMgr->GetIntDefault("LoginDatabase.SynchThreads", 1)); - ///- Initialise the login database - if (!LoginDatabase.Open(dbString, asyncThreads, synchThreads)) - { - TC_LOG_ERROR("server.worldserver", "Cannot connect to login database %s", dbString.c_str()); + if (!loader.Load()) return false; - } ///- Get the realm Id from the configuration file realmHandle.Index = sConfigMgr->GetIntDefault("RealmID", 0); @@ -628,6 +540,7 @@ bool StartDB() return false; } + // Realm Handles QueryResult realmIdQuery = LoginDatabase.PQuery("SELECT `Region`,`Battlegroup` FROM `realmlist` WHERE `id`=%u", realmHandle.Index); if (!realmIdQuery) { diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 86d9dac2946..4254061e2fa 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -11,6 +11,7 @@ # PERFORMANCE SETTINGS # SERVER LOGGING # SERVER SETTINGS +# UPDATE SETTINGS # WARDEN SETTINGS # PLAYER INTERACTION # CREATURE SETTINGS @@ -1130,6 +1131,90 @@ FeatureSystem.CharacterUndelete.Cooldown = 2592000 ################################################################################################### ################################################################################################### +# UPDATE SETTINGS +# +# Updates.EnableDatabases +# Description: A mask that describes which databases shall be updated. +# +# Following flags are available +# DATABASE_LOGIN = 1, // Auth database +# DATABASE_CHARACTER = 2, // Character database +# DATABASE_WORLD = 4, // World database +# DATABASE_HOTFIX = 8, // Hotfixes database +# +# Default: 15 - (All enabled) +# 4 - (Enable world only) +# 0 - (All Disabled) + +Updates.EnableDatabases = 15 + +# +# Updates.SourcePath +# Description: The path to your TrinityCore source directory. +# If the path is left empty, built-in CMAKE_SOURCE_DIR is used. +# Example: "../TrinityCore" +# Default: "" + +Updates.SourcePath = "" + +# +# Updates.SourcePath +# Description: The path to your mysql cli binary. +# If the path is left empty, built-in path from cmake is used. +# Example: "C:/Program Files/MySQL/MySQL Server 5.6/bin/mysql.exe" +# "mysql.exe" +# "/usr/bin/mysql" +# Default: "" + +Updates.MySqlCLIPath = "" + +# +# Updates.AutoSetup +# Description: Auto populate empty databases. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.AutoSetup = 1 + +# +# Updates.Redundancy +# Description: Perform data redundancy checks through hashing +# to detect changes on sql updates and reapply it. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.Redundancy = 1 + +# +# Updates.ArchivedRedundancy +# Description: Check hashes of archived updates (slows down startup). +# Default: 0 - (Disabled) +# 1 - (Enabled) + +Updates.ArchivedRedundancy = 0 + +# +# Updates.AllowRehash +# Description: Inserts the current file hash in the database if it is left empty. +# Useful if you want to mark a file as applied but you don't know its hash. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.AllowRehash = 1 + +# +# Updates.CleanDeadRef +# Description: Cleans dead/ orphaned references that occure if a update was deleted or renamed and edited. +# Disable this if you want to know if the database is in a possible "dirty state". +# Default: 1 - (Enabled) +# 0 - (Disabled) + +Updates.CleanDeadRef = 1 + +# +################################################################################################### + +################################################################################################### # WARDEN SETTINGS # # Warden.Enabled @@ -3224,6 +3309,7 @@ Logger.root=5,Console Server Logger.server=3,Console Server Logger.commands.gm=3,Console GM Logger.sql.sql=5,Console DBErrors +Logger.sql.updates=3,Console Server #Logger.achievement=3,Console Server #Logger.ahbot=3,Console Server |