Git-Url:
http://git.frugalware.org/gitweb/gitweb.cgi?p=pacman-g2.git;a=commitdiff;h=9039fa77f873a899e88335ab181192614c7c38ba
commit 9039fa77f873a899e88335ab181192614c7c38ba
Author: Miklos Vajna <[EMAIL PROTECTED]>
Date: Wed Dec 26 03:55:41 2007 +0100
_pacman_runhook(): initial support for libpacman hooks
diff --git a/lib/libpacman/handle.c b/lib/libpacman/handle.c
index 750e5a6..7967dc6 100644
--- a/lib/libpacman/handle.c
+++ b/lib/libpacman/handle.c
@@ -83,6 +83,7 @@ pmhandle_t *_pacman_handle_new()
handle->dbpath = strdup(PM_DBPATH);
handle->cachedir = strdup(PM_CACHEDIR);
+ handle->hooksdir = strdup(PM_HOOKSDIR);
handle->language = setlocale(LC_ALL, NULL);
@@ -108,6 +109,7 @@ int _pacman_handle_free(pmhandle_t *handle)
FREE(handle->root);
FREE(handle->dbpath);
FREE(handle->cachedir);
+ FREE(handle->hooksdir);
FREE(handle->logfile);
FREE(handle->proxyhost);
FREE(handle->xfercommand);
@@ -143,6 +145,13 @@ int _pacman_handle_set_option(pmhandle_t *handle, unsigned
char val, unsigned lo
handle->cachedir = strdup((data && strlen((char *)data) != 0) ? (char *)data :
PM_CACHEDIR);
_pacman_log(PM_LOG_FLOW2, _("PM_OPT_CACHEDIR set to '%s'"), handle->cachedir);
break;
+ case PM_OPT_HOOKSDIR:
+ if(handle->hooksdir) {
+ FREE(handle->hooksdir);
+ }
+ handle->hooksdir = strdup((data && strlen((char *)data)
!= 0) ? (char *)data : PM_HOOKSDIR);
+ _pacman_log(PM_LOG_FLOW2, _("PM_OPT_HOOKSDIR set to
'%s'"), handle->hooksdir);
+ break;
case PM_OPT_LOGFILE:
if((char *)data == NULL || handle->uid != 0) {
return(0);
@@ -337,6 +346,7 @@ int _pacman_handle_get_option(pmhandle_t *handle, unsigned
char val, long *data)
case PM_OPT_ROOT: *data = (long)handle->root; break;
case PM_OPT_DBPATH: *data = (long)handle->dbpath; break;
case PM_OPT_CACHEDIR: *data = (long)handle->cachedir; break;
+ case PM_OPT_HOOKSDIR: *data = (long)handle->hooksdir; break;
case PM_OPT_LOCALDB: *data = (long)handle->db_local; break;
case PM_OPT_SYNCDB: *data = (long)handle->dbs_sync; break;
case PM_OPT_LOGFILE: *data = (long)handle->logfile; break;
diff --git a/lib/libpacman/handle.h b/lib/libpacman/handle.h
index fa83a19..6713fb9 100644
--- a/lib/libpacman/handle.h
+++ b/lib/libpacman/handle.h
@@ -44,6 +44,7 @@ typedef struct __pmhandle_t {
char *dbpath;
char *cachedir;
char *logfile;
+ char *hooksdir;
pmlist_t *noupgrade; /* List of strings */
pmlist_t *noextract; /* List of strings */
pmlist_t *ignorepkg; /* List of strings */
diff --git a/lib/libpacman/pacman.h b/lib/libpacman/pacman.h
index 531e90b..758a88b 100644
--- a/lib/libpacman/pacman.h
+++ b/lib/libpacman/pacman.h
@@ -36,6 +36,7 @@ extern "C" {
#define PM_DBPATH "var/lib/pacman"
#define PM_CACHEDIR "var/cache/pacman/pkg"
#define PM_LOCK "/tmp/pacman-g2.lck"
+#define PM_HOOKSDIR "etc/pacman-g2/hooks"
#define PM_EXT_PKG ".fpm"
@@ -119,7 +120,8 @@ enum {
PM_OPT_MAXTRIES,
PM_OPT_OLDDELAY,
PM_OPT_DLREMAIN,
- PM_OPT_DLHOWMANY
+ PM_OPT_DLHOWMANY,
+ PM_OPT_HOOKSDIR
};
int pacman_set_option(unsigned char parm, unsigned long data);
diff --git a/lib/libpacman/sync.c b/lib/libpacman/sync.c
index bbcc3ff..f00344e 100644
--- a/lib/libpacman/sync.c
+++ b/lib/libpacman/sync.c
@@ -1083,6 +1083,10 @@ int _pacman_sync_commit(pmtrans_t *trans, pmdb_t
*db_local, pmlist_t **data)
unlink(i->data);
}
}
+
+ if(handle->sysupgrade) {
+ _pacman_runhook(handle->root, handle->hooksdir,
"post_sysupgrade", trans);
+ }
return(0);
error:
diff --git a/lib/libpacman/util.c b/lib/libpacman/util.c
index 0ae1760..c8331b1 100644
--- a/lib/libpacman/util.c
+++ b/lib/libpacman/util.c
@@ -537,6 +537,112 @@ cleanup:
return(retval);
}
+int _pacman_runhook(char *root, char *hookdir, char *hookname, pmtrans_t
*trans)
+{
+ char scriptfn[PATH_MAX];
+ char *scriptpath;
+ char hookpath[PATH_MAX];
+ char cmdline[PATH_MAX];
+ char cwd[PATH_MAX] = "";
+ pid_t pid;
+ int retval = 0;
+ DIR *dir;
+ struct dirent *ent;
+
+ _pacman_log(PM_LOG_FLOW2, _("executing %s hooks..."), hookname);
+
+ /* save the cwd so we can restore it later */
+ if(getcwd(cwd, PATH_MAX) == NULL) {
+ _pacman_log(PM_LOG_ERROR, _("could not get current working
directory"));
+ /* in case of error, cwd content is undefined: so we set it to
something */
+ cwd[0] = 0;
+ }
+
+ /* just in case our cwd was removed in the upgrade operation */
+ if(chdir(root) != 0) {
+ _pacman_log(PM_LOG_ERROR, _("could not change directory to %s
(%s)"), root, strerror(errno));
+ }
+
+ snprintf(hookpath, PATH_MAX, "%s/%s", root, hookdir);
+
+ dir = opendir(hookpath);
+ if (!dir) {
+ _pacman_log(PM_LOG_ERROR, _("opening hooks directory failed
(%s)"), strerror(errno));
+ retval = 1;
+ goto cleanup;
+ }
+ while ((ent = readdir(dir)) != NULL) {
+ if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
+ continue;
+ }
+ snprintf(scriptfn, PATH_MAX, "%s/%s", hookpath, ent->d_name);
+ /* chop off the root so we can find the script in the chroot */
+ scriptpath = scriptfn + strlen(root) - 1;
+ if(!grep(scriptfn, hookname)) {
+ /* script not found in scriptlet file */
+ continue;
+ }
+ snprintf(cmdline, PATH_MAX, "source %s %s", scriptpath,
hookname);
+ _pacman_log(PM_LOG_DEBUG, "%s", cmdline);
+ pid = fork();
+ if(pid == -1) {
+ _pacman_log(PM_LOG_ERROR, _("could not fork a new
process (%s)"), strerror(errno));
+ retval = 1;
+ goto cleanup;
+ }
+
+ if(pid == 0) {
+ FILE *pp;
+ _pacman_log(PM_LOG_DEBUG, _("chrooting in %s"), root);
+ if(chroot(root) != 0) {
+ _pacman_log(PM_LOG_ERROR, _("could not change
the root directory (%s)"), strerror(errno));
+ return(1);
+ }
+ if(chdir("/") != 0) {
+ _pacman_log(PM_LOG_ERROR, _("could not change
directory to / (%s)"), strerror(errno));
+ return(1);
+ }
+ umask(0022);
+ _pacman_log(PM_LOG_DEBUG, _("executing \"%s\""),
cmdline);
+ pp = popen(cmdline, "r");
+ if(!pp) {
+ _pacman_log(PM_LOG_ERROR, _("call to popen
failed (%s)"), strerror(errno));
+ retval = 1;
+ goto cleanup;
+ }
+ while(!feof(pp)) {
+ char line[1024];
+ if(fgets(line, 1024, pp) == NULL)
+ break;
+ /* "START <event desc>" */
+ if((strlen(line) > strlen(STARTSTR)) &&
!strncmp(line, STARTSTR, strlen(STARTSTR))) {
+ EVENT(trans,
PM_TRANS_EVT_SCRIPTLET_START, _pacman_strtrim(line + strlen(STARTSTR)), NULL);
+ /* "DONE <ret code>" */
+ } else if((strlen(line) > strlen(DONESTR)) &&
!strncmp(line, DONESTR, strlen(DONESTR))) {
+ EVENT(trans,
PM_TRANS_EVT_SCRIPTLET_DONE, (void*)atol(_pacman_strtrim(line +
strlen(DONESTR))), NULL);
+ } else {
+ EVENT(trans,
PM_TRANS_EVT_SCRIPTLET_INFO, _pacman_strtrim(line), NULL);
+ }
+ }
+ pclose(pp);
+ exit(0);
+ } else {
+ if(waitpid(pid, 0, 0) == -1) {
+ _pacman_log(PM_LOG_ERROR, _("call to waitpid
failed (%s)"), strerror(errno));
+ retval = 1;
+ goto cleanup;
+ }
+ }
+ }
+
+cleanup:
+ if(strlen(cwd)) {
+ chdir(cwd);
+ }
+
+ return(retval);
+}
+
#ifndef __sun__
static long long get_freespace()
{
diff --git a/lib/libpacman/util.h b/lib/libpacman/util.h
index e6b560b..cc36187 100644
--- a/lib/libpacman/util.h
+++ b/lib/libpacman/util.h
@@ -66,6 +66,7 @@ int _pacman_logaction(unsigned char usesyslog, FILE *f, char
*fmt, ...);
int _pacman_ldconfig(char *root);
#ifdef _PACMAN_TRANS_H
int _pacman_runscriptlet(char *util, char *installfn, char *script, char *ver,
char *oldver, pmtrans_t *trans);
+int _pacman_runhook(char *root, char *hookdir, char *hookname, pmtrans_t
*trans);
#ifndef __sun__
int _pacman_check_freespace(pmtrans_t *trans, pmlist_t **data);
#endif
_______________________________________________
Frugalware-git mailing list
[email protected]
http://frugalware.org/mailman/listinfo/frugalware-git