From d39b1dbe627af218e49be6424857089a5888903b Mon Sep 17 00:00:00 2001 From: Xavier Chantry Date: Sun, 19 Jul 2009 11:15:11 +0200 Subject: Add new --print operation for all operations And a new --print-format option to configure the output. This implements FS#14208 Example usage : pacman -Sp --print-format "%r/%n-%v : %l [%s]" kdelibs extra/kdelibs-4.3.2-4 : ftp://mir2.archlinuxfr.org/archlinux/extra/os/i686/kdelibs-4.3.2-4-i686.pkg.tar.gz [0,00] Signed-off-by: Xavier Chantry Signed-off-by: Dan McGee --- src/pacman/conf.c | 1 + src/pacman/conf.h | 6 ++- src/pacman/pacman.c | 23 +++++++--- src/pacman/remove.c | 6 +++ src/pacman/sync.c | 26 ++--------- src/pacman/upgrade.c | 8 +++- src/pacman/util.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++---- src/pacman/util.h | 1 + 8 files changed, 151 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/pacman/conf.c b/src/pacman/conf.c index 92c6f4eb..a8da49c5 100644 --- a/src/pacman/conf.c +++ b/src/pacman/conf.c @@ -62,6 +62,7 @@ int config_free(config_t *oldconfig) free(oldconfig->dbpath); free(oldconfig->logfile); free(oldconfig->xfercommand); + free(oldconfig->print_format); free(oldconfig); oldconfig = NULL; diff --git a/src/pacman/conf.h b/src/pacman/conf.h index c97e5d78..6ded522d 100644 --- a/src/pacman/conf.h +++ b/src/pacman/conf.h @@ -31,6 +31,8 @@ typedef struct __config_t { unsigned short noconfirm; unsigned short noprogressbar; unsigned short logmask; + unsigned short print; + char *print_format; /* unfortunately, we have to keep track of paths both here and in the library * because they can come from both the command line or config file, and we * need to ensure we get the order of preference right. */ @@ -59,7 +61,6 @@ typedef struct __config_t { unsigned short op_s_sync; unsigned short op_s_search; unsigned short op_s_upgrade; - unsigned short op_s_printuris; unsigned short group; pmtransflag_t flags; @@ -103,7 +104,8 @@ enum { OP_IGNOREGROUP, OP_NEEDED, OP_ASEXPLICIT, - OP_ARCH + OP_ARCH, + OP_PRINTFORMAT }; /* clean method */ diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index 0e80fb22..d4385ebc 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -129,7 +129,6 @@ static void usage(int op, const char * const myname) printf(_(" -g, --groups view all members of a package group\n")); printf(_(" -i, --info view package information\n")); printf(_(" -l, --list view a list of packages in a repo\n")); - printf(_(" -p, --print-uris print out URIs for given packages and their dependencies\n")); printf(_(" -s, --search search remote repositories for matching strings\n")); printf(_(" -u, --sysupgrade upgrade installed packages (-uu allows downgrade)\n")); printf(_(" -w, --downloadonly download packages but do not install/upgrade anything\n")); @@ -140,6 +139,9 @@ static void usage(int op, const char * const myname) " ignore a group upgrade (can be used more than once)\n")); printf(_(" -q, --quiet show less information for query and search\n")); } + printf(_(" --print only print the targets instead of performing the operation\n")); + printf(_(" --print-format \n" + " specify how the targets should be printed\n")); printf(_(" --config set an alternate configuration file\n")); printf(_(" --logfile set an alternate log file\n")); printf(_(" --noconfirm do not ask for any confirmation\n")); @@ -371,7 +373,7 @@ static int parseargs(int argc, char *argv[]) {"nosave", no_argument, 0, 'n'}, {"owns", no_argument, 0, 'o'}, {"file", no_argument, 0, 'p'}, - {"print-uris", no_argument, 0, 'p'}, + {"print", no_argument, 0, 'p'}, {"quiet", no_argument, 0, 'q'}, {"root", required_argument, 0, 'r'}, {"recursive", no_argument, 0, 's'}, @@ -397,6 +399,7 @@ static int parseargs(int argc, char *argv[]) {"needed", no_argument, 0, OP_NEEDED}, {"asexplicit", no_argument, 0, OP_ASEXPLICIT}, {"arch", required_argument, 0, OP_ARCH}, + {"print-format", required_argument, 0, OP_PRINTFORMAT}, {0, 0, 0, 0} }; @@ -485,6 +488,9 @@ static int parseargs(int argc, char *argv[]) check_optarg(); setarch(optarg); break; + case OP_PRINTFORMAT: + config->print_format = strdup(optarg); + break; case 'Q': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_QUERY); break; case 'R': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_REMOVE); break; case 'S': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_SYNC); break; @@ -521,9 +527,7 @@ static int parseargs(int argc, char *argv[]) case 'o': config->op_q_owns = 1; break; case 'p': config->op_q_isfile = 1; - config->op_s_printuris = 1; - config->flags |= PM_TRANS_FLAG_NOCONFLICTS; - config->flags |= PM_TRANS_FLAG_NOLOCK; + config->print = 1; break; case 'q': config->quiet = 1; @@ -1126,6 +1130,15 @@ int main(int argc, char *argv[]) config->noconfirm = 1; } + /* set up the print operations */ + if(config->print) { + config->noconfirm = 1; + config->flags |= PM_TRANS_FLAG_NOCONFLICTS; + config->flags |= PM_TRANS_FLAG_NOLOCK; + /* Display only errors */ + config->logmask &= ~PM_LOG_WARNING; + } + #if defined(HAVE_GETEUID) && !defined(CYGWIN) /* check if we have sufficient permission for the requested operation */ if(myuid > 0 && needs_root()) { diff --git a/src/pacman/remove.c b/src/pacman/remove.c index 61b57c77..4a5d9bfb 100644 --- a/src/pacman/remove.c +++ b/src/pacman/remove.c @@ -121,6 +121,12 @@ int pacman_remove(alpm_list_t *targets) printf(_(" there is nothing to do\n")); goto cleanup; /* we are done */ } + + if(config->print) { + print_packages(pkglist); + goto cleanup; + } + /* print targets and ask user confirmation */ display_targets(pkglist, 0); printf("\n"); diff --git a/src/pacman/sync.c b/src/pacman/sync.c index bd58f545..0ec7732f 100644 --- a/src/pacman/sync.c +++ b/src/pacman/sync.c @@ -688,23 +688,8 @@ static int sync_trans(alpm_list_t *targets) } /* Step 3: actually perform the operation */ - if(config->op_s_printuris) { - /* print uris */ - alpm_list_t *i; - for(i = packages; i; i = alpm_list_next(i)) { - pmpkg_t *pkg = alpm_list_getdata(i); - pmdb_t *db = alpm_pkg_get_db(pkg); - const char *dburl = alpm_db_get_url(db); - if(dburl) { - printf("%s/%s\n", dburl, alpm_pkg_get_filename(pkg)); - } else { - /* can't use WARNING here, we don't show warnings in -Sp... */ - pm_fprintf(stderr, PM_LOG_ERROR, _("no URL for package: %s\n"), - alpm_pkg_get_name(pkg)); - } - - } - /* we are done */ + if(config->print) { + print_packages(packages); goto cleanup; } @@ -777,11 +762,6 @@ int pacman_sync(alpm_list_t *targets) { alpm_list_t *sync_dbs = NULL; - /* Display only errors with -Sp and -Sw operations */ - if((config->flags & PM_TRANS_FLAG_DOWNLOADONLY) || config->op_s_printuris) { - config->logmask &= ~PM_LOG_WARNING; - } - /* clean the cache */ if(config->op_s_clean) { int ret = 0; @@ -851,7 +831,7 @@ int pacman_sync(alpm_list_t *targets) } alpm_list_t *targs = alpm_list_strdup(targets); - if(!(config->flags & PM_TRANS_FLAG_DOWNLOADONLY) && !config->op_s_printuris) { + if(!(config->flags & PM_TRANS_FLAG_DOWNLOADONLY) && !config->print) { /* check for newer versions of packages to be upgraded first */ alpm_list_t *packages = syncfirst(); if(packages) { diff --git a/src/pacman/upgrade.c b/src/pacman/upgrade.c index ddb47964..5e4234b1 100644 --- a/src/pacman/upgrade.c +++ b/src/pacman/upgrade.c @@ -69,7 +69,6 @@ int pacman_upgrade(alpm_list_t *targets) } /* add targets to the created transaction */ - printf(_("loading package data...\n")); for(i = targets; i; i = alpm_list_next(i)) { char *targ = alpm_list_getdata(i); if(alpm_add_target(targ) == -1) { @@ -129,6 +128,13 @@ int pacman_upgrade(alpm_list_t *targets) } /* Step 3: perform the installation */ + + if(config->print) { + print_packages(alpm_trans_get_add()); + trans_release(); + return(0); + } + /* print targets and ask user confirmation */ alpm_list_t *packages = alpm_trans_get_add(); if(packages == NULL) { /* we are done */ diff --git a/src/pacman/util.c b/src/pacman/util.c index d237d00e..d5ad229b 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -47,8 +47,15 @@ int trans_init(pmtransflag_t flags) { - if(alpm_trans_init(flags, cb_trans_evt, - cb_trans_conv, cb_trans_progress) == -1) { + int ret; + if(config->print) { + ret = alpm_trans_init(flags, NULL, NULL, NULL); + } else { + ret = alpm_trans_init(flags, cb_trans_evt, cb_trans_conv, + cb_trans_progress); + } + + if(ret == -1) { pm_fprintf(stderr, PM_LOG_ERROR, _("failed to init transaction (%s)\n"), alpm_strerrorlast()); if(pm_errno == PM_ERR_HANDLE_LOCK) { @@ -72,13 +79,16 @@ int trans_release(void) int needs_root(void) { - if(config->op == PM_OP_UPGRADE || config->op == PM_OP_REMOVE || /* -U, -R */ - (config->op == PM_OP_SYNC && (config->op_s_clean || config->op_s_sync || /* -Sc, -Sy */ - (!config->group && !config->op_s_info && !config->op_q_list /* all other -S combinations, where */ - && !config->op_s_search && !config->op_s_printuris)))) { /* -g, -i, -l, -s, -p is not set */ - return(1); - } else { - return(0); + switch(config->op) { + case PM_OP_UPGRADE: + case PM_OP_REMOVE: + return(!config->print); + case PM_OP_SYNC: + return(config->op_s_clean || config->op_s_sync || + (!config->group && !config->op_s_info && !config->op_q_list && + !config->op_s_search && !config->print)); + default: + return(0); } } @@ -553,6 +563,98 @@ void display_targets(const alpm_list_t *pkgs, int install) FREELIST(targets); } +off_t pkg_get_size(pmpkg_t *pkg) +{ + switch(config->op) { + case PM_OP_SYNC: + return(alpm_pkg_download_size(pkg)); + case PM_OP_UPGRADE: + return(alpm_pkg_get_size(pkg)); + default: + return(alpm_pkg_get_isize(pkg)); + } +} + +char *pkg_get_location(pmpkg_t *pkg) +{ + pmdb_t *db; + const char *dburl; + char *string; + switch(config->op) { + case PM_OP_SYNC: + db = alpm_pkg_get_db(pkg); + dburl = alpm_db_get_url(db); + if(dburl) { + char *pkgurl = NULL; + asprintf(&pkgurl, "%s/%s", dburl, alpm_pkg_get_filename(pkg)); + return(pkgurl); + } + case PM_OP_UPGRADE: + return(strdup(alpm_pkg_get_filename(pkg))); + default: + string = NULL; + asprintf(&string, "%s-%s", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); + return(string); + } +} + +void print_packages(const alpm_list_t *packages) +{ + const alpm_list_t *i; + if(!config->print_format) { + config->print_format = strdup("%l"); + } + for(i = packages; i; i = alpm_list_next(i)) { + pmpkg_t *pkg = alpm_list_getdata(i); + char *string = strdup(config->print_format); + char *temp = string; + /* %n : pkgname */ + if(strstr(temp,"%n")) { + string = strreplace(temp, "%n", alpm_pkg_get_name(pkg)); + free(temp); + temp = string; + } + /* %v : pkgver */ + if(strstr(temp,"%v")) { + string = strreplace(temp, "%v", alpm_pkg_get_version(pkg)); + free(temp); + temp = string; + } + /* %l : location */ + if(strstr(temp,"%l")) { + char *pkgloc = pkg_get_location(pkg); + string = strreplace(temp, "%l", pkgloc); + free(pkgloc); + free(temp); + temp = string; + } + /* %r : repo */ + if(strstr(temp,"%r")) { + const char *repo = "local"; + pmdb_t *db = alpm_pkg_get_db(pkg); + if(db) { + repo = alpm_db_get_name(db); + } + string = strreplace(temp, "%r", repo); + free(temp); + temp = string; + } + /* %s : size */ + if(strstr(temp,"%s")) { + char *size; + double mbsize = 0.0; + mbsize = pkg_get_size(pkg) / (1024.0 * 1024.0); + asprintf(&size, "%.2f", mbsize); + string = strreplace(temp, "%s", size); + free(size); + free(temp); + temp = string; + } + printf("%s\n",string); + free(string); + } +} + /* Helper function for comparing strings using the * alpm "compare func" signature */ int str_cmp(const void *s1, const void *s2) diff --git a/src/pacman/util.h b/src/pacman/util.h index 7a8c39d1..0fed4901 100644 --- a/src/pacman/util.h +++ b/src/pacman/util.h @@ -55,6 +55,7 @@ void list_display_linebreak(const char *title, const alpm_list_t *list); void display_targets(const alpm_list_t *pkgs, int install); void display_new_optdepends(pmpkg_t *oldpkg, pmpkg_t *newpkg); void display_optdepends(pmpkg_t *pkg); +void print_packages(const alpm_list_t *packages); int yesno(char *fmt, ...); int noyes(char *fmt, ...); int pm_printf(pmloglevel_t level, const char *format, ...) __attribute__((format(printf,2,3))); -- cgit v1.2.3-24-g4f1b