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

Reply via email to