diff options
| author | Roy Marples <roy@marples.name> | 2007-12-14 12:24:16 +0000 | 
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2007-12-14 12:24:16 +0000 | 
| commit | a3db3bac6242ff29871161620d0449125b3262aa (patch) | |
| tree | a4b6d7f9cefb59dd5955a88a474d1484d82c2fb6 /src | |
| parent | b73bd04cf3f19b47480c85dd58e63eef5900fa3c (diff) | |
| download | openrc-a3db3bac6242ff29871161620d0449125b3262aa.tar.xz | |
Allow services to be in /usr/local/etc/init.d, but disallow them being added to the boot runlevel.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librc-depend.c | 2 | ||||
| -rw-r--r-- | src/librc.c | 51 | ||||
| -rw-r--r-- | src/rc-misc.h | 3 | ||||
| -rw-r--r-- | src/rc-status.c | 2 | ||||
| -rw-r--r-- | src/rc-update.c | 37 | 
5 files changed, 66 insertions, 29 deletions
diff --git a/src/librc-depend.c b/src/librc-depend.c index ee6c79b7..e870c73c 100644 --- a/src/librc-depend.c +++ b/src/librc-depend.c @@ -673,6 +673,8 @@ bool rc_deptree_update_needed (void)  	/* Quick test to see if anything we use has changed */  	if (! is_newer_than (RC_DEPTREE, RC_INITDIR) ||  		! is_newer_than (RC_DEPTREE, RC_CONFDIR) || +		! is_newer_than (RC_DEPTREE, RC_INITDIR_LOCAL) || +		! is_newer_than (RC_DEPTREE, RC_CONFDIR_LOCAL) ||  		! is_newer_than (RC_DEPTREE, "/etc/rc.conf"))  		return (true); diff --git a/src/librc.c b/src/librc.c index e429318b..61f91525 100644 --- a/src/librc.c +++ b/src/librc.c @@ -71,6 +71,7 @@ static char **ls_dir (const char *dir, int options)  	DIR *dp;  	struct dirent *d;  	char **list = NULL; +	struct stat buf;  	if ((dp = opendir (dir)) == NULL)   		return (NULL); @@ -79,11 +80,14 @@ static char **ls_dir (const char *dir, int options)  		if (d->d_name[0] != '.') {  			if (options & LS_INITD) {  				int l = strlen (d->d_name); -				char *init = rc_strcatpaths (RC_INITDIR, d->d_name, -											 (char *) NULL); -				bool ok = exists (init); -				free (init); -				if (! ok) + +				/* Check that our file really exists. +				 * This is important as a service maybe in a runlevel, but +				 * could also have been removed. */ +				char *file = rc_strcatpaths (dir, d->d_name, NULL); +				int ok = stat (file, &buf); +				free (file); +				if (ok != 0)  					continue;  				/* .sh files are not init scripts */ @@ -93,8 +97,6 @@ static char **ls_dir (const char *dir, int options)  					continue;  			}  			if (options & LS_DIR) { -				struct stat buf; -  				if (stat (d->d_name, &buf) == 0 && ! S_ISDIR (buf.st_mode))  					continue;  			} @@ -258,8 +260,15 @@ char *rc_service_resolve (const char *service)  		if (r > 0)  			return (xstrdup (buffer));  	} -  	snprintf (buffer, sizeof (buffer), RC_INITDIR "/%s", service); + +	/* So we don't exist in /etc/init.d - check /usr/local/etc/init.d */ +	if (stat (buffer, &buf) != 0) { +		snprintf (buffer, sizeof (buffer), RC_INITDIR_LOCAL "/%s", service); +		if (stat (buffer, &buf) != 0) +			return (NULL); +	} +  	return (xstrdup (buffer));  }  librc_hidden_def(rc_service_resolve) @@ -717,8 +726,16 @@ char **rc_services_in_runlevel (const char *runlevel)  	char *dir;  	char **list = NULL; -	if (! runlevel) -		return (ls_dir (RC_INITDIR, LS_INITD)); +	if (! runlevel) { +		int i; +		char **local = ls_dir (RC_INITDIR_LOCAL, LS_INITD); + +		list = ls_dir (RC_INITDIR, LS_INITD); +		STRLIST_FOREACH (local, dir, i) +			rc_strlist_addsortu (&list, dir); +		rc_strlist_free (local); +		return (list); +	}  	/* These special levels never contain any services */  	if (strcmp (runlevel, RC_LEVEL_SYSINIT) == 0 || @@ -785,6 +802,20 @@ bool rc_service_add (const char *runlevel, const char *service)  	}  	init = rc_service_resolve (service); + +	/* We need to ensure that only things in /etc/init.d are added +	 * to the boot runlevel */ +	if (strcmp (runlevel, RC_LEVEL_BOOT) == 0) { +		char *tmp = xstrdup (init); +		retval = (strcmp (dirname (tmp), RC_INITDIR) == 0); +		free (tmp); +		if (! retval) { +			free (init); +			errno = EPERM; +			return (false); +		} +	} +  	svc = xstrdup (service);  	file = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, basename (svc),  						   (char *) NULL); diff --git a/src/rc-misc.h b/src/rc-misc.h index bb3b33dc..985726d3 100644 --- a/src/rc-misc.h +++ b/src/rc-misc.h @@ -51,6 +51,9 @@  #define RC_INITDIR              "/etc/init.d"  #define RC_CONFDIR              "/etc/conf.d" +#define RC_INITDIR_LOCAL        "/usr/local/etc/init.d" +#define RC_CONFDIR_LOCAL        "/usr/local/etc/conf.d" +  #define RC_KSOFTLEVEL           RC_SVCDIR "/ksoftlevel"  #define RC_STARTING             RC_SVCDIR "/rc.starting"  #define RC_STOPPING             RC_SVCDIR "/rc.stopping" diff --git a/src/rc-status.c b/src/rc-status.c index dc515af7..535f438a 100644 --- a/src/rc-status.c +++ b/src/rc-status.c @@ -170,7 +170,7 @@ int rc_status (int argc, char **argv)  	/* Output the services in the order in which they would start */  	if (geteuid () == 0) -		deptree = _rc_deptree_load (); +		deptree = _rc_deptree_load (NULL);  	else  		deptree = rc_deptree_load (); diff --git a/src/rc-update.c b/src/rc-update.c index ddec0066..d5f2ba92 100644 --- a/src/rc-update.c +++ b/src/rc-update.c @@ -60,8 +60,6 @@ static ssize_t add (const char *runlevel, const char *service)  	if (! rc_service_exists (service))  		eerror ("%s: service `%s' does not exist", applet, service); -	else if (! rc_runlevel_exists (runlevel)) -		eerror ("%s: runlevel `%s' does not exist", applet, runlevel);  	else if (rc_service_in_runlevel (service, runlevel)) {  		ewarn ("%s: %s already installed in runlevel `%s'; skipping",  			   applet, service, runlevel); @@ -80,19 +78,18 @@ static ssize_t delete (const char *runlevel, const char *service)  {  	ssize_t retval = -1; -	if (rc_service_in_runlevel (service, runlevel))	{ -		if (rc_service_delete (runlevel, service)) { -			einfo ("%s removed from runlevel %s", service, runlevel); -			retval = 1; -		} else -			eerror ("%s: failed to remove service `%s' from runlevel `%s': %s", -					applet, service, runlevel, strerror (errno)); -	} else if (! rc_service_exists (service)) -		eerror ("%s: service `%s' does not exist", applet, service); -	else if (! rc_runlevel_exists (runlevel)) -		eerror ("%s: runlevel `%s' does not exist", applet, runlevel); -	else -		retval = 0; +	errno = 0; +	if (rc_service_delete (runlevel, service)) { +		einfo ("%s removed from runlevel %s", service, runlevel); +		return 1; +	} + +	if (errno == ENOENT) +		eerror ("%s: service `%s' is not in the runlevel `%s'", +				applet, service, runlevel); +	else  +		eerror ("%s: failed to remove service `%s' from runlevel `%s': %s", +				applet, service, runlevel, strerror (errno));  	return (retval);  } @@ -238,11 +235,10 @@ int rc_update (int argc, char **argv)  	} else {  		if (! service)  			eerror ("%s: no service specified", applet); -		else if (! rc_service_exists (service)) -			eerror ("%s: service `%s' does not exist", applet, service);  		else {  			ssize_t num_updated = 0;  			ssize_t (*actfunc)(const char *, const char *); +			size_t ret;  			if (action & DOADD) {  				actfunc = add; @@ -259,7 +255,12 @@ int rc_update (int argc, char **argv)  				eerrorx ("%s: no runlevels found", applet);  			STRLIST_FOREACH (runlevels, runlevel, i) { -				ssize_t ret = actfunc (runlevel, service); +				if (! rc_runlevel_exists (runlevel)) { +					eerror ("%s: runlevel `%s' does not exist", applet, runlevel); +					continue; +				} + +				ret = actfunc (runlevel, service);  				if (ret < 0)  					retval = EXIT_FAILURE;  				num_updated += ret;  | 
