Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Be able to handle rc scripts
Baptiste Daroussin committed 14 years ago
commit 4d5e7dbec1fe1e55018e3fe57c7b766021562bb0
parent 8adc4af
6 files changed +169 -1
modified libpkg/Makefile
@@ -24,7 +24,8 @@ SRCS= pkg.c \
		backup.c \
		fetch.c \
		packing.c \
-
		scripts.c
+
		scripts.c \
+
		rcscripts.c

CFLAGS+=	-std=c99
CFLAGS+=	-I${.CURDIR} \
modified libpkg/pkg.h
@@ -838,4 +838,7 @@ typedef int(*pkg_event_cb)(void *, struct pkg_event *);

void pkg_event_register(pkg_event_cb cb, void *data);

+
int pkg_stop_rc_scripts(struct pkg *);
+
int pkg_start_rc_scripts(struct pkg *);
+

#endif
modified libpkg/pkg_add.c
@@ -92,6 +92,7 @@ pkg_add(struct pkgdb *db, const char *path, int flags)
	char dpath[MAXPATHLEN + 1];
	const char *basedir;
	const char *ext;
+
	const char *handle_rc = NULL;
	int retcode = EPKG_OK;
	int ret;

@@ -217,6 +218,14 @@ pkg_add(struct pkgdb *db, const char *path, int flags)
	else
		pkg_script_run(pkg, PKG_SCRIPT_POST_INSTALL);

+
	/*
+
	 * start the different related services if the users do want that
+
	 * and that the service is running
+
	 */
+
	handle_rc = pkg_config("HANDLE_RC_SCRIPTS");
+
	if (handle_rc && ((strcmp(handle_rc, "yes") == 0) || (strcmp(handle_rc, "YES") == 0)))
+
		pkg_start_rc_scripts(pkg);
+

	cleanup_reg:
	if ((flags & PKG_ADD_UPGRADE) == 0)
		pkgdb_register_finale(db, retcode);
modified libpkg/pkg_config.c
@@ -21,6 +21,7 @@ static struct _config {
	{ "PKG_CACHEDIR", "/var/cache/pkg", NULL},
	{ "PORTSDIR", "/usr/ports", NULL },
	{ "PUBKEY", "/etc/ssl/pkg.pub", NULL },
+
	{ "HANDLE_RC_SCRIPTS", NULL, NULL},
	{ NULL, NULL, NULL}
};

modified libpkg/pkg_delete.c
@@ -17,6 +17,7 @@ pkg_delete(struct pkg *pkg, struct pkgdb *db, int flags)
{
	struct pkg_dep *rdep = NULL;
	int ret;
+
	const char *handle_rc = NULL;

	assert(pkg != NULL);
	assert(db != NULL);
@@ -53,6 +54,14 @@ pkg_delete(struct pkg *pkg, struct pkgdb *db, int flags)
			return (EPKG_REQUIRED);
	}

+
	/*
+
	 * stop the different related services if the users do want that
+
	 * and that the service is running
+
	 */
+
	handle_rc = pkg_config("HANDLE_RC_SCRIPTS");
+
	if (handle_rc && ((strcmp(handle_rc, "yes") == 0) || (strcmp(handle_rc, "YES") == 0)))
+
		pkg_stop_rc_scripts(pkg);
+

	if (flags & PKG_DELETE_UPGRADE) {
		if (( ret = pkg_script_run(pkg, PKG_SCRIPT_PRE_UPGRADE)) != EPKG_OK )
			return (ret);
added libpkg/rcscripts.c
@@ -0,0 +1,145 @@
+
#include <sys/param.h>
+
#include <sys/types.h>
+
#include <sys/wait.h>
+

+
#include <errno.h>
+
#include <fcntl.h>
+
#include <string.h>
+
#include <unistd.h>
+

+
#include "pkg.h"
+
#include "pkg_event.h"
+

+
static int rc_stop(const char *);
+
static int rc_start(const char *);
+

+
int
+
pkg_stop_rc_scripts(struct pkg *pkg)
+
{
+
	struct pkg_file *file = NULL;
+
	char rc_d_path[PATH_MAX + 1];
+
	const char *rcfile;
+
	size_t len = 0;
+
	int ret = 0;
+

+
	snprintf(rc_d_path, PATH_MAX, "%s/etc/rc.d/", pkg_get(pkg, PKG_PREFIX));
+
	len = strlen(rc_d_path);
+

+
	while (pkg_files(pkg, &file) == EPKG_OK) {
+
		if (strncmp(rc_d_path, pkg_file_path(file), len) == 0) {
+
			rcfile = pkg_file_path(file);
+
			rcfile += len;
+

+
			ret += rc_stop(rcfile);
+
		}
+
	}
+

+
	return (ret);
+
}
+

+
int
+
pkg_start_rc_scripts(struct pkg *pkg)
+
{
+
	struct pkg_file *file = NULL;
+
	char rc_d_path[PATH_MAX + 1];
+
	const char *rcfile;
+
	size_t len = 0;
+
	int ret = 0;
+

+
	snprintf(rc_d_path, PATH_MAX, "%s/etc/rc.d/", pkg_get(pkg, PKG_PREFIX));
+
	len = strlen(rc_d_path);
+

+
	while (pkg_files(pkg, &file) == EPKG_OK) {
+
		if (strncmp(rc_d_path, pkg_file_path(file), len) == 0) {
+
			rcfile = pkg_file_path(file);
+
			rcfile += len;
+

+
			ret += rc_start(rcfile);
+
		}
+
	}
+
	return (ret);
+
}
+

+
static int
+
rc_stop(const char *rc_file)
+
{
+
	int pstat;
+
	int fd;
+
	pid_t pid;
+

+
	switch ((pid = fork())) {
+
		case -1:
+
			return (-1);
+
		case 0:
+
			/* child */
+
			/*
+
			 * We don't need to see the out put
+
			 */
+
			fd = open("/dev/null", O_WRONLY);
+
			dup2(fd, STDERR_FILENO);
+
			dup2(fd, STDOUT_FILENO);
+
			execl("/usr/sbin/service", rc_file, "onestatus");
+
			_exit(1);
+
			/* NOT REACHED */
+
		default:
+
			/* parent */
+
			break;
+
	}
+

+
	while (waitpid(pid, &pstat, 0) == -1) {
+
		if (errno != EINTR)
+
			return (-1);
+
	}
+

+
	if (pstat != 0)
+
		return (0);
+

+
	switch ((pid = fork())) {
+
		case -1:
+
			return (-1);
+
		case 0:
+
			/* child */
+
			execl("/usr/sbin/service", rc_file, "forcestop");
+
			_exit(1);
+
			/* NOT REACHED */
+
		default:
+
			/* parent */
+
			break;
+
	}
+

+
	while (waitpid(pid, &pstat, 0) == -1) {
+
		if (errno != EINTR)
+
			return (-1);
+
	}
+

+
	return (pstat);
+
}
+

+
static int
+
rc_start(const char *rc_file)
+
{
+
	int pstat;
+
	pid_t pid;
+

+
	switch ((pid = fork())) {
+
		case -1:
+
			return (-1);
+
		case 0:
+
			/* child */
+
			execl("/usr/sbin/service", rc_file, "quietstart");
+
			_exit(1);
+
			/* NOT REACHED */
+
		default:
+
			/* parent */
+
			break;
+
	}
+

+
	while (waitpid(pid, &pstat, 0) == -1) {
+
		if (errno != EINTR)
+
			return (-1);
+
	}
+

+
	return (pstat);
+
}
+

+