diff options
Diffstat (limited to 'src/librc/rc.h')
-rw-r--r-- | src/librc/rc.h | 446 |
1 files changed, 446 insertions, 0 deletions
diff --git a/src/librc/rc.h b/src/librc/rc.h new file mode 100644 index 00000000..0020764e --- /dev/null +++ b/src/librc/rc.h @@ -0,0 +1,446 @@ +/* + * Copyright 2007 Roy Marples + * All rights reserved + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __RC_H__ +#define __RC_H__ + +#ifdef __GNUC__ +# define GCC_VERSION (__GNUC__ * 1000 + __GNUC__MINOR) +# if (GCC_VERSION >= 3005) +# define SENTINEL __attribute__ ((__sentinel__)) +# endif +#endif +#ifndef SENTINEL +# define SENTINEL +#endif + +#include <sys/types.h> +#include <stdbool.h> + +/*! @name Reserved runlevel names */ +#define RC_LEVEL_SYSINIT "sysinit" +#define RC_LEVEL_SINGLE "single" +#define RC_LEVEL_SHUTDOWN "shutdown" +#define RC_LEVEL_REBOOT "reboot" + +/*! Return the current runlevel. + * @return the current runlevel */ +char *rc_runlevel_get (void); + +/*! Checks if the runlevel exists or not + * @param runlevel to check + * @return true if the runlevel exists, otherwise false */ +bool rc_runlevel_exists (const char *runlevel); + +/*! Return a NULL terminated list of runlevels + * @return a NULL terminated list of runlevels */ +char **rc_runlevel_list (void); + +/*! Set the runlevel. + * This just changes the stored runlevel and does not start or stop any services. + * @param runlevel to store */ +bool rc_runlevel_set (const char *runlevel); + +/*! Is the runlevel starting? + * @return true if yes, otherwise false */ +bool rc_runlevel_starting (void); + +/*! Is the runlevel stopping? + * @return true if yes, otherwise false */ +bool rc_runlevel_stopping (void); + +/*! @name RC + * A service can be given as a full path or just its name. + * If its just a name then we try to resolve the service to a full path. + * This should allow the use if local init.d directories in the future. */ + +/*! @brief States a service can be in */ +typedef enum +{ + /* These are actual states + * The service has to be in one only at all times */ + RC_SERVICE_STOPPED = 0x0001, + RC_SERVICE_STARTED = 0x0002, + RC_SERVICE_STOPPING = 0x0004, + RC_SERVICE_STARTING = 0x0008, + RC_SERVICE_INACTIVE = 0x0010, + + /* Service may or may not have been coldplugged */ + RC_SERVICE_COLDPLUGGED = 0x0100, + + /* Optional states service could also be in */ + RC_SERVICE_FAILED = 0x0200, + RC_SERVICE_SCHEDULED = 0x0400, + RC_SERVICE_WASINACTIVE = 0x0800 +} rc_service_state_t; + +/*! Add the service to the runlevel + * @param runlevel to add to + * @param service to add + * @return true if successful, otherwise false */ +bool rc_service_add (const char *runlevel, const char *service); + +/*! Remove the service from the runlevel + * @param runlevel to remove from + * @param service to remove + * @return true if sucessful, otherwise false */ +bool rc_service_delete (const char *runlevel, const char *service); + +/*! Save the arguments to find a running daemon + * @param service to save arguments for + * @param exec that we started + * @param name of the process (optional) + * @param pidfile of the process (optional) + * @param started if true, add the arguments otherwise remove existing matching arguments */ +bool rc_service_daemon_set (const char *service, const char *exec, + const char *name, const char *pidfile, + bool started); + +/*! Returns a description of what the service and/or option does. + * @param service to check + * @param option to check (if NULL, service description) + * @return a newly allocated pointer to the description */ +char *rc_service_description (const char *service, const char *option); + +/*! Checks if a service exists or not. + * @param service to check + * @return true if service exists, otherwise false */ +bool rc_service_exists (const char *service); + +/*! Checks if a service is in a runlevel + * @param service to check + * @param runlevel it should be in + * @return true if service is in the runlevel, otherwise false */ +bool rc_service_in_runlevel (const char *service, const char *runlevel); + +/*! Marks the service state + * @param service to mark + * @param state service should be in + * @return true if service state change was successful, otherwise false */ +bool rc_service_mark (const char *service, rc_service_state_t state); + +/*! Lists the extra commands a service has + * @param service to load the commands from + * @return NULL terminated string list of commands */ +char **rc_service_extra_commands (const char *service); + +/*! Check if the service is allowed to be hot/cold plugged + * @param service to check + * @return true if allowed, otherwise false */ +bool rc_service_plugable (const char *service); + +/*! Resolves a service name to its full path. + * @param service to check + * @return pointer to full path of service */ +char *rc_service_resolve (const char *service); + +/*! Schedule a service to be started when another service starts + * @param service that starts the scheduled service when started + * @param service_to_start service that will be started */ +bool rc_service_schedule_start (const char *service, + const char *service_to_start); +/*! Return a NULL terminated list of services that are scheduled to start + * when the given service has started + * @param service to check + * @return NULL terminated list of services scheduled to start */ +char **rc_services_scheduled_by (const char *service); + +/*! Clear the list of services scheduled to be started by this service + * @param service to clear + * @return true if no errors, otherwise false */ +bool rc_service_schedule_clear (const char *service); + +/*! Checks if a service in in a state + * @param service to check + * @return state of the service */ +rc_service_state_t rc_service_state (const char *service); + +/*! Start a service + * @param service to start + * @return pid of the service starting process */ +pid_t rc_service_start (const char *service); + +/*! Stop a service + * @param service to stop + * @return pid of service stopping process */ +pid_t rc_service_stop (const char *service); + +/*! Check if the service started the daemon + * @param service to check + * @param exec to check + * @param indx of the daemon (optional - 1st daemon, 2nd daemon, etc) + * @return true if started by this service, otherwise false */ +bool rc_service_started_daemon (const char *service, const char *exec, + int indx); + +/*! Return a saved value for a service + * @param service to check + * @param option to load + * @return saved value */ +char *rc_service_value_get (const char *service, const char *option); + +/*! Save a persistent value for a service + * @param service to save for + * @param option to save + * @param value of the option + * @return true if saved, otherwise false */ +bool rc_service_value_set (const char *service, const char *option, + const char *value); + +/*! List the services in a runlevel + * @param runlevel to list + * @return NULL terminated list of services */ +char **rc_services_in_runlevel (const char *runlevel); + +/*! List the services in a state + * @param state to list + * @return NULL terminated list of services */ +char **rc_services_in_state (rc_service_state_t state); + +/*! List the services shceduled to start when this one does + * @param service to check + * @return NULL terminated list of services */ +char **rc_services_scheduled (const char *service); + +/*! Checks that all daemons started with start-stop-daemon by the service + * are still running. + * @param service to check + * @return true if all daemons started are still running, otherwise false */ +bool rc_service_daemons_crashed (const char *service); + +/*! @name Dependency options + * These options can change the services found by the rc_get_depinfo and + * rc_get_depends functions. */ +/*! Trace provided services */ +#define RC_DEP_TRACE 0x01 +/*! Only use services added to runlevels */ +#define RC_DEP_STRICT 0x02 +/*! Runlevel is starting */ +#define RC_DEP_START 0x04 +/*! Runlevel is stopping */ +#define RC_DEP_STOP 0x08 + +/*! @name Dependencies + * We analyse each init script and cache the resultant dependency tree. + * This tree can be accessed using the below functions. */ + +#ifndef _IN_LIBRC +/* Handles to internal structures */ +typedef void *rc_depinfo_t; +#endif + +/*! Update the cached dependency tree if it's older than any init script, + * its configuration file or an external configuration file the init script + * has specified. + * @return true if successful, otherwise false */ +bool rc_deptree_update (void); + +/*! Check if the cached dependency tree is older than any init script, + * its configuration file or an external configuration file the init script + * has specified. + * @return true if it needs updating, otherwise false */ +bool rc_deptree_update_needed (void); + +/*! Load the cached dependency tree and return a pointer to it. + * This pointer should be freed with rc_deptree_free when done. + * @return pointer to the dependency tree */ +rc_depinfo_t *rc_deptree_load (void); + +/*! List the depend for the type of service + * @param deptree to search + * @param type to use (keywords, etc) + * @param service to check + * @return NULL terminated list of services in order */ +char **rc_deptree_depend (const rc_depinfo_t *deptree, + const char *type, const char *service); + +/*! List all the services in order that the given services have + * for the given types and options. + * @param deptree to search + * @param types to use (ineed, iuse, etc) + * @param services to check + * @param options to pass + * @return NULL terminated list of services in order */ +char **rc_deptree_depends (const rc_depinfo_t *deptree, + const char *const *types, + const char *const *services, const char *runlevel, + int options); + +/*! List all the services that should be stoppned and then started, in order, + * for the given runlevel, including sysinit and boot services where + * approriate. + * @param deptree to search + * @param runlevel to change into + * @param options to pass + * @return NULL terminated list of services in order */ +char **rc_deptree_order (const rc_depinfo_t *deptree, const char *runlevel, + int options); + +/*! Free a deptree and its information + * @param deptree to free */ +void rc_deptree_free (rc_depinfo_t *deptree); + +/*! @name Plugins + * For each plugin loaded we will call rc_plugin_hook with the below + * enum and either the runlevel name or service name. + * + * Plugins are called when rc does something. This does not indicate an + * end result and the plugin should use the above functions to query things + * like service status. + * + * The service hooks have extra ones - now and done. This is because after + * start_in we may start other services before we start the service in + * question. now shows we really will start the service now and done shows + * when we have done it as may start scheduled services at this point. */ +/*! Points at which a plugin can hook into RC */ +typedef enum +{ + RC_HOOK_RUNLEVEL_STOP_IN = 1, + RC_HOOK_RUNLEVEL_STOP_OUT = 4, + RC_HOOK_RUNLEVEL_START_IN = 5, + RC_HOOK_RUNLEVEL_START_OUT = 8, + /*! We send the abort if an init script requests we abort and drop + * into single user mode if system not fully booted */ + RC_HOOK_ABORT = 99, + RC_HOOK_SERVICE_STOP_IN = 101, + RC_HOOK_SERVICE_STOP_NOW = 102, + RC_HOOK_SERVICE_STOP_DONE = 103, + RC_HOOK_SERVICE_STOP_OUT = 104, + RC_HOOK_SERVICE_START_IN = 105, + RC_HOOK_SERVICE_START_NOW = 106, + RC_HOOK_SERVICE_START_DONE = 107, + RC_HOOK_SERVICE_START_OUT = 108 +} rc_hook_t; + +/*! Plugin entry point + * @param hook point + * @param name of runlevel or service + * @return 0 for success otherwise -1 */ +int rc_plugin_hook (rc_hook_t hook, const char *name); + +/*! Plugins should write FOO=BAR to this fd to set any environment + * variables they wish. Variables should be separated by NULLs. */ +extern FILE *rc_environ_fd; + +/*! @name Configuration + * These functions help to deal with shell based configuration files */ +/*! Return a NULL terminated list of non comment lines from a file. */ +char **rc_config_list (const char *file); + +/*! Return a NULL terminated list of key=value lines from a file. */ +char **rc_config_load (const char *file); + +/*! Return the value of the entry from a key=value list. */ +char *rc_config_value (char **list, const char *entry); + +/*! Check if a variable is a boolean and return it's value. + * If variable is not a boolean then we set errno to be ENOENT when it does + * not exist or EINVAL if it's not a boolean. + * @param variable to check + * @return true if it matches true, yes or 1, false if otherwise. */ +bool rc_yesno (const char *variable); + +/*! @name String List functions + * Handy functions for dealing with string arrays of char **. + * It's safe to assume that any function here that uses char ** is a string + * list that can be manipulated with the below functions. Every string list + * should be released with a call to rc_strlist_free. */ + +/*! Duplicate the item, add it to end of the list and return a pointer to it. + * @param list to add the item too + * @param item to add. + * @return pointer to newly added item */ +char *rc_strlist_add (char ***list, const char *item); + +/*! If the item does not exist in the list, duplicate it, add it to the + * list and then return a pointer to it. + * @param list to add the item too + * @param item to add. + * @return pointer to newly added item */ +char *rc_strlist_addu (char ***list, const char *item); + +/*! Duplicate the item, add it to the list at the point based on locale and + * then return a pointer to it. + * @param list to add the item too + * @param item to add. + * @return pointer to newly added item */ +char *rc_strlist_addsort (char ***list, const char *item); + +/*! Duplicate the item, add it to the list at the point based on C locale and + * then return a pointer to it. + * @param list to add the item too + * @param item to add. + * @return pointer to newly added item */ +char *rc_strlist_addsortc (char ***list, const char *item); + +/*! If the item does not exist in the list, duplicate it, add it to the + * list based on locale and then return a pointer to it. + * @param list to add the item too + * @param item to add. + * @return pointer to newly added item */ +char *rc_strlist_addsortu (char ***list, const char *item); + +/*! Free the item and remove it from the list. Return 0 on success otherwise -1. + * @param list to add the item too + * @param item to add. + * @return true on success, otherwise false */ +bool rc_strlist_delete (char ***list, const char *item); + +/*! Moves the contents of list2 onto list1, so list2 is effectively emptied. + * Returns a pointer to the last item on the new list. + * @param list1 to append to + * @param list2 to move from + * @return pointer to the last item on the list */ +char *rc_strlist_join (char ***list1, char **list2); + +/*! Reverses the contents of the list. + * @param list to reverse */ +void rc_strlist_reverse (char **list); + +/*! Frees each item on the list and the list itself. + * @param list to free */ +void rc_strlist_free (char **list); + +/*! Concatenate paths adding '/' if needed. The resultant pointer should be + * freed when finished with. + * @param path1 starting path + * @param paths NULL terminated list of paths to add + * @return pointer to the new path */ +char *rc_strcatpaths (const char *path1, const char *paths, ...) SENTINEL; + +/*! Find processes based on criteria. + * All of these are optional. + * pid overrides anything else. + * If both exec and cmd are given then we ignore exec. + * @param exec to check for + * @param cmd to check for + * @param uid to check for + * @param pid to check for + * @return NULL terminated list of pids */ +pid_t *rc_find_pids (const char *exec, const char *cmd, + uid_t uid, pid_t pid); + +#endif |