diff options
author | Xavier Chantry <chantry.xavier@gmail.com> | 2010-10-17 01:08:34 +0200 |
---|---|---|
committer | Xavier Chantry <chantry.xavier@gmail.com> | 2011-01-29 19:33:16 +0100 |
commit | f2fcf7eeb10dafec06d5d7d853b681f2e9fde45a (patch) | |
tree | d1e1003b81bb458fdfd3ca5fed1178d1ff1fae64 /src | |
parent | 1767a569c65ad1067eac7dcd1d9665e55767e50e (diff) | |
download | pacman-f2fcf7eeb10dafec06d5d7d853b681f2e9fde45a.tar.gz pacman-f2fcf7eeb10dafec06d5d7d853b681f2e9fde45a.tar.xz |
pacman/sync: rewrite target handling
This uses the new public functions to handle targets from the frontend,
like it used to be :
1) alpm_find_dbs_satisfier to find (optionally versioned) package or
provision
2) alpm_find_grp_pkgs to find members for a groups
3) alpm_add_pkg to finally add the pmpkg_t from 1 or 2
Of course, this adds more code to the frontend, but it completely
deprecates sync_target and sync_dbtarget interfaces.
This all-in-one interfaces felt wrong and left no control to the
frontend. A good frontend should just use alpm_add_pkg, with pkg coming
from alpm_db_get_pkg (for normal targets), alpm_find_dbs_satisfier (for
versioned provisions) or alpm_find_grp_pkgs (for groups).
This also opens the way to provide a better group handling in pacman
without constraint from libalpm and callbacks.
In ignore006, only the retcode changes, because no package was found to
satisfy the target (the only possible package is ignored).
Signed-off-by: Xavier Chantry <chantry.xavier@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/pacman/sync.c | 110 |
1 files changed, 95 insertions, 15 deletions
diff --git a/src/pacman/sync.c b/src/pacman/sync.c index 7353f7ee..deda77d4 100644 --- a/src/pacman/sync.c +++ b/src/pacman/sync.c @@ -590,6 +590,84 @@ static alpm_list_t *syncfirst(void) { return(res); } +static pmdb_t *get_db(const char *dbname) +{ + alpm_list_t *i; + for(i = alpm_option_get_syncdbs(); i; i = i->next) { + pmdb_t *db = i->data; + if(strcmp(alpm_db_get_name(db), dbname) == 0) { + return(db); + } + } + return(NULL); +} + +static int process_pkg(pmpkg_t *pkg) +{ + int ret = alpm_add_pkg(pkg); + + if(ret == -1) { + if(pm_errno == PM_ERR_TRANS_DUP_TARGET + || pm_errno == PM_ERR_PKG_IGNORED) { + /* just skip duplicate or ignored targets */ + pm_printf(PM_LOG_WARNING, _("skipping target: %s\n"), alpm_pkg_get_name(pkg)); + return(0); + } else { + pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", alpm_pkg_get_name(pkg), + alpm_strerrorlast()); + return(1); + } + } + return(0); +} + +static int process_group(alpm_list_t *dbs, char *group) +{ + int ret = 0; + alpm_list_t *i; + alpm_list_t *pkgs = alpm_find_grp_pkgs(dbs, group); + int count = alpm_list_count(pkgs); + + if(!count) { + pm_fprintf(stderr, PM_LOG_ERROR, _("target not found: %s\n"), group); + return(1); + } + + printf(_(":: There are %d members in group %s:\n"), count, + group); + select_display(pkgs); + select_question(count, + _("Which ones do you want to install?")); + char *array = malloc(count); + memset(array, 1, count); + int n = 0; + for(i = pkgs; i; i = alpm_list_next(i)) { + if(array[n++] == 0) + continue; + pmpkg_t *pkg = alpm_list_getdata(i); + + if(process_pkg(pkg) == 1) { + ret = 1; + goto cleanup; + } + } +cleanup: + alpm_list_free(pkgs); + free(array); + return(ret); +} + +static int process_targname(alpm_list_t *dblist, char *targname) +{ + pmpkg_t *pkg = alpm_find_dbs_satisfier(dblist, targname); + + if(pkg) { + return(process_pkg(pkg)); + } + /* fallback on group */ + return(process_group(dblist, targname)); +} + static int process_target(char *target) { /* process targets */ @@ -597,28 +675,30 @@ static int process_target(char *target) char *targname = strchr(targstring, '/'); char *dbname = NULL; int ret = 0; + alpm_list_t *dblist = NULL; + if(targname) { + pmdb_t *db = NULL; + *targname = '\0'; targname++; dbname = targstring; - ret = alpm_sync_dbtarget(dbname,targname); - } else { - targname = targstring; - ret = alpm_sync_target(targname); - } - - if(ret == -1) { - if(pm_errno == PM_ERR_TRANS_DUP_TARGET - || pm_errno == PM_ERR_PKG_IGNORED) { - /* just skip duplicate or ignored targets */ - pm_printf(PM_LOG_WARNING, _("skipping target: %s\n"), target); - } else { - pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", target, - alpm_strerrorlast()); + db = get_db(dbname); + if(!db) { + pm_fprintf(stderr, PM_LOG_ERROR, _("database not found: %s\n"), + dbname); ret = 1; + goto cleanup; } + dblist = alpm_list_add(dblist, db); + ret = process_targname(dblist, targname); + alpm_list_free(dblist); + } else { + targname = targstring; + dblist = alpm_option_get_syncdbs(); + ret = process_targname(dblist, targname); } - +cleanup: free(targstring); return(ret); } |