summaryrefslogtreecommitdiffstats
path: root/src/pacman/query.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pacman/query.c')
-rw-r--r--src/pacman/query.c186
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);