[pacman-dev] [PATCH] Add support for user defined per package post install actions
Allan McRae
allan at archlinux.org
Sat Jan 31 20:59:10 EST 2009
Hi,
This seems similar to the hooks mechanism the we have been discussing
but less general. Have a look at
http://wiki.archlinux.org/index.php/User:Allan/Pacman_Hooks for more
information. So in short, I like the idea but would want a more general
approach taken.
Allan
Mårten Olsson wrote:
> Hi all!
>
> Wasn't sure if I could include additonal text in "patch-mail".
> So I hope it is ok to send an additonal mail with extra info:
>
> At some places the code needs cleanup which I will do if the concept shown
> is accepted (didn't want to take to much time on that if the concept is disliked
> and never will be accpeted for that reason).
> I want to fix the code-duplication issue (one function) and make the parsign so one
> can have arguments with spaces inside " ".
>
> I wasn't sure if this functionality can be considered dangerous because it will run a script
> with full access to the system, but I guess the same problem could show up if you make "bad"
> packages with an install script.
>
> BR,
> Mårten
>
> ----- Original Message -----
> From: "Mårten Olsson" <marten.olsson at purplescout.se>
> To: pacman-dev at archlinux.org
> Sent: Sunday, February 1, 2009 2:36:46 AM GMT +01:00 Amsterdam / Berlin / Bern / Rome / Stockholm / Vienna
> Subject: [pacman-dev] [PATCH] Add support for user defined per package post install actions
>
> This adds suport for user to add per package post install
> actions, somewhat similar to post-install scripts in packages
> but controlled by local user and not part of package/not done
> by package maintainer.
> The actions is performed by "system" call and can't contain
> spaces (not even when inside ").
> Syntax in logfile is
> PostInstallAction = <packagename>:<action>
> Functionality added inside libalpm, add support for configuring
> in pacman.
>
> Signed-off-by: Mårten Olsson <marten.olsson_at_purplescout.se>
> ---
> lib/libalpm/add.c | 43 +++++++++++++++++++++++++++++++++
> lib/libalpm/alpm.h | 3 ++
> lib/libalpm/handle.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++
> lib/libalpm/handle.h | 6 ++++
> src/pacman/pacman.c | 20 +++++++++++++++
> 5 files changed, 137 insertions(+), 0 deletions(-)
>
> diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
> index 6eb2085..1cd6e28 100644
> --- a/lib/libalpm/add.c
> +++ b/lib/libalpm/add.c
> @@ -632,6 +632,46 @@ static int extract_single_file(struct archive *archive,
> return(errors);
> }
>
> +static int postinstallcompare(const void *postinstalldata, const void *pkgname)
> +{
> + const postinstallaction_t *postinstallaction=postinstalldata;
> +
> + if( (pkgname != NULL) && (postinstallaction->pkgname != NULL) && (strcmp(postinstallaction->pkgname, pkgname) == 0)) {
> + return(0);
> + }
> +
> + return(1);
> +}
> +
> +/** Test if a package has a postinstallaction associated with it and executes the action.
> + *
> + * Checks if the package has a postinstallaction associated with it
> + * and if so executes the action by the system call
> + *
> + * @param pkg the package to test
> + *
> + * @return 0 if no action found or if the associated action completed succesfully, 1 otherwise
> + */
> +static int check_run_postinstallaction(pmpkg_t *pkg)
> +{
> + postinstallaction_t *postinstallaction = NULL;
> +
> + _alpm_log(PM_LOG_DEBUG, "PostInstallAction: finding PostInstallAction for package: %s\n", alpm_pkg_get_name(pkg));
> +
> + postinstallaction=alpm_list_find(handle->postinstallactions, alpm_pkg_get_name(pkg), postinstallcompare);
> +
> + if( postinstallaction != NULL) {
> + _alpm_log(PM_LOG_DEBUG, "PostInstallAction: package: %s action: %s \n", postinstallaction->pkgname, postinstallaction->action);
> +
> + /* should this be more like the install-scriptlet code */
> + if( system(postinstallaction->action) != 0) {
> + return(1);
> + }
> + }
> +
> + return(0);
> +}
> +
> static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
> pmtrans_t *trans, pmdb_t *db)
> {
> @@ -847,6 +887,9 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
> }
> }
>
> + /* check and run postinstall action */
> + check_run_postinstallaction(newpkg);
> +
> if(is_upgrade) {
> EVENT(trans, PM_TRANS_EVT_UPGRADE_DONE, newpkg, oldpkg);
> } else {
> diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
> index 7b7ca4e..04ff886 100644
> --- a/lib/libalpm/alpm.h
> +++ b/lib/libalpm/alpm.h
> @@ -122,6 +122,9 @@ void alpm_option_add_noupgrade(const char *pkg);
> void alpm_option_set_noupgrades(alpm_list_t *noupgrade);
> int alpm_option_remove_noupgrade(const char *pkg);
>
> +int alpm_option_add_postinstallaction(const char *pkg, const char *action);
> +int alpm_option_remove_postinstallaction(const char *pkg);
> +
> alpm_list_t *alpm_option_get_noextracts();
> void alpm_option_add_noextract(const char *pkg);
> void alpm_option_set_noextracts(alpm_list_t *noextract);
> diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c
> index 813f439..504157d 100644
> --- a/lib/libalpm/handle.c
> +++ b/lib/libalpm/handle.c
> @@ -53,6 +53,23 @@ pmhandle_t *_alpm_handle_new()
> return(handle);
> }
>
> +void postinstallactionfree(void *data)
> +{
> + postinstallaction_t *postinstallaction=data;
> +
> + if(postinstallaction->pkgname != NULL)
> + {
> + free(postinstallaction->pkgname);
> + }
> +
> + if(postinstallaction->action != NULL)
> + {
> + free(postinstallaction->action);
> + }
> +
> + free(postinstallaction);
> +}
> +
> void _alpm_handle_free(pmhandle_t *handle)
> {
> ALPM_LOG_FUNC;
> @@ -84,6 +101,8 @@ void _alpm_handle_free(pmhandle_t *handle)
> FREELIST(handle->noextract);
> FREELIST(handle->ignorepkg);
> FREELIST(handle->ignoregrp);
> + alpm_list_free_inner(handle->postinstallactions, postinstallactionfree);
> + alpm_list_free(handle->postinstallactions);
> FREE(handle);
> }
>
> @@ -453,6 +472,52 @@ int SYMEXPORT alpm_option_remove_noupgrade(const char *pkg)
> return(0);
> }
>
> +int SYMEXPORT alpm_option_add_postinstallaction(const char *pkg, const char *action)
> +{
> + postinstallaction_t *postinstallaction=0;
> +
> + postinstallaction=malloc(sizeof(postinstallaction_t));
> +
> + if(postinstallaction == NULL) {
> + return(1);
> + }
> +
> + postinstallaction->pkgname = strdup(pkg);
> + postinstallaction->action= strdup(action);
> +
> + handle->postinstallactions = alpm_list_add(handle->postinstallactions, postinstallaction);
> +
> + return(0);
> +}
> +
> +/* Duplicated here for now, cleanup needed */
> +static int postinstallcompare(const void *postinstalldata, const void *pkgname)
> +{
> + const postinstallaction_t *postinstallaction=postinstalldata;
> +
> + if( (pkgname != NULL) && (postinstallaction->pkgname != NULL) && (strcmp(postinstallaction->pkgname, pkgname) == 0)) {
> + return(0);
> + }
> +
> + return(1);
> +}
> +
> +int SYMEXPORT alpm_option_remove_postinstallaction(const char *pkg)
> +{
> + postinstallaction_t *postinstallaction=0;
> +
> + handle->postinstallactions=alpm_list_remove(handle->postinstallactions, pkg, postinstallcompare, (void *)&postinstallaction );
> +
> + if( postinstallaction != NULL) {
> + free(postinstallaction->pkgname);
> + free(postinstallaction->action);
> + free(postinstallaction);
> + return(1);
> + }
> +
> + return(0);
> +}
> +
> void SYMEXPORT alpm_option_add_noextract(const char *pkg)
> {
> handle->noextract = alpm_list_add(handle->noextract, strdup(pkg));
> diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h
> index ad7666d..c53e7f6 100644
> --- a/lib/libalpm/handle.h
> +++ b/lib/libalpm/handle.h
> @@ -28,6 +28,11 @@
> #include "alpm.h"
> #include "trans.h"
>
> +typedef struct _postinstallaction_t {
> + char *pkgname;
> + char *action;
> +} postinstallaction_t;
> +
> typedef struct _pmhandle_t {
> /* internal usage */
> pmdb_t *db_local; /* local db pointer */
> @@ -53,6 +58,7 @@ typedef struct _pmhandle_t {
> alpm_list_t *noextract; /* List of files NOT to extract */
> alpm_list_t *ignorepkg; /* List of packages to ignore */
> alpm_list_t *ignoregrp; /* List of groups to ignore */
> + alpm_list_t *postinstallactions; /* List of packages to perform actions postinstall */
>
> /* options */
> unsigned short usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */
> diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
> index 59916d6..1f1371d 100644
> --- a/src/pacman/pacman.c
> +++ b/src/pacman/pacman.c
> @@ -549,6 +549,24 @@ static void option_add_syncfirst(const char *name) {
> config->syncfirst = alpm_list_add(config->syncfirst, strdup(name));
> }
>
> +/* helper for being used with setrepeatingoption, additional parsing done here*/
> +static void option_add_postinstallaction(const char *string) {
> + char *name = (char *)string;
> + char *action = 0;
> +
> + action=strchr(string,':');
> +
> + if( action != NULL) {
> + *action = '\0';
> + action++;
> +
> + pm_printf(PM_LOG_DEBUG, "config: Postinstallaction package %s action: %s\n", name, action);
> +
> + alpm_option_add_postinstallaction(name, action);
> + }
> +
> +}
> +
> /** Add repeating options such as NoExtract, NoUpgrade, etc to libalpm
> * settings. Refactored out of the parseconfig code since all of them did
> * the exact same thing and duplicated code.
> @@ -710,6 +728,8 @@ static int _parseconfig(const char *file, const char *givensection,
> setrepeatingoption(ptr, "HoldPkg", option_add_holdpkg);
> } else if(strcmp(key, "SyncFirst") == 0) {
> setrepeatingoption(ptr, "SyncFirst", option_add_syncfirst);
> + } else if(strcmp(key, "PostInstallAction") == 0) {
> + setrepeatingoption(ptr, "PostInstallAction", option_add_postinstallaction);
> } else if(strcmp(key, "DBPath") == 0) {
> /* don't overwrite a path specified on the command line */
> if(!config->dbpath) {
>
More information about the pacman-dev
mailing list