Initial doxygen documentation for rc.h and einfo.h. Plus some header clean ups.
This commit is contained in:
		
							
								
								
									
										12
									
								
								src/Makefile
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/Makefile
									
									
									
									
									
								
							| @@ -75,13 +75,13 @@ RC_BINLINKS = einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \ | ||||
| 			  service_inactive service_wasinactive \ | ||||
| 			  service_coldplugged \ | ||||
| 			  is_runlevel_start is_runlevel_stop service_started_daemon \ | ||||
| 			  checkown fstabinfo mountinfo rc-depend | ||||
| 			  checkown fstabinfo mountinfo rc-depend \ | ||||
| 			  get_options save_options | ||||
| RC_SBINLINKS =  mark_service_starting mark_service_inactive \ | ||||
| 				mark_service_started \ | ||||
| 				mark_service_stopping mark_service_stopped \ | ||||
| 				mark_service_inactive mark_service_wasinactive \ | ||||
| 				mark_service_coldplugged \ | ||||
| 				get_options save_options rc-abort | ||||
| 				mark_service_started mark_service_stopping \ | ||||
| 				mark_service_stopped mark_service_inactive \ | ||||
| 				mark_service_wasinactive mark_service_coldplugged \ | ||||
| 				rc-abort | ||||
| BINLINKS = rc-status | ||||
| SBINLINKS = env-update rc-update runscript start-stop-daemon | ||||
| ALL_LINKS = $(sort $(BINLINKS) $(SBINLINKS) $(RC_BINLINKS) $(RC_SBINLINKS)) | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| /* | ||||
| /*! | ||||
|  * @file _usage.c | ||||
|  * @brief standardize help/usage output across all our programs | ||||
|  * @internal | ||||
|   | ||||
							
								
								
									
										129
									
								
								src/einfo.h
									
									
									
									
									
								
							
							
						
						
									
										129
									
								
								src/einfo.h
									
									
									
									
									
								
							| @@ -1,21 +1,31 @@ | ||||
| /* | ||||
|    rc.h  | ||||
|    Header file for external applications to get RC information. | ||||
|    Copyright 2007 Gentoo Foundation | ||||
|    Released under the GPLv2 | ||||
|    */ | ||||
| /*! | ||||
|  * @file einfo.h  | ||||
|  * @brief Describes how to interface with the einfo library | ||||
|  * | ||||
|  * Copyright 2007 Gentoo Foundation | ||||
|  * Released under the GPLv2 | ||||
|  */ | ||||
|  | ||||
| #ifndef __EINFO_H__ | ||||
| #define __EINFO_H__ | ||||
|  | ||||
| #define EINFO_PRINTF | ||||
| #define EINFO_XPRINTF | ||||
| #define EEND_PRINTF | ||||
|  | ||||
| #ifdef __GNUC__ | ||||
| #  define EINFO_PRINTF(_one, _two)  __attribute__ ((__format__ (__printf__, _one, _two))) | ||||
| #  define EINFO_XPRINTF(_one, _two)  __attribute__ ((__noreturn__, __format__ (__printf__, _one, _two))) | ||||
| #  undef EINFO_PRINTF | ||||
| #  undef EINFO_XPRINTF | ||||
| #  undef EEND_PRINTF | ||||
| #  define EINFO_PRINTF  __attribute__ ((__format__ (__printf__, 1, 2))) | ||||
| #  define EINFO_XPRINTF  __attribute__ ((__noreturn__, __format__ (__printf__, 1, 2))) | ||||
| #  define EEND_PRINTF  __attribute__ ((__format__ (__printf__, 2, 3))) | ||||
| #endif | ||||
|  | ||||
| #include <sys/types.h> | ||||
| #include <stdbool.h> | ||||
|  | ||||
| /*! @brief Color types to use */ | ||||
| typedef enum | ||||
| { | ||||
| 	ecolor_good, | ||||
| @@ -26,46 +36,83 @@ typedef enum | ||||
| 	ecolor_normal | ||||
| } einfo_color_t; | ||||
|  | ||||
| /* We work out if the terminal supports colour or not through the use | ||||
|    of the TERM env var. We cache the reslt in a static bool, so | ||||
|    subsequent calls are very fast. | ||||
|    The n suffix means that a newline is NOT appended to the string | ||||
|    The v suffix means that we only print it when RC_VERBOSE=yes | ||||
|    NOTE We use the v suffix here so we can add veinfo for va_list | ||||
|    in the future, but veinfo is used by shell scripts as they don't | ||||
|    have the va_list concept | ||||
|    */ | ||||
| /*! @brief Returns the ASCII code for the color */ | ||||
| const char *ecolor (einfo_color_t); | ||||
| void elog (int level, const char *fmt, ...) EINFO_PRINTF (2, 3); | ||||
| int einfon (const char *fmt, ...) EINFO_PRINTF (1, 2); | ||||
| int ewarnn (const char *fmt, ...) EINFO_PRINTF (1, 2); | ||||
| int eerrorn (const char *fmt, ...) EINFO_PRINTF (1, 2); | ||||
| int einfo (const char *fmt, ...) EINFO_PRINTF(1, 2); | ||||
| int ewarn (const char *fmt, ...) EINFO_PRINTF (1, 2); | ||||
| void ewarnx (const char *fmt, ...) EINFO_XPRINTF (1,2); | ||||
| int eerror (const char *fmt, ...) EINFO_PRINTF (1,2); | ||||
| void eerrorx (const char *fmt, ...) EINFO_XPRINTF (1,2); | ||||
| int ebegin (const char *fmt, ...) EINFO_PRINTF (1, 2); | ||||
| int eend (int retval, const char *fmt, ...) EINFO_PRINTF (2, 3); | ||||
| int ewend (int retval, const char *fmt, ...) EINFO_PRINTF (2, 3); | ||||
|  | ||||
| /*! @brief Writes to syslog. */ | ||||
| void elog (int level, const char *fmt, ...) EEND_PRINTF; | ||||
|  | ||||
| /*! | ||||
|  * @brief Display informational messages. | ||||
|  * | ||||
|  * The einfo family of functions display messages in a consistent manner | ||||
|  * across Gentoo applications. Basically they prefix the message with | ||||
|  * " * ". If the terminal can handle color then we color the * based on | ||||
|  * the command used. Otherwise we are identical to the printf function. | ||||
|  * | ||||
|  * - einfo  - green | ||||
|  * - ewarn  - yellow | ||||
|  * - eerror - red | ||||
|  * | ||||
|  * The n suffix denotes that no new line should be printed. | ||||
|  * The v suffix means only print if RC_VERBOSE is yes. | ||||
|  */ | ||||
| /*@{*/ | ||||
| int einfon (const char *fmt, ...) EINFO_PRINTF; | ||||
| int ewarnn (const char *fmt, ...) EINFO_PRINTF; | ||||
| int eerrorn (const char *fmt, ...) EINFO_PRINTF; | ||||
| int einfo (const char *fmt, ...) EINFO_PRINTF; | ||||
| int ewarn (const char *fmt, ...) EINFO_PRINTF; | ||||
| void ewarnx (const char *fmt, ...) EINFO_XPRINTF; | ||||
| int eerror (const char *fmt, ...) EINFO_PRINTF; | ||||
| void eerrorx (const char *fmt, ...) EINFO_XPRINTF; | ||||
|  | ||||
| int einfovn (const char *fmt, ...) EINFO_PRINTF; | ||||
| int ewarnvn (const char *fmt, ...) EINFO_PRINTF; | ||||
| int ebeginvn (const char *fmt, ...) EINFO_PRINTF; | ||||
| int eendvn (int retval, const char *fmt, ...) EEND_PRINTF; | ||||
| int ewendvn (int retval, const char *fmt, ...) EEND_PRINTF; | ||||
| int einfov (const char *fmt, ...) EINFO_PRINTF; | ||||
| int ewarnv (const char *fmt, ...) EINFO_PRINTF; | ||||
| /*@}*/ | ||||
|  | ||||
| /*! @ingroup ebegin | ||||
|  * @brief Display informational messages that may take some time. | ||||
|  * | ||||
|  * Similar to einfo, but we add ... to the end of the message */ | ||||
| /*@{*/ | ||||
| int ebeginv (const char *fmt, ...) EINFO_PRINTF; | ||||
| int ebegin (const char *fmt, ...) EINFO_PRINTF; | ||||
| /*@}*/ | ||||
|  | ||||
| /*! @ingroup eend | ||||
|  * @brief End an ebegin. | ||||
|  * | ||||
|  * If you ebegin, you should eend also. | ||||
|  * eend places [ ok ] or [ !! ] at the end of the terminal line depending on | ||||
|  * retval (0 or ok, anything else for !!) | ||||
|  * | ||||
|  * ebracket allows you to specifiy the position, color and message */ | ||||
| /*@{*/ | ||||
| int eend (int retval, const char *fmt, ...) EEND_PRINTF; | ||||
| int ewend (int retval, const char *fmt, ...) EEND_PRINTF; | ||||
| void ebracket (int col, einfo_color_t color, const char *msg); | ||||
|  | ||||
| int eendv (int retval, const char *fmt, ...) EEND_PRINTF; | ||||
| int ewendv (int retval, const char *fmt, ...) EEND_PRINTF; | ||||
| /*@}*/ | ||||
|  | ||||
| /*! @ingroup eindent | ||||
|  * @brief Indents the einfo lines. | ||||
|  * | ||||
|  * For each indent you should outdent when done */ | ||||
| /*@{*/ | ||||
| void eindent (void); | ||||
| void eoutdent (void); | ||||
|  | ||||
| int einfovn (const char *fmt, ...) EINFO_PRINTF (1, 2); | ||||
| int ewarnvn (const char *fmt, ...) EINFO_PRINTF (1, 2); | ||||
| int ebeginvn (const char *fmt, ...) EINFO_PRINTF (1, 2); | ||||
| int eendvn (int retval, const char *fmt, ...) EINFO_PRINTF (2, 3); | ||||
| int ewendvn (int retval, const char *fmt, ...) EINFO_PRINTF (2, 3); | ||||
| int einfov (const char *fmt, ...) EINFO_PRINTF (1, 2); | ||||
| int ewarnv (const char *fmt, ...) EINFO_PRINTF (1, 2); | ||||
| int ebeginv (const char *fmt, ...) EINFO_PRINTF (1, 2); | ||||
| int eendv (int retval, const char *fmt, ...) EINFO_PRINTF (2, 3); | ||||
| int ewendv (int retval, const char *fmt, ...) EINFO_PRINTF (2, 3); | ||||
| void eindentv (void); | ||||
| void eoutdentv (void); | ||||
|  | ||||
| /* Pointer to a string that is always prefixed to einfo/ewarn/error */ | ||||
| /*! @brief Prefix each einfo line with something */ | ||||
| void eprefix (const char *prefix); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -588,9 +588,10 @@ char **rc_make_env (void) | ||||
| 	bool has_net_fs_list = false; | ||||
| 	FILE *fp; | ||||
| 	char buffer[PATH_MAX]; | ||||
| 	char *runlevel = rc_get_runlevel (); | ||||
|  | ||||
| 	/* Don't trust environ for softlevel yet */ | ||||
| 	snprintf (buffer, PATH_MAX, "%s.%s", RC_CONFIG, rc_get_runlevel()); | ||||
| 	snprintf (buffer, PATH_MAX, "%s.%s", RC_CONFIG, runlevel); | ||||
| 	if (rc_exists (buffer)) | ||||
| 		config = rc_get_config (buffer); | ||||
| 	else | ||||
| @@ -632,10 +633,9 @@ char **rc_make_env (void) | ||||
|  | ||||
| 	rc_strlist_add (&env, "RC_BOOTLEVEL=" RC_LEVEL_BOOT); | ||||
|  | ||||
| 	p = rc_get_runlevel (); | ||||
| 	i = strlen ("RC_SOFTLEVEL=") + strlen (p) + 1; | ||||
| 	i = strlen ("RC_SOFTLEVEL=") + strlen (runlevel) + 1; | ||||
| 	line = rc_xmalloc (sizeof (char *) * i); | ||||
| 	snprintf (line, i, "RC_SOFTLEVEL=%s", p); | ||||
| 	snprintf (line, i, "RC_SOFTLEVEL=%s", runlevel); | ||||
| 	rc_strlist_add (&env, line); | ||||
| 	free (line); | ||||
|  | ||||
| @@ -717,6 +717,7 @@ char **rc_make_env (void) | ||||
| 		free (line); | ||||
| 	} | ||||
|  | ||||
| 	free (runlevel); | ||||
| 	return (env); | ||||
| } | ||||
| librc_hidden_def(rc_make_env) | ||||
|   | ||||
| @@ -135,7 +135,7 @@ int rc_strlist_delete (char ***list, const char *item) | ||||
| } | ||||
| librc_hidden_def(rc_strlist_delete) | ||||
|  | ||||
| int rc_strlist_join (char ***list1, char **list2) | ||||
| char *rc_strlist_join (char ***list1, char **list2) | ||||
| { | ||||
| 	char **lst1 = *list1; | ||||
| 	char **newlist; | ||||
| @@ -143,7 +143,7 @@ int rc_strlist_join (char ***list1, char **list2) | ||||
| 	int j = 0; | ||||
|  | ||||
| 	if (! list2) | ||||
| 		return (0); | ||||
| 		return (NULL); | ||||
|  | ||||
| 	while (lst1 && lst1[i]) | ||||
| 		i++; | ||||
| @@ -164,7 +164,7 @@ int rc_strlist_join (char ***list1, char **list2) | ||||
| 	newlist[i] = NULL; | ||||
|  | ||||
| 	*list1 = newlist; | ||||
| 	return (0); | ||||
| 	return (newlist[i == 0 ? 0 : i - 1]); | ||||
| } | ||||
| librc_hidden_def(rc_strlist_join) | ||||
|  | ||||
|   | ||||
							
								
								
									
										41
									
								
								src/librc.c
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								src/librc.c
									
									
									
									
									
								
							| @@ -65,24 +65,23 @@ librc_hidden_def(rc_get_runlevels) | ||||
| char *rc_get_runlevel (void) | ||||
| { | ||||
| 	FILE *fp; | ||||
| 	static char buffer[PATH_MAX]; | ||||
| 	char buffer[RC_LINEBUFFER]; | ||||
| 	char *runlevel = NULL; | ||||
|  | ||||
| 	if (! (fp = fopen (SOFTLEVEL, "r"))) { | ||||
| 		snprintf (buffer, sizeof (buffer), "sysinit"); | ||||
| 		return (buffer); | ||||
| 	} | ||||
|  | ||||
| 	if (fgets (buffer, PATH_MAX, fp)) { | ||||
| 		int i = strlen (buffer) - 1; | ||||
| 		if (buffer[i] == '\n') | ||||
| 			buffer[i] = 0; | ||||
| 	if ((fp = fopen (SOFTLEVEL, "r"))) { | ||||
| 		if (fgets (buffer, PATH_MAX, fp)) { | ||||
| 			int i = strlen (buffer) - 1; | ||||
| 			if (buffer[i] == '\n') | ||||
| 				buffer[i] = 0; | ||||
| 			runlevel = rc_xstrdup (buffer); | ||||
| 		} | ||||
| 		fclose (fp); | ||||
| 		return (buffer); | ||||
| 	} | ||||
|  | ||||
| 	fclose (fp); | ||||
| 	snprintf (buffer, sizeof (buffer), "sysinit"); | ||||
| 	return (buffer); | ||||
| 	if (! runlevel) | ||||
| 		runlevel = rc_xstrdup (RC_LEVEL_SYSINIT); | ||||
|  | ||||
| 	return (runlevel); | ||||
| } | ||||
| librc_hidden_def(rc_get_runlevel) | ||||
|  | ||||
| @@ -452,31 +451,27 @@ bool rc_service_state (const char *service, const rc_service_state_t state) | ||||
| } | ||||
| librc_hidden_def(rc_service_state) | ||||
|  | ||||
| bool rc_get_service_option (const char *service, const char *option, | ||||
| 							char *value) | ||||
| char *rc_get_service_option (const char *service, const char *option) | ||||
| { | ||||
| 	FILE *fp; | ||||
| 	char buffer[RC_LINEBUFFER]; | ||||
| 	char *file = rc_strcatpaths (RC_SVCDIR, "options", service, option, | ||||
| 								 (char *) NULL); | ||||
| 	bool retval = false; | ||||
| 	char *value = NULL; | ||||
|  | ||||
| 	if (rc_exists (file)) { | ||||
| 		if ((fp = fopen (file, "r")) == NULL) | ||||
| 			eerror ("fopen `%s': %s", file, strerror (errno)); | ||||
| 		else { | ||||
| 			memset (buffer, 0, sizeof (buffer)); | ||||
| 			while (fgets (buffer, RC_LINEBUFFER, fp)) { | ||||
| 				memcpy (value, buffer, strlen (buffer)); | ||||
| 				value += strlen (buffer); | ||||
| 			} | ||||
| 			if (fgets (buffer, RC_LINEBUFFER, fp))  | ||||
| 				value = rc_xstrdup (buffer); | ||||
| 			fclose (fp); | ||||
| 			retval = true; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	free (file); | ||||
| 	return (retval); | ||||
| 	return (value); | ||||
| } | ||||
| librc_hidden_def(rc_get_service_option) | ||||
|  | ||||
|   | ||||
| @@ -117,8 +117,11 @@ int rc_status (int argc, char **argv) | ||||
| 	while (optind < argc) | ||||
| 		rc_strlist_add (&levels, argv[optind++]); | ||||
|  | ||||
| 	if (! levels) | ||||
| 		rc_strlist_add (&levels, rc_get_runlevel ()); | ||||
| 	if (! levels) { | ||||
| 		level = rc_get_runlevel (); | ||||
| 		rc_strlist_add (&levels, level); | ||||
| 		free (level); | ||||
| 	} | ||||
|  | ||||
| 	STRLIST_FOREACH (levels, level, i) { | ||||
| 		print_level (level); | ||||
|   | ||||
| @@ -208,8 +208,11 @@ int rc_update (int argc, char **argv) | ||||
| 			eerror ("%s: service `%s' does not exist", applet, service); | ||||
| 		else { | ||||
| 			retval = EXIT_SUCCESS; | ||||
| 			if (! runlevels) | ||||
| 				rc_strlist_add (&runlevels, rc_get_runlevel ());	 | ||||
| 			if (! runlevels) { | ||||
| 				runlevel = rc_get_runlevel (); | ||||
| 				rc_strlist_add (&runlevels, runlevel); | ||||
| 				free (runlevel); | ||||
| 			} | ||||
| 			STRLIST_FOREACH (runlevels, runlevel, i) { | ||||
| 				if (action & DOADD) { | ||||
| 					if (! add (runlevel, service)) | ||||
|   | ||||
							
								
								
									
										11
									
								
								src/rc.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/rc.c
									
									
									
									
									
								
							| @@ -359,11 +359,12 @@ static int do_options (int argc, char **argv) | ||||
| 		eerrorx ("%s: no option specified", applet); | ||||
|  | ||||
| 	if (strcmp (applet, "get_options") == 0) { | ||||
| 		char buffer[1024]; | ||||
| 		memset (buffer, 0, 1024); | ||||
| 		ok = rc_get_service_option (service, argv[0], buffer); | ||||
| 		if (ok) | ||||
| 			printf ("%s", buffer); | ||||
| 		char *option = rc_get_service_option (service, argv[0]); | ||||
| 		if (option) { | ||||
| 			printf ("%s", option); | ||||
| 			free (option); | ||||
| 			ok = true; | ||||
| 		} | ||||
| 	} else if (strcmp (applet, "save_options") == 0) | ||||
| 		ok = rc_set_service_option (service, argv[0], argv[1]); | ||||
| 	else | ||||
|   | ||||
							
								
								
									
										386
									
								
								src/rc.h
									
									
									
									
									
								
							
							
						
						
									
										386
									
								
								src/rc.h
									
									
									
									
									
								
							| @@ -1,32 +1,45 @@ | ||||
| /* | ||||
|    rc.h  | ||||
|    Header file for external applications to get RC information. | ||||
|    Copyright 2007 Gentoo Foundation | ||||
|    Released under the GPLv2 | ||||
|    */ | ||||
| /*! | ||||
|  * @file rc.h  | ||||
|  * @brief Describes how to interface with the RC library | ||||
|  * @internal | ||||
|  * | ||||
|  * Copyright 2007 Gentoo Foundation | ||||
|  * Released under the GPLv2 | ||||
|  */ | ||||
|  | ||||
| #ifndef __RC_H__ | ||||
| #define __RC_H__ | ||||
|  | ||||
| #define SENTINEL | ||||
| #ifdef __GNUC__ | ||||
| #  define GCC_VERSION (__GNUC__ * 1000 + __GNUC__MINOR ) | ||||
| #  define GCC_VERSION (__GNUC__ * 1000 + __GNUC__MINOR) | ||||
| #  if (GCC_VERSION >= 3005) | ||||
| #    undef SENTINEL | ||||
| #    define SENTINEL __attribute__ ((__sentinel__)) | ||||
| #  endif | ||||
| #endif | ||||
| #ifndef SENTINEL | ||||
| #  define SENTINEL | ||||
| #endif | ||||
|  | ||||
| #include <sys/types.h> | ||||
| #include <stdbool.h> | ||||
| #include <stdio.h> | ||||
|  | ||||
| /* Special level names */ | ||||
| /*! @name Reserved runlevel names */ | ||||
| #define RC_LEVEL_SYSINIT    "sysinit" | ||||
| #define RC_LEVEL_SINGLE     "single" | ||||
| #define RC_LEVEL_SHUTDOWN   "shutdown" | ||||
| #define RC_LEVEL_REBOOT     "reboot" | ||||
|  | ||||
| /*! @name rc_ls_dir options */ | ||||
| /*! Ensure that an init.d service exists for each file returned */ | ||||
| #define RC_LS_INITD	0x01 | ||||
|  | ||||
| /*! @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 | ||||
| { | ||||
| 	rc_service_started, | ||||
| @@ -41,114 +54,272 @@ typedef enum | ||||
| 	rc_service_crashed | ||||
| } rc_service_state_t; | ||||
|  | ||||
| /*! Resolves a service name to its full path. | ||||
|  * @param service to check | ||||
|  * @return pointer to full path of service */ | ||||
| char *rc_resolve_service (const char *service); | ||||
| /*! 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); | ||||
|  | ||||
| /*! Lists the extra options a service has | ||||
|  * @param service to load the options from | ||||
|  * @return NULL terminated string list of options */ | ||||
| char **rc_service_options (const char *service); | ||||
|  | ||||
| /*! 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 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); | ||||
|  | ||||
| /*! Checks if a service in in a state | ||||
|  * @param service to check | ||||
|  * @param state service should be in | ||||
|  * @return true if service is in the requested state, otherwise false */ | ||||
| bool rc_service_state (const char *service, rc_service_state_t state); | ||||
|  | ||||
| /*! 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_mark_service (const char *service, rc_service_state_t state); | ||||
|  | ||||
| /*! Stop a service | ||||
|  * @param service to stop | ||||
|  * @return pid of service stopping process */ | ||||
| pid_t rc_stop_service (const char *service); | ||||
|  | ||||
| /*! Start a service | ||||
|  * @param service to start | ||||
|  * @return pid of the service starting process */ | ||||
| pid_t rc_start_service (const char *service); | ||||
|  | ||||
| /*! Wait for a process to finish | ||||
|  * @param pid to wait for | ||||
|  * @return exit status of the process */ | ||||
| int rc_waitpid (pid_t pid);  | ||||
|  | ||||
| /*! 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 */ | ||||
| void rc_schedule_start_service (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 */ | ||||
| void rc_schedule_clear (const char *service); | ||||
|  | ||||
| /*! Wait for a service to finish | ||||
|  * @param service to wait for | ||||
|  * @return true if service finished before timeout, otherwise false */ | ||||
| bool rc_wait_service (const char *service); | ||||
| bool rc_get_service_option (const char *service, const char *option, | ||||
| 							char *value); | ||||
|  | ||||
| /*! Return a saved value for a service | ||||
|  * @param service to check | ||||
|  * @param option to load | ||||
|  * @return saved value */ | ||||
| char *rc_get_service_option (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_set_service_option (const char *service, const char *option, | ||||
| 							const char *value); | ||||
| /*! 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 */ | ||||
| void rc_set_service_daemon (const char *service, const char *exec, | ||||
| 							const char *name, const char *pidfile, | ||||
| 							bool started); | ||||
| /*! 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); | ||||
|  | ||||
| /*! Check if the service is allowed to be hot/cold plugged | ||||
|  * @param service to check | ||||
|  * @return true if allowed, otherwise false */ | ||||
| bool rc_allow_plug (char *service); | ||||
|  | ||||
| /*! Return the current runlevel. | ||||
|  * @return the current runlevel */ | ||||
| char *rc_get_runlevel (void); | ||||
| /*! Set the runlevel. | ||||
|  * This just changes the stored runlevel and does not start or stop any services. | ||||
|  * @param runlevel to store */ | ||||
| void rc_set_runlevel (const char *runlevel); | ||||
|  | ||||
| /*! 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_get_runlevels (void); | ||||
|  | ||||
| /*! 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); | ||||
|  | ||||
| /*! 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); | ||||
| /*! 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); | ||||
|  | ||||
| /* Find pids based on criteria - free the pointer returned after use */ | ||||
| /*! 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); | ||||
| /* Checks that all daemons started with start-stop-daemon by the service | ||||
|    are still running. If so, return false otherwise true. | ||||
|    You should check that the service has been started before calling this. */ | ||||
| /*! 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); | ||||
|  | ||||
| /* Dependency tree structs and functions. */ | ||||
| /*! @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 structures and functions. */ | ||||
| /*! Singly linked list of dependency types that list the services the | ||||
|  * type is for */ | ||||
| typedef struct rc_deptype | ||||
| { | ||||
| 	/*! ineed, iuse, iafter, etc */ | ||||
| 	char *type; | ||||
| 	/*! NULL terminated list of services */ | ||||
| 	char **services; | ||||
| 	/*! Next dependency type */ | ||||
| 	struct rc_deptype *next; | ||||
| } rc_deptype_t; | ||||
|  | ||||
| /*! Singly linked list of services and their dependencies */ | ||||
| typedef struct rc_depinfo | ||||
| { | ||||
| 	/*! Name of service */ | ||||
| 	char *service; | ||||
| 	/*! Dependencies */ | ||||
| 	rc_deptype_t *depends; | ||||
| 	/*! Next service dependency type */ | ||||
| 	struct rc_depinfo *next; | ||||
| } rc_depinfo_t; | ||||
|  | ||||
|  | ||||
| /* Options for rc_dep_depends and rc_order_services. | ||||
|    When changing runlevels, you should use RC_DEP_START and RC_DEP_STOP for | ||||
|    the start and stop lists as we tweak the provided services for this. */ | ||||
| #define RC_DEP_TRACE    0x01 | ||||
| #define RC_DEP_STRICT   0x02 | ||||
| #define RC_DEP_START    0x04 | ||||
| #define RC_DEP_STOP     0x08 | ||||
|  | ||||
| /*! 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. | ||||
|  * @param force an update | ||||
|  * @return 0 if successful, otherwise -1 */ | ||||
| int rc_update_deptree (bool force); | ||||
| /*! Load the cached dependency tree and return a pointer to it. | ||||
|  * This pointer should be freed with rc_free_deptree when done. | ||||
|  * @return pointer to the dependency tree */ | ||||
| rc_depinfo_t *rc_load_deptree (void); | ||||
| /*! Get a services depedency information from a loaded tree | ||||
|  * @param deptree to search | ||||
|  * @param service to find | ||||
|  * @return service dependency information */ | ||||
| rc_depinfo_t *rc_get_depinfo (rc_depinfo_t *deptree, const char *service); | ||||
| /*! Get a depenency type from the service dependency information | ||||
|  * @param depinfo service dependency to search | ||||
|  * @param type to find | ||||
|  * @return service dependency type information */ | ||||
| rc_deptype_t *rc_get_deptype (rc_depinfo_t *depinfo, const char *type); | ||||
| char **rc_get_depends (rc_depinfo_t *deptree, char **types, | ||||
| 					   char **services, const char *runlevel, int options); | ||||
| /* List all the services that should be started, in order, the the | ||||
|    given runlevel, including sysinit and boot services where | ||||
|    approriate. | ||||
|    If reboot, shutdown or single are given then we list all the services | ||||
|    we that we need to shutdown in order. */ | ||||
| /*! 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_order_services (rc_depinfo_t *deptree, const char *runlevel, | ||||
| 						  int options); | ||||
|  | ||||
| /*! Free a deptree and its information | ||||
|  * @param deptree to free */ | ||||
| void rc_free_deptree (rc_depinfo_t *deptree); | ||||
|  | ||||
| /* Plugin handler | ||||
|    For each plugin loaded we will call it's _name_hook with the below | ||||
|    enum and either the runlevel name or service name. For example | ||||
|    int _splash_hook (rc_hook_t hook, const char *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. */ | ||||
| /*! @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 reserved a few numbers if we need rc_runlevel_stop_now and done */ | ||||
| 	rc_hook_abort = 99, | ||||
| 	/* We send the abort if an init script requests we abort and drop | ||||
| 	/*! 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, | ||||
| 	rc_hook_service_stop_done, | ||||
| @@ -159,53 +330,146 @@ typedef enum | ||||
| 	rc_hook_service_start_out | ||||
| } rc_hook_t; | ||||
|  | ||||
| /* Plugins should write FOO=BAR to this fd to set any environment variables | ||||
|  * they wish. At this time we only support the setting of one env var. */ | ||||
| /*! 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; | ||||
|  | ||||
| /* RC utility functions. | ||||
|    Although not directly related to RC in general, they are used by RC | ||||
|    itself and the supporting applications. */ | ||||
| /*! @name Memory Allocation | ||||
|  * Ensure that if we cannot allocate the memory then we exit */ | ||||
| /*@{*/ | ||||
| /*! Allocate a block of memory | ||||
|  * @param size of memory to allocate | ||||
|  * @return pointer to memory */ | ||||
| void *rc_xmalloc (size_t size); | ||||
| /*! Re-size a block of memory | ||||
|  * @param ptr to the block of memory to re-size | ||||
|  * @param size memory should be | ||||
|  * @return pointer to memory block */ | ||||
| void *rc_xrealloc (void *ptr, size_t size); | ||||
| /*! Duplicate a NULL terminated string | ||||
|  * @param str to duplicate | ||||
|  * @return pointer to the new string */ | ||||
| char *rc_xstrdup (const char *str); | ||||
| /*@}*/ | ||||
|  | ||||
| /* Concat paths adding '/' if needed. */ | ||||
| /*! @name Utility | ||||
|  * Although not RC specific functions, they are used by the supporting | ||||
|  * applications */ | ||||
| /*! 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; | ||||
|  | ||||
| /*! Check if an environment variable matches the given value | ||||
|  * @param variable to check | ||||
|  * @param value it should be | ||||
|  * @return true if it matches */ | ||||
| bool rc_is_env (const char *variable, const char *value); | ||||
| /*! Check if the file exists or not | ||||
|  * @param pathname to check | ||||
|  * @return true if it exists, otherwise false */ | ||||
| bool rc_exists (const char *pathname); | ||||
| /*! Check if the file is a real file | ||||
|  * @param pathname to check | ||||
|  * @return true if it's a real file, otherwise false */ | ||||
| bool rc_is_file (const char *pathname); | ||||
| /*! Check if the file is a symbolic link or not | ||||
|  * @param pathname to check | ||||
|  * @return true if it's a symbolic link, otherwise false */ | ||||
| bool rc_is_link (const char *pathname); | ||||
| /*! Check if the file is a directory or not | ||||
|  * @param pathname to check | ||||
|  * @return true if it's a directory, otherwise false */ | ||||
| bool rc_is_dir (const char *pathname); | ||||
| /*! Check if the file is marked executable or not | ||||
|  * @param pathname to check | ||||
|  * @return true if it's marked executable, otherwise false */ | ||||
| bool rc_is_exec (const char *pathname); | ||||
|  | ||||
| #define RC_LS_INITD	0x01 | ||||
| /*! Return a NULL terminted sorted list of the contents of the directory | ||||
|  * @param dir to list | ||||
|  * @param options any options to apply | ||||
|  * @return NULL terminated list */ | ||||
| char **rc_ls_dir (const char *dir, int options); | ||||
|  | ||||
| /*! Remove a directory | ||||
|  * @param pathname to remove | ||||
|  * @param top remove the top level directory too | ||||
|  * @return true if successful, otherwise false */ | ||||
| bool rc_rm_dir (const char *pathname, bool top); | ||||
|  | ||||
| /* Config file functions */ | ||||
| /*! @name Configuration */ | ||||
| /*! Return a NULL terminated list of non comment lines from a file. */ | ||||
| char **rc_get_list (const char *file); | ||||
| /*! Return a NULL terminated list of key=value lines from a file. */ | ||||
| char **rc_get_config (const char *file); | ||||
| /*! Return the value of the entry from a key=value list. */ | ||||
| char *rc_get_config_entry (char **list, const char *entry); | ||||
|  | ||||
| /* Make an environment list which filters out all unwanted values | ||||
|    and loads it up with our RC config */ | ||||
| /*! Return a NULL terminated string list of variables allowed through | ||||
|  * from the current environemnt. */ | ||||
| char **rc_filter_env (void); | ||||
| /*! Return a NULL terminated string list of enviroment variables made from | ||||
|  * our configuration files. */ | ||||
| char **rc_make_env (void); | ||||
|  | ||||
| /* Handy functions for dealing with string arrays of char ** */ | ||||
| /*! @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 0 on success, otherwise -1 */ | ||||
| int rc_strlist_delete (char ***list, const char *item); | ||||
| /* join moves items from list2 to list1, so list2 is empty | ||||
|  * on return. It still needs to be freed though. */ | ||||
| int rc_strlist_join (char ***list1, char **list2); | ||||
| /*! 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); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -307,6 +307,7 @@ static void cleanup (void) | ||||
| 	free (applet); | ||||
| 	free (prefix); | ||||
| 	free (service); | ||||
| 	free (softlevel); | ||||
| } | ||||
|  | ||||
| static int write_prefix (const char *buffer, size_t bytes, bool *prefixed) { | ||||
| @@ -1029,7 +1030,7 @@ int runscript (int argc, char **argv) | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	if ((softlevel = getenv ("RC_SOFTLEVEL")) == NULL) { | ||||
| 	if ((softlevel = rc_xstrdup (getenv ("RC_SOFTLEVEL"))) == NULL) { | ||||
| 		/* Ensure our environment is pure | ||||
| 		   Also, add our configuration to it */ | ||||
| 		tmplist = rc_make_env(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user