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
|
- confirm whether to act (show changeset-size, installed, removed) if
|
||||||
other packages affected then the ones explicitly specified
|
other packages affected then the ones explicitly specified
|
||||||
|
|
||||||
|
@ -19,6 +16,9 @@
|
||||||
- Error handling and rollback
|
- Error handling and rollback
|
||||||
- Dependency manipulation API: deletion, overwrite, check compatibility
|
- 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
|
- New user/group creation
|
||||||
|
|
||||||
- Non-trivial solution finder
|
- 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_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_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);
|
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;
|
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,
|
static struct apk_db_dir *apk_db_dir_get_db(struct apk_database *db,
|
||||||
apk_blob_t name)
|
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] == '/')
|
if (name.len && name.ptr[name.len-1] == '/')
|
||||||
name.len--;
|
name.len--;
|
||||||
|
|
||||||
dir = (struct apk_db_dir *) apk_hash_get(&db->installed.dirs, name);
|
dir = apk_db_dir_query(db, name);
|
||||||
if (dir != NULL)
|
if (dir != NULL)
|
||||||
return apk_db_dir_get(dir);
|
return apk_db_dir_get(dir);
|
||||||
|
|
||||||
|
@ -643,6 +649,8 @@ static int apk_db_write_config(struct apk_database *db)
|
||||||
if (os == NULL)
|
if (os == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
n = apk_deps_format(buf, sizeof(buf), db->world);
|
n = apk_deps_format(buf, sizeof(buf), db->world);
|
||||||
|
if (n < sizeof(buf))
|
||||||
|
buf[n++] = '\n';
|
||||||
os->write(os, buf, n);
|
os->write(os, buf, n);
|
||||||
os->close(os);
|
os->close(os);
|
||||||
|
|
||||||
|
@ -677,7 +685,6 @@ void apk_db_close(struct apk_database *db)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < db->num_repos; i++)
|
for (i = 0; i < db->num_repos; i++)
|
||||||
free(db->repos[i].url);
|
free(db->repos[i].url);
|
||||||
for (i = 0; i < db->protected_paths->num; i++)
|
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)));
|
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 *apk_db_pkg_add_file(struct apk_database *db, const char *file)
|
||||||
{
|
{
|
||||||
struct apk_package *info;
|
struct apk_package *info;
|
||||||
|
@ -901,7 +935,7 @@ static int apk_db_install_archive_entry(void *_ctx,
|
||||||
ctx->diri = diri;
|
ctx->diri = diri;
|
||||||
}
|
}
|
||||||
|
|
||||||
file = apk_db_file_get(db, name, ctx);
|
file = apk_db_file_get(db, bfile, ctx);
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
apk_error("%s: Failed to create fdb entry for '%*s'\n",
|
apk_error("%s: Failed to create fdb entry for '%*s'\n",
|
||||||
pkg->name->name, name.len, name.ptr);
|
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;
|
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)
|
static int info_parse(void *ctx, int optch, int optindex, const char *optarg)
|
||||||
{
|
{
|
||||||
struct info_ctx *ictx = (struct info_ctx *) ctx;
|
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':
|
case 'e':
|
||||||
ictx->action = info_exists;
|
ictx->action = info_exists;
|
||||||
break;
|
break;
|
||||||
|
case 'W':
|
||||||
|
ictx->action = info_who_owns;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -88,6 +123,7 @@ static int info_main(void *ctx, int argc, char **argv)
|
||||||
|
|
||||||
static struct option info_options[] = {
|
static struct option info_options[] = {
|
||||||
{ "installed", no_argument, NULL, 'e' },
|
{ "installed", no_argument, NULL, 'e' },
|
||||||
|
{ "who-owns", no_argument, NULL, 'W' },
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct apk_applet apk_info = {
|
static struct apk_applet apk_info = {
|
||||||
|
|
|
@ -141,13 +141,13 @@ int apk_deps_format(char *buf, int size,
|
||||||
if (depends == NULL)
|
if (depends == NULL)
|
||||||
return 0;
|
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,
|
n += snprintf(&buf[n], size-n,
|
||||||
"%s ",
|
"%s",
|
||||||
depends->item[i].name->name);
|
depends->item[i].name->name);
|
||||||
n += snprintf(&buf[n], size-n,
|
}
|
||||||
"%s\n",
|
|
||||||
depends->item[i].name->name);
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,6 +545,8 @@ apk_blob_t apk_pkg_format_index_entry(struct apk_package *info, int size,
|
||||||
if (info->depends != NULL) {
|
if (info->depends != NULL) {
|
||||||
n += snprintf(&buf[n], size-n, "D:");
|
n += snprintf(&buf[n], size-n, "D:");
|
||||||
n += apk_deps_format(&buf[n], size-n, info->depends);
|
n += apk_deps_format(&buf[n], size-n, info->depends);
|
||||||
|
if (n < size)
|
||||||
|
buf[n++] = '\n';
|
||||||
}
|
}
|
||||||
n += snprintf(&buf[n], size-n, "C:");
|
n += snprintf(&buf[n], size-n, "C:");
|
||||||
n += apk_hexdump_format(size-n, &buf[n],
|
n += apk_hexdump_format(size-n, &buf[n],
|
||||||
|
|
Loading…
Reference in New Issue