summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Teras <timo.teras@iki.fi>2009-01-13 15:22:14 +0200
committerTimo Teras <timo.teras@iki.fi>2009-01-13 15:22:14 +0200
commitb7f9f9bdb21ffeb50f5814fdcce2f315215fdb1e (patch)
treea77d7e52c7d61b6601ea6f0021bd529da3e85dbe
parentc831ead63c5fdb4d1e75c264084576cfefe581e6 (diff)
downloadapk-tools-b7f9f9bdb21ffeb50f5814fdcce2f315215fdb1e.tar.bz2
apk-tools-b7f9f9bdb21ffeb50f5814fdcce2f315215fdb1e.tar.xz
info: implement who owns packages query (apk_info -W)
In quiet mode e.g. "apk info -q -W <file list>" a list of dependencies suitable for .PKGINFO is output in one line.
-rw-r--r--TODO6
-rw-r--r--src/apk_database.h1
-rw-r--r--src/database.c40
-rw-r--r--src/info.c36
-rw-r--r--src/package.c12
5 files changed, 84 insertions, 11 deletions
diff --git a/TODO b/TODO
index 5f18c73..4cebb9d 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,3 @@
-- list of files on stdin, minimum dependencies on stdout
-- way to test if packages is installed
-
- confirm whether to act (show changeset-size, installed, removed) if
other packages affected then the ones explicitly specified
@@ -19,6 +16,9 @@
- Error handling and rollback
- Dependency manipulation API: deletion, overwrite, check compatibility
+- Change fdb internally to has according to full filename (that's what we
+ use to lookup in install_archive_entry and also in info -W)
+
- New user/group creation
- Non-trivial solution finder
diff --git a/src/apk_database.h b/src/apk_database.h
index c6134d7..e5d4957 100644
--- a/src/apk_database.h
+++ b/src/apk_database.h
@@ -102,6 +102,7 @@ void apk_db_close(struct apk_database *db);
struct apk_package *apk_db_pkg_add_file(struct apk_database *db, const char *file);
struct apk_package *apk_db_get_pkg(struct apk_database *db, csum_t sum);
+struct apk_package *apk_db_get_file_owner(struct apk_database *db, apk_blob_t filename);
void apk_db_index_write(struct apk_database *db, struct apk_ostream *os);
diff --git a/src/database.c b/src/database.c
index 373acb6..3f67d4e 100644
--- a/src/database.c
+++ b/src/database.c
@@ -135,6 +135,12 @@ static struct apk_db_dir *apk_db_dir_get(struct apk_db_dir *dir)
return dir;
}
+static struct apk_db_dir *apk_db_dir_query(struct apk_database *db,
+ apk_blob_t name)
+{
+ return (struct apk_db_dir *) apk_hash_get(&db->installed.dirs, name);
+}
+
static struct apk_db_dir *apk_db_dir_get_db(struct apk_database *db,
apk_blob_t name)
{
@@ -145,7 +151,7 @@ static struct apk_db_dir *apk_db_dir_get_db(struct apk_database *db,
if (name.len && name.ptr[name.len-1] == '/')
name.len--;
- dir = (struct apk_db_dir *) apk_hash_get(&db->installed.dirs, name);
+ dir = apk_db_dir_query(db, name);
if (dir != NULL)
return apk_db_dir_get(dir);
@@ -643,6 +649,8 @@ static int apk_db_write_config(struct apk_database *db)
if (os == NULL)
return -1;
n = apk_deps_format(buf, sizeof(buf), db->world);
+ if (n < sizeof(buf))
+ buf[n++] = '\n';
os->write(os, buf, n);
os->close(os);
@@ -677,7 +685,6 @@ void apk_db_close(struct apk_database *db)
}
}
-
for (i = 0; i < db->num_repos; i++)
free(db->repos[i].url);
for (i = 0; i < db->protected_paths->num; i++)
@@ -700,6 +707,33 @@ struct apk_package *apk_db_get_pkg(struct apk_database *db, csum_t sum)
APK_BLOB_PTR_LEN((void*) sum, sizeof(csum_t)));
}
+struct apk_package *apk_db_get_file_owner(struct apk_database *db,
+ apk_blob_t filename)
+{
+ apk_blob_t dir, file;
+ struct apk_db_dir *ddir;
+ struct apk_db_file *dfile;
+ struct hlist_node *cur;
+
+ if (!apk_blob_rsplit(filename, '/', &dir, &file))
+ return NULL;
+
+ if (dir.ptr[0] == '/')
+ dir.ptr++, dir.len--;
+
+ ddir = apk_db_dir_query(db, dir);
+ if (ddir == NULL)
+ return NULL;
+
+ hlist_for_each_entry(dfile, cur, &ddir->files, dir_files_list) {
+ if (strncmp(dfile->filename, file.ptr, file.len) == 0 &&
+ dfile->filename[file.len] == 0)
+ return dfile->diri->pkg;
+ }
+
+ return NULL;
+}
+
struct apk_package *apk_db_pkg_add_file(struct apk_database *db, const char *file)
{
struct apk_package *info;
@@ -901,7 +935,7 @@ static int apk_db_install_archive_entry(void *_ctx,
ctx->diri = diri;
}
- file = apk_db_file_get(db, name, ctx);
+ file = apk_db_file_get(db, bfile, ctx);
if (file == NULL) {
apk_error("%s: Failed to create fdb entry for '%*s'\n",
pkg->name->name, name.len, name.ptr);
diff --git a/src/info.c b/src/info.c
index 2e41742..c981c18 100644
--- a/src/info.c
+++ b/src/info.c
@@ -54,6 +54,38 @@ static int info_exists(struct apk_database *db, int argc, char **argv)
return 0;
}
+static int info_who_owns(struct apk_database *db, int argc, char **argv)
+{
+ struct apk_package *pkg;
+ struct apk_dependency_array *deps = NULL;
+ struct apk_dependency dep;
+ int i;
+
+ for (i = 0; i < argc; i++) {
+ pkg = apk_db_get_file_owner(db, APK_BLOB_STR(argv[i]));
+ if (pkg == NULL)
+ continue;
+
+ if (apk_quiet) {
+ dep = (struct apk_dependency) {
+ .name = pkg->name,
+ };
+ apk_deps_add(&deps, &dep);
+ } else {
+ printf("%s is owned by %s-%s\n", argv[i],
+ pkg->name->name, pkg->version);
+ }
+ }
+ if (apk_quiet && deps != NULL) {
+ char buf[512];
+ apk_deps_format(buf, sizeof(buf), deps);
+ printf("%s\n", buf);
+ free(deps);
+ }
+
+ return 0;
+}
+
static int info_parse(void *ctx, int optch, int optindex, const char *optarg)
{
struct info_ctx *ictx = (struct info_ctx *) ctx;
@@ -62,6 +94,9 @@ static int info_parse(void *ctx, int optch, int optindex, const char *optarg)
case 'e':
ictx->action = info_exists;
break;
+ case 'W':
+ ictx->action = info_who_owns;
+ break;
default:
return -1;
}
@@ -88,6 +123,7 @@ static int info_main(void *ctx, int argc, char **argv)
static struct option info_options[] = {
{ "installed", no_argument, NULL, 'e' },
+ { "who-owns", no_argument, NULL, 'W' },
};
static struct apk_applet apk_info = {
diff --git a/src/package.c b/src/package.c
index 40fc871..59ca93a 100644
--- a/src/package.c
+++ b/src/package.c
@@ -141,13 +141,13 @@ int apk_deps_format(char *buf, int size,
if (depends == NULL)
return 0;
- for (i = 0; i < depends->num - 1; i++)
+ for (i = 0; i < depends->num; i++) {
+ if (i && n < size)
+ buf[n++] = ' ';
n += snprintf(&buf[n], size-n,
- "%s ",
+ "%s",
depends->item[i].name->name);
- n += snprintf(&buf[n], size-n,
- "%s\n",
- depends->item[i].name->name);
+ }
return n;
}
@@ -545,6 +545,8 @@ apk_blob_t apk_pkg_format_index_entry(struct apk_package *info, int size,
if (info->depends != NULL) {
n += snprintf(&buf[n], size-n, "D:");
n += apk_deps_format(&buf[n], size-n, info->depends);
+ if (n < size)
+ buf[n++] = '\n';
}
n += snprintf(&buf[n], size-n, "C:");
n += apk_hexdump_format(size-n, &buf[n],