#ifndef __SITECING_CONFIGURATION_H #define __SITECING_CONFIGURATION_H #include #include #include #include #include #include /** * @file * @brief Classes related to configuration. */ namespace sitecing { using namespace std; class configuration; /** * The config options container class. */ class config_options { public: /** * The flags enumeration. */ enum _flags { /** * Skeleton has been specified in the context. * @see skeleton */ flag_skeleton = 0x0001, /** * CPPFLAGS have been specified in the context * @see cpp_flags */ flag_cpp_flags = 0x0002, /** * LDFLAGS have been specified in the context. * @see ld_flags */ flag_ld_flags = 0x0004, /** * Enforced intermediate dependencies have been specified in the * context. * @see internediate_deps */ flag_intermediate_deps = 0x0008, /** * Enforced .so dependencies have been specified in the context. * @see so_deps */ flag_so_deps = 0x0010, /** * Whether components should be built specified in the context. * @see build */ flag_build = 0x0020, /** * Whether to track down cpp dependencies has been specified in * the context. * @see cpp_deps */ flag_cpp_deps = 0x0040, /** * The exception handler has been specified in the context. * @see exception_handler */ flag_exception_handler = 0x0080, /** * Action handlers have been specified in the context. * @see action_handlers */ flag_action_handlers = 0x0100, /** * HTTP status handerls have been specified in the context. * @see http_status_handlers */ flag_http_status_handlers = 0x0200, /** * The files to be built are specified in the context. * @see auto_build_files */ flag_auto_build_files = 0x0400 }; /** * The flags specifying what parts of configuration have been * specified for the context. */ int flags; /** * The skeleton for building components. */ string skeleton; /** * The flags to pass to compiler. */ list cpp_flags; /** * The flags to pass to linker. */ list ld_flags; /** * Whether to build inexstent and outdated components. */ bool build; /** * Whether to track cpp dependencies. */ bool cpp_deps; /** * The component handling caught exceptions. */ string exception_handler; /** * Enforced intermediate dependencies. */ list intermediate_deps; /** * Enforced depencies for .so objects. */ list so_deps; /** * The action handler type. */ struct action_handler_t { /** * The regexp to check request against. */ string s_regex; /** * Precompiled regex. */ pcrepp::Pcre regex; /** * The action handler component. */ string action; /** * Arguments for the action hander coponent. */ list args; /** * @param s regex pattern * @param a action handler */ action_handler_t(const string& s,const string& a) : s_regex(s), regex(s), action(a) { } /** * Copy constructor * * @param s source object */ action_handler_t(const action_handler_t& s) : s_regex(s.s_regex), regex(s.regex), action (s.action), args(s.args) { } }; /** * Type for the list of action handlers. */ typedef list action_handlers_t; /** * The list of action handlers. */ action_handlers_t action_handlers; /** * Type for the map of HTTP status handler components. */ typedef map http_status_handlers_t; /** * The map of HTTP status handler components. */ http_status_handlers_t http_status_handlers; /** * Files to be built automatically. */ list auto_build_files; config_options() : flags(0) { } /** * Look up if there is an action handler for the target defined. * @param target the target component. * @return the pointer to handler or zero. */ action_handler_t *lookup_action_handler(const string& target); /** * Look up if there is a handler defined for the HTTP status. * @param status HTTP status * @return the handler component. */ string lookup_http_status_handler(const string& status); /** * Check whether the file should be build automatically. * @param fn file name. * @param rv reference to the boolean where the answer should go. * @return true if we know the answer. */ bool match_autobuild_files(const char *fn,bool &rv); }; /** * Configuration data container for the configuration loaded from disk file. */ class loaded_options : public config_options { public: /** * The file where configuration originates from. */ string source_file; /** * The stat structure for the source file as it was when we have * loaded it. */ struct stat st; /** * See if the data is still valid. * @return true if yes. */ bool is_valid(); /** * Load the configuration file. * @param config the main configuration container. * @param cfile the configuration file. */ void parse(configuration *config,const string& cfile); }; /** * The main configuration container. */ class configuration { public: /** * @todo TODO:: document me. */ bool autobuild; /** * The flags enumeration. */ enum _flags { /** * Was the source root specified? * @see root_source */ flag_root_source = 0x00000001, /** * Was the root for intermediate files specified? * @see root_intermediate */ flag_root_intermediate = 0x00000002, /** * Was the root for the resulting .so files specified? * @see root_so */ flag_root_so = 0x00000004, /** * Was the socket to listen to specified? * @see listen_socket */ flag_listen_socket = 0x00000008, /** * Was the per-dir config file name specified. * @see rc_file_name */ flag_rc_file_name = 0x00000010, /** * Was the minimum number of child processes specified? * @see min_children */ flag_min_children = 0x00000020, /** * Was the maximum number of child processes specified? * @see max_children */ flag_max_children = 0x00000040, /** * Was the minimum number of spare child processes specified? * @see min_spare_children */ flag_min_spare_children = 0x00000080, /** * Was he maximum number of spare child processes specified? * @see max_spare_children */ flag_max_spare_children = 0x00000100, /** * Was the number of requests to handle per child process * specified? * @see requests_per_child */ flag_requests_per_child = 0x00000200, /** * Was the multiprocess node (or it's absences) specified? * @see multi_process */ flag_multi_process = 0x00000400, /** * Was the user specified? * @see user */ flag_user = 0x00000800, /** * Was the group specified? * @see group */ flag_group = 0x00001000, /** * Was the root to change to specified? * @see chroot */ flag_chroot = 0x00002000, /** * Was the file for storing PID specified? * @see pidfile */ flag_pid_file = 0x00004000, /** * Was it specified wether we should daemonize the process? * @see daemonize */ flag_daemonize = 0x00008000 }; /** * The flags specifying what parts of the configuration has been * loaded into the object. */ long flags; /** * The root for the components source code. */ string root_source; /** * The root for intermediate files. */ string root_intermediate; /** * The root for .so files. */ string root_so; /** * Socket to bind to */ string listen_socket; /** * per-dir config file name. */ string rc_file_name; /** * The minimum number of child processes in multiprocess mode. */ int min_children; /** * The maxium number of child processes in multiprocess mode. */ int max_children; /** * The minimum number of spare chidren in multiprocess mode. */ int min_spare_children; /** * The maximum number of spare children in multiprocess mode. */ int max_spare_children; /** * The number of requests the child process should handle before * exiting. */ int requests_per_child; /** * Whether we should run in multiprocess mode or not. */ bool multi_process; /** * User to change to. */ string user; /** * Group to set to. */ string group; /** * Directory to change root to. */ string chroot; /** * The file to store PID into. */ string pid_file; /** * Whether we should fork into background. */ bool daemonize; /** * Type for the config options map * @see specs */ typedef map specs_t; /** * The local config options map. */ specs_t specs; /** * Type for the loaded per-dir config map * @see loaded_specs */ typedef map loaded_specs_t; /** * The local config options as specified in per-dir config files * map. */ loaded_specs_t loaded_specs; configuration(); /** * @param cfile the configuration file. * @param ab document me @todo TODO:: document me */ configuration(const string& cfile,bool ab=false); /** * Parse the configuration file. * @param cfile the configuration file. */ void parse(const string& cfile); /** * Fetch the reference to options for the very root. */ config_options& root_options() { return specs[""]; } /** * Lookup where the certain config option for the target lies in. * @param target the target component. * @param flag the flag specifying the option we're looking for. * @return the destination options continer or zero. */ config_options* lookup_config(const string& target,int flag); /** * Lookup the action handler for the target. * @param target the target request. * @return the action handler or zero. */ config_options::action_handler_t *lookup_action_handler(const string& target); /** * Lookup the HTPP status handler for the target. * @param target the target. * @param status the HTTP status. * @return the handler component. */ string lookup_http_status_handler(const string& target,const string& status); /** * Lookup the options loaded from per-dir config for the target * @param target the target. * @return options container or zero. */ loaded_options* lookup_loaded_options(const string& target); /** * Check whether the components for the target should be prebuilt. * @param target the target. * @param fn file name. * @return true if yes. */ bool match_autobuild_files(const string& target,const char *fn); }; } #endif /* __SITECING_CONFIGURATION_H */