libalpm compliant programs now support running pre-commit and post-commit hooks. Currently, the implementation is as simple as I can make it -- if /etc/pacman.d/hooks.d/transact.sh exists, it will be run with the 'pre-commit' parameter just before a transaction is committed, and it will be run with 'post-commit' after the transaction has been completed. The intent is for transact.sh to be a wrapper that calls scripts in /etc/pacman.d/hooks.d/transact.d with the arg it is passed, but since this is just for a demo I did not actually include any of that. I also didn't bother adhering to any of the coding standards, as that will be easy enough to fix up once we have something a bit more fleshed out. --- lib/libalpm/hooks.c | 28 ++++++++++++++++++++++++++++ lib/libalpm/hooks.h | 4 ++++ lib/libalpm/trans.c | 4 +++- 3 files changed, 35 insertions(+), 1 deletions(-) diff --git a/lib/libalpm/hooks.c b/lib/libalpm/hooks.c index 9630c70..5982ea5 100644 --- a/lib/libalpm/hooks.c +++ b/lib/libalpm/hooks.c @@ -30,6 +30,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <sys/statvfs.h> +#include <sys/wait.h> #include <errno.h> /* libalpm */ @@ -46,3 +47,30 @@ #include "alpm.h" #include "deps.h" #include "cache.h" + +int alpm_hook_transact(char* phase) { + char filename[PATH_MAX]; + struct stat sbuf; + pid_t childpid, retpid; + int status; + /* ignore transaction hooks when targeting another root filesystem + if (!strcmp(handle->root,"/")) + return 1;*/ + snprintf(filename,PATH_MAX,"%s/transact.sh",ALPM_HOOKS_DIR); + /* if we cannot stat transact.sh, just return */ + if (stat(filename,&sbuf) != 0) + return 1; + fflush(NULL); + childpid=fork(); + if (childpid == -1) { + return 1; + } else if (childpid == 0) { + execl(filename,"transact.sh",phase,(char *)0); + } else { + /* return the exit status of the transact.sh program. */ + do { + retpid = waitpid(childpid,&status,0); + } while (!WIFEXITED(status) && !WIFSIGNALED(status)); + } + return !WEXITSTATUS(status); +} diff --git a/lib/libalpm/hooks.h b/lib/libalpm/hooks.h index d60b1f4..f79d2c4 100644 --- a/lib/libalpm/hooks.h +++ b/lib/libalpm/hooks.h @@ -25,4 +25,8 @@ #include "alpm.h" +#define ALPM_HOOKS_DIR "/etc/pacman.d/hooks.d" + +int alpm_hook_transact(char*); + #endif /*ALPM_HOOKS_H */ diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c index 523f33b..ed26aa6 100644 --- a/lib/libalpm/trans.c +++ b/lib/libalpm/trans.c @@ -195,7 +195,8 @@ int SYMEXPORT alpm_trans_commit(alpm_list_t **data) if(trans->add == NULL && trans->remove == NULL) { return(0); } - + if (! alpm_hook_transact("pre-commit")) + return (-1); trans->state = STATE_COMMITING; if(trans->add == NULL) { @@ -211,6 +212,7 @@ int SYMEXPORT alpm_trans_commit(alpm_list_t **data) } trans->state = STATE_COMMITED; + alpm_hook_transact("post-commit"); return(0); } -- 1.7.1.1