diff options
| author | Roy Marples <roy@marples.name> | 2008-10-30 17:40:48 +0000 | 
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2008-10-30 17:40:48 +0000 | 
| commit | 20380d314421c25bec7076335eb34360bdc38719 (patch) | |
| tree | 64c202020b79d032ebff465c86627a1d88547db5 /src/rc | |
| parent | e1341e372bac3352035892a2931458faf98c38a0 (diff) | |
| download | openrc-20380d314421c25bec7076335eb34360bdc38719.tar.xz | |
Allow ~ and ~user to expand for chdir and chroot.
Diffstat (limited to 'src/rc')
| -rw-r--r-- | src/rc/start-stop-daemon.c | 86 | 
1 files changed, 72 insertions, 14 deletions
| diff --git a/src/rc/start-stop-daemon.c b/src/rc/start-stop-daemon.c index fd281a1d..6bb821c5 100644 --- a/src/rc/start-stop-daemon.c +++ b/src/rc/start-stop-daemon.c @@ -96,10 +96,10 @@ typedef struct scheduleitem  	TAILQ_ENTRY(scheduleitem) entries;  } SCHEDULEITEM;  TAILQ_HEAD(, scheduleitem) schedule; -static char **nav = NULL; +static char **nav;  extern const char *applet; -static char *changeuser = NULL; +static char *changeuser, *ch_root, *ch_dir;  extern char **environ; @@ -498,6 +498,45 @@ static void handle_signal(int sig)  	errno = serrno;  } +static char * +expand_home(const char *home, const char *path) +{ +	char *pat, *p, *nh; +	size_t len; +	struct passwd *pw; + +	if (!path || *path != '~') +		return xstrdup(path); + +	pat = xstrdup(path); +	if (pat[1] != '/' && pat[1] != '\0') { +		p = strchr(pat + 1, '/'); +		if (p) +			*p = '\0'; +		pw = getpwnam(pat + 1); +		if (pw) { +			home = pw->pw_dir; +			pat = p; +			if (pat) +				*pat = '/'; +		} else +			home = NULL; +	} else +		pat++; + +	if (!home) { +		free(pat); +		return xstrdup(path); +	} +	if (!pat) +		return xstrdup(home); + +	len = strlen(pat) + strlen(home) + 1; +	nh = xmalloc(len); +	snprintf(nh, len, "%s%s", home, pat); +	free(pat); +	return nh; +}  #include "_usage.h"  #define getoptstring "KN:R:Sbc:d:e:g:k:mn:op:s:tu:r:x:1:2:" getoptstring_COMMON @@ -582,8 +621,7 @@ int start_stop_daemon(int argc, char **argv)  	bool makepidfile = false;  	uid_t uid = 0;  	gid_t gid = 0; -	char *ch_root = NULL; -	char *ch_dir = NULL; +	char *home = NULL;  	int tid = 0;  	char *redirect_stderr = NULL;  	char *redirect_stdout = NULL; @@ -624,6 +662,14 @@ int start_stop_daemon(int argc, char **argv)  			eerror("%s: invalid nice level `%s' (SSD_NICELEVEL)",  				applet, tmp); +	/* Get our initial dir */ +	home = getenv("HOME"); +	if (!home) { +		pw = getpwuid(getuid()); +		if (pw) +			home = pw->pw_dir; +	} +  	while ((opt = getopt_long(argc, argv, getoptstring, longopts,  				  (int *) 0)) != -1)  		switch (opt) { @@ -633,7 +679,8 @@ int start_stop_daemon(int argc, char **argv)  		case 'N':  /* --nice */  			if (sscanf(optarg, "%d", &nicelevel) != 1) -				eerrorx("%s: invalid nice level `%s'", applet, optarg); +				eerrorx("%s: invalid nice level `%s'", +					applet, optarg);  			break;  		case 'R':  /* --retry <schedule>|<timeout> */ @@ -659,10 +706,12 @@ int start_stop_daemon(int argc, char **argv)  				else  					pw = getpwuid((uid_t) tid); -				if (! pw) -					eerrorx("%s: user `%s' not found", applet, tmp); +				if (!pw) +					eerrorx("%s: user `%s' not found", +						applet, tmp);  				uid = pw->pw_uid; -				if (! gid) +				home = pw->pw_dir; +				if (!gid)  					gid = pw->pw_gid;  				if (p) { @@ -672,8 +721,9 @@ int start_stop_daemon(int argc, char **argv)  					else  						gr = getgrgid((gid_t) tid); -					if (! gr) -						eerrorx("%s: group `%s' not found", +					if (!gr) +						eerrorx("%s: group `%s'" +							" not found",  							applet, tmp);  					gid = gr->gr_gid;  				} @@ -686,9 +736,10 @@ int start_stop_daemon(int argc, char **argv)  		case 'e': /* --env */  			if (putenv(optarg) == 0) { -				if (strncmp("HOME=", optarg, 5) == 0) +				if (strncmp("HOME=", optarg, 5) == 0) {  					sethome = true; -				else if (strncmp("USER=", optarg, 5) == 0) +					home = strchr(optarg, '=') + 1; +				} else if (strncmp("USER=", optarg, 5) == 0)  					setuser = true;  			}  			break; @@ -700,8 +751,9 @@ int start_stop_daemon(int argc, char **argv)  				else  					gr = getgrgid((gid_t) tid); -				if (! gr) -					eerrorx("%s: group `%s' not found", applet, optarg); +				if (!gr) +					eerrorx("%s: group `%s' not found", +						applet, optarg);  				gid = gr->gr_gid;  			}  			break; @@ -835,6 +887,12 @@ int start_stop_daemon(int argc, char **argv)  		exit(EXIT_SUCCESS);  	} +	/* Expand ~ */ +	if (ch_dir && *ch_dir == '~') +		ch_dir = expand_home(home, ch_dir); +	if (ch_root && *ch_root == '~') +		ch_root = expand_home(home, ch_root); +  	/* Validate that the binary exists if we are starting */  	if (*exec == '/' || *exec == '.') {  		/* Full or relative path */ | 
