diff options
Diffstat (limited to 'src/pacman/query.c')
-rw-r--r-- | src/pacman/query.c | 186 |
1 files changed, 93 insertions, 93 deletions
diff --git a/src/pacman/query.c b/src/pacman/query.c index ab19bab2..fc2c90c4 100644 --- a/src/pacman/query.c +++ b/src/pacman/query.c @@ -1,7 +1,7 @@ /* * query.c * - * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify @@ -18,8 +18,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "config.h" - #include <stdlib.h> #include <stdio.h> #include <stdint.h> @@ -38,22 +36,7 @@ #include "conf.h" #include "util.h" -static char *resolve_path(const char *file) -{ - char *str = NULL; - - str = calloc(PATH_MAX, sizeof(char)); - if(!str) { - return NULL; - } - - if(!realpath(file, str)) { - free(str); - return NULL; - } - - return str; -} +#define LOCAL_PREFIX "local/" /* check if filename exists in PATH */ static int search_path(char **filename, struct stat *bufptr) @@ -75,7 +58,7 @@ static int search_path(char **filename, struct stat *bufptr) /* strip the trailing slash if one exists */ while(path[plen - 1] == '/') { - path[--plen] = '\0'; + path[--plen] = '\0'; } fullname = malloc(plen + flen + 2); @@ -111,7 +94,6 @@ static int query_fileowner(alpm_list_t *targets) { int ret = 0; char path[PATH_MAX]; - const char *root; size_t rootlen; alpm_list_t *t; alpm_db_t *db_local; @@ -125,25 +107,44 @@ static int query_fileowner(alpm_list_t *targets) /* Set up our root path buffer. We only need to copy the location of root in * once, then we can just overwrite whatever file was there on the previous * iteration. */ - root = alpm_option_get_root(config->handle); - rootlen = strlen(root); - if(rootlen + 1 > PATH_MAX) { - /* we are in trouble here */ - pm_printf(ALPM_LOG_ERROR, _("path too long: %s%s\n"), root, ""); + + /* resolve root now so any symlinks in it will only have to be resolved once */ + if(!realpath(alpm_option_get_root(config->handle), path)) { + pm_printf(ALPM_LOG_ERROR, _("cannot determine real path for '%s': %s\n"), + path, strerror(errno)); + return 1; + } + + /* make sure there's enough room to append the package file to path */ + rootlen = strlen(path); + if(rootlen + 2 > PATH_MAX) { + pm_printf(ALPM_LOG_ERROR, _("path too long: %s%s\n"), path, ""); return 1; } - strcpy(path, root); - db_local = alpm_option_get_localdb(config->handle); + /* append trailing '/' removed by realpath */ + path[rootlen++] = '/'; + path[rootlen] = '\0'; + + db_local = alpm_get_localdb(config->handle); for(t = targets; t; t = alpm_list_next(t)) { - char *filename, *dname, *rpath; + char *filename = NULL, *dname = NULL, *rpath = NULL; const char *bname; struct stat buf; alpm_list_t *i; + size_t len; int found = 0; - filename = strdup(alpm_list_getdata(t)); + if((filename = strdup(t->data)) == NULL) { + goto targcleanup; + } + + /* trailing '/' causes lstat to dereference directory symlinks */ + len = strlen(filename) - 1; + while(len > 0 && filename[len] == '/') { + filename[len--] = '\0'; + } if(lstat(filename, &buf) == -1) { /* if it is not a path but a program name, then check in PATH */ @@ -151,49 +152,33 @@ static int query_fileowner(alpm_list_t *targets) if(search_path(&filename, &buf) == -1) { pm_printf(ALPM_LOG_ERROR, _("failed to find '%s' in PATH: %s\n"), filename, strerror(errno)); - ret++; - free(filename); - continue; + goto targcleanup; } } else { pm_printf(ALPM_LOG_ERROR, _("failed to read file '%s': %s\n"), filename, strerror(errno)); - ret++; - free(filename); - continue; + goto targcleanup; } } if(S_ISDIR(buf.st_mode)) { pm_printf(ALPM_LOG_ERROR, _("cannot determine ownership of directory '%s'\n"), filename); - ret++; - free(filename); - continue; + goto targcleanup; } bname = mbasename(filename); dname = mdirname(filename); - /* for files in '/', there is no directory name to match */ - if(strcmp(dname, "") == 0) { - rpath = NULL; - } else { - rpath = resolve_path(dname); + rpath = realpath(dname, NULL); - if(!rpath) { - pm_printf(ALPM_LOG_ERROR, _("cannot determine real path for '%s': %s\n"), - filename, strerror(errno)); - free(filename); - free(dname); - free(rpath); - ret++; - continue; - } + if(!dname || !rpath) { + pm_printf(ALPM_LOG_ERROR, _("cannot determine real path for '%s': %s\n"), + filename, strerror(errno)); + goto targcleanup; } - free(dname); for(i = alpm_db_get_pkgcache(db_local); i && !found; i = alpm_list_next(i)) { - alpm_pkg_t *info = alpm_list_getdata(i); + alpm_pkg_t *info = i->data; alpm_filelist_t *filelist = alpm_pkg_get_files(info); size_t j; @@ -202,41 +187,49 @@ static int query_fileowner(alpm_list_t *targets) char *ppath, *pdname; const char *pkgfile = file->name; - /* avoid the costly resolve_path usage if the basenames don't match */ + /* avoid the costly realpath usage if the basenames don't match */ if(strcmp(mbasename(pkgfile), bname) != 0) { continue; } - /* for files in '/', there is no directory name to match */ - if(!rpath) { - print_query_fileowner(filename, info); - found = 1; - continue; - } - + /* concatenate our file and the root path */ if(rootlen + 1 + strlen(pkgfile) > PATH_MAX) { - pm_printf(ALPM_LOG_ERROR, _("path too long: %s%s\n"), root, pkgfile); + path[rootlen] = '\0'; /* reset path for error message */ + pm_printf(ALPM_LOG_ERROR, _("path too long: %s%s\n"), path, pkgfile); + continue; } - /* concatenate our file and the root path */ strcpy(path + rootlen, pkgfile); pdname = mdirname(path); - ppath = resolve_path(pdname); + ppath = realpath(pdname, NULL); free(pdname); - if(ppath && strcmp(ppath, rpath) == 0) { + if(!ppath) { + pm_printf(ALPM_LOG_ERROR, _("cannot determine real path for '%s': %s\n"), + path, strerror(errno)); + continue; + } + + if(strcmp(ppath, rpath) == 0) { print_query_fileowner(filename, info); found = 1; + free(ppath); + break; } free(ppath); } } if(!found) { pm_printf(ALPM_LOG_ERROR, _("No package owns %s\n"), filename); + } + +targcleanup: + if(!found) { ret++; } free(filename); free(rpath); + free(dname); } return ret; @@ -247,7 +240,8 @@ static int query_search(alpm_list_t *targets) { alpm_list_t *i, *searchlist; int freelist; - alpm_db_t *db_local = alpm_option_get_localdb(config->handle); + alpm_db_t *db_local = alpm_get_localdb(config->handle); + unsigned short cols; /* if we have a targets list, search for packages matching it */ if(targets) { @@ -261,37 +255,38 @@ static int query_search(alpm_list_t *targets) return 1; } + cols = getcols(fileno(stdout)); for(i = searchlist; i; i = alpm_list_next(i)) { alpm_list_t *grp; - alpm_pkg_t *pkg = alpm_list_getdata(i); + alpm_pkg_t *pkg = i->data; if(!config->quiet) { - printf("local/%s %s", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); + printf(LOCAL_PREFIX "%s %s", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); } else { - printf("%s", alpm_pkg_get_name(pkg)); + fputs(alpm_pkg_get_name(pkg), stdout); } if(!config->quiet) { if((grp = alpm_pkg_get_groups(pkg)) != NULL) { alpm_list_t *k; - printf(" ("); + fputs(" (", stdout); for(k = grp; k; k = alpm_list_next(k)) { - const char *group = alpm_list_getdata(k); - printf("%s", group); + const char *group = k->data; + fputs(group, stdout); if(alpm_list_next(k)) { /* only print a spacer if there are more groups */ - printf(" "); + putchar(' '); } } - printf(")"); + putchar(')'); } /* we need a newline and initial indent first */ - printf("\n "); - indentprint(alpm_pkg_get_desc(pkg), 4); + fputs("\n ", stdout); + indentprint(alpm_pkg_get_desc(pkg), 4, cols); } - printf("\n"); + fputc('\n', stdout); } /* we only want to free if the list was a search list */ @@ -304,33 +299,33 @@ static int query_search(alpm_list_t *targets) static int query_group(alpm_list_t *targets) { alpm_list_t *i, *j; - char *grpname = NULL; + const char *grpname = NULL; int ret = 0; - alpm_db_t *db_local = alpm_option_get_localdb(config->handle); + alpm_db_t *db_local = alpm_get_localdb(config->handle); if(targets == NULL) { for(j = alpm_db_get_groupcache(db_local); j; j = alpm_list_next(j)) { - alpm_group_t *grp = alpm_list_getdata(j); + alpm_group_t *grp = j->data; const alpm_list_t *p; for(p = grp->packages; p; p = alpm_list_next(p)) { - alpm_pkg_t *pkg = alpm_list_getdata(p); + alpm_pkg_t *pkg = p->data; printf("%s %s\n", grp->name, alpm_pkg_get_name(pkg)); } } } else { for(i = targets; i; i = alpm_list_next(i)) { alpm_group_t *grp; - grpname = alpm_list_getdata(i); - grp = alpm_db_readgroup(db_local, grpname); + grpname = i->data; + grp = alpm_db_get_group(db_local, grpname); if(grp) { const alpm_list_t *p; for(p = grp->packages; p; p = alpm_list_next(p)) { if(!config->quiet) { printf("%s %s\n", grpname, - alpm_pkg_get_name(alpm_list_getdata(p))); + alpm_pkg_get_name(p->data)); } else { - printf("%s\n", alpm_pkg_get_name(alpm_list_getdata(p))); + printf("%s\n", alpm_pkg_get_name(p->data)); } } } else { @@ -346,11 +341,11 @@ static int is_foreign(alpm_pkg_t *pkg) { const char *pkgname = alpm_pkg_get_name(pkg); alpm_list_t *j; - alpm_list_t *sync_dbs = alpm_option_get_syncdbs(config->handle); + alpm_list_t *sync_dbs = alpm_get_syncdbs(config->handle); int match = 0; for(j = sync_dbs; j; j = alpm_list_next(j)) { - alpm_db_t *db = alpm_list_getdata(j); + alpm_db_t *db = j->data; alpm_pkg_t *findpkg = alpm_db_get_pkg(db, pkgname); if(findpkg) { match = 1; @@ -395,7 +390,7 @@ static int filter(alpm_pkg_t *pkg) } /* check if this pkg is outdated */ if(config->op_q_upgrade && (alpm_sync_newversion(pkg, - alpm_option_get_syncdbs(config->handle)) == NULL)) { + alpm_get_syncdbs(config->handle)) == NULL)) { return 0; } return 1; @@ -514,7 +509,7 @@ int pacman_query(alpm_list_t *targets) } } - db_local = alpm_option_get_localdb(config->handle); + db_local = alpm_get_localdb(config->handle); /* operations on all packages in the local DB * valid: no-op (plain -Q), list, info, check @@ -526,7 +521,7 @@ int pacman_query(alpm_list_t *targets) } for(i = alpm_db_get_pkgcache(db_local); i; i = alpm_list_next(i)) { - pkg = alpm_list_getdata(i); + pkg = i->data; if(filter(pkg)) { int value = display(pkg); if(value != 0) { @@ -552,7 +547,12 @@ int pacman_query(alpm_list_t *targets) /* operations on named packages in the local DB * valid: no-op (plain -Q), list, info, check */ for(i = targets; i; i = alpm_list_next(i)) { - char *strname = alpm_list_getdata(i); + const char *strname = i->data; + + /* strip leading part of "local/pkgname" */ + if(strncmp(strname, LOCAL_PREFIX, strlen(LOCAL_PREFIX)) == 0) { + strname += strlen(LOCAL_PREFIX); + } if(config->op_q_isfile) { alpm_pkg_load(config->handle, strname, 1, 0, &pkg); |