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.cute-signatures
parent
c831ead63c
commit
b7f9f9bdb2
6
TODO
6
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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
36
src/info.c
36
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 = {
|
||||
|
|
|
@ -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],
|
||||
|
|
Loading…
Reference in New Issue