New pkgdb (0.21) and repo index (1.7) format, see NEWS for info.

This commit is contained in:
Juan RP
2013-03-05 04:08:42 +01:00
parent 76c9eae37c
commit 7c1a0ac3e8
46 changed files with 1021 additions and 1045 deletions

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2009-2012 Juan Romero Pardines.
* Copyright (c) 2009-2013 Juan Romero Pardines.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -48,24 +48,34 @@ static void *
pkgdb_thread_worker(void *arg)
{
prop_dictionary_t pkgd;
prop_array_t array;
prop_object_t obj;
struct thread_data *thd = arg;
const char *pkgname, *pkgver;
const char *pkgver;
char *pkgname;
unsigned int i;
int rv;
array = prop_dictionary_all_keys(thd->xhp->pkgdb);
assert(array);
/* process pkgs from start until end */
for (i = thd->start; i < thd->end; i++) {
pkgd = prop_array_get(thd->xhp->pkgdb, i);
prop_dictionary_get_cstring_nocopy(pkgd, "pkgname", &pkgname);
obj = prop_array_get(array, i);
pkgd = prop_dictionary_get_keysym(thd->xhp->pkgdb, obj);
prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
if (thd->xhp->flags & XBPS_FLAG_VERBOSE)
printf("Checking %s ...\n", pkgver);
pkgname = xbps_pkg_name(pkgver);
assert(pkgname);
rv = check_pkg_integrity(thd->xhp, pkgd, pkgname);
free(pkgname);
if (rv != 0)
fprintf(stderr, "pkgdb[%d] failed for %s: %s\n",
thd->thread_num, pkgver, strerror(rv));
}
prop_object_release(array);
return NULL;
}
@ -84,7 +94,7 @@ check_pkg_integrity_all(struct xbps_handle *xhp)
thd = calloc(maxthreads, sizeof(*thd));
assert(thd);
slicecount = prop_array_count(xhp->pkgdb) / maxthreads;
slicecount = prop_dictionary_count(xhp->pkgdb) / maxthreads;
pkgcount = 0;
for (i = 0; i < maxthreads; i++) {
@ -92,7 +102,7 @@ check_pkg_integrity_all(struct xbps_handle *xhp)
thd[i].xhp = xhp;
thd[i].start = pkgcount;
if (i + 1 >= maxthreads)
thd[i].end = prop_array_count(xhp->pkgdb);
thd[i].end = prop_dictionary_count(xhp->pkgdb);
else
thd[i].end = pkgcount + slicecount;
pthread_create(&thd[i].thread, NULL,
@ -141,13 +151,8 @@ check_pkg_integrity(struct xbps_handle *xhp,
propsd = prop_dictionary_internalize_from_file(buf);
free(buf);
if (propsd == NULL) {
printf("%s: unexistent metafile, converting to 0.18 "
"format...\n", pkgname);
if ((rv = convert_pkgd_metadir(xhp, opkgd)) != 0)
return rv;
return 0;
xbps_error_printf("%s: unexistent metafile!\n", pkgname);
return EINVAL;
} else if (prop_dictionary_count(propsd) == 0) {
xbps_error_printf("%s: incomplete metadata file.\n", pkgname);
prop_object_release(propsd);

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2012 Juan Romero Pardines.
* Copyright (c) 2013 Juan Romero Pardines.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -38,136 +38,81 @@
#include <xbps_api.h>
#include "defs.h"
static prop_data_t
create_script_blob(struct xbps_handle *xhp,
const char *file,
const char *pkgname)
{
prop_data_t data;
struct stat st;
void *mf;
char *buf;
int fd;
buf = xbps_xasprintf("%s/metadata/%s/%s", xhp->metadir, pkgname, file);
if ((fd = open(buf, O_RDONLY)) == -1) {
free(buf);
if (errno != ENOENT)
fprintf(stderr, "%s: can't read INSTALL script: %s\n",
pkgname, strerror(errno));
return NULL;
}
if (stat(buf, &st) == -1) {
free(buf);
fprintf(stderr, "%s: failed to stat %s script: %s\n",
pkgname, file, strerror(errno));
return NULL;
}
free(buf);
mf = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (mf == MAP_FAILED) {
close(fd);
fprintf(stderr, "%s: failed to map INSTALL script: %s\n",
pkgname, strerror(errno));
return NULL;
}
data = prop_data_create_data(mf, st.st_size);
munmap(mf, st.st_size);
return data;
}
/*
* Converts package metadata format to 0.18.
* Convert pkgdb format to 0.21.
*/
int
convert_pkgd_metadir(struct xbps_handle *xhp, prop_dictionary_t pkgd)
static void
pkgdb_format_021(struct xbps_handle *xhp, const char *plist_new)
{
prop_dictionary_t filesd, propsd;
prop_array_t array;
prop_data_t data;
const char *pkgname;
char *buf, *sha256, *propsf, *filesf;
prop_array_t array, rdeps;
prop_dictionary_t pkgdb, pkgd;
size_t i;
char *pkgname, *plist;
prop_dictionary_get_cstring_nocopy(pkgd, "pkgname", &pkgname);
/* Merge XBPS_PKGFILES */
propsf = xbps_xasprintf("%s/metadata/%s/%s", xhp->metadir,
pkgname, XBPS_PKGPROPS);
propsd = prop_dictionary_internalize_from_zfile(propsf);
assert(propsd);
filesf = xbps_xasprintf("%s/metadata/%s/%s", xhp->metadir,
pkgname, XBPS_PKGFILES);
filesd = prop_dictionary_internalize_from_zfile(filesf);
assert(filesd);
array = prop_dictionary_get(filesd, "files");
if (array && prop_array_count(array))
prop_dictionary_set(propsd, "files", array);
array = prop_dictionary_get(filesd, "conf_files");
if (array && prop_array_count(array))
prop_dictionary_set(propsd, "conf_files", array);
array = prop_dictionary_get(filesd, "dirs");
if (array && prop_array_count(array))
prop_dictionary_set(propsd, "dirs", array);
array = prop_dictionary_get(filesd, "links");
if (array && prop_array_count(array))
prop_dictionary_set(propsd, "links", array);
prop_object_release(filesd);
/* Merge INSTALL script */
if ((data = create_script_blob(xhp, "INSTALL", pkgname))) {
prop_dictionary_set(propsd, "install-script", data);
prop_object_release(data);
plist = xbps_xasprintf("%s/pkgdb.plist", xhp->metadir);
if (access(plist, R_OK) == -1) {
if (errno == ENOENT) {
/* missing file, no conversion needed */
free(plist);
return;
}
xbps_error_printf("cannot read %s: %s\n",
plist, strerror(errno));
exit(EXIT_FAILURE);
}
/* Merge REMOVE script */
if ((data = create_script_blob(xhp, "REMOVE", pkgname))) {
prop_dictionary_set(propsd, "remove-script", data);
prop_object_release(data);
array = prop_array_internalize_from_zfile(plist);
if (prop_object_type(array) != PROP_TYPE_ARRAY) {
xbps_error_printf("unknown object type for %s\n",
plist, strerror(errno));
exit(EXIT_FAILURE);
}
/* Externalize pkg metaplist */
buf = xbps_xasprintf("%s/.%s.plist", xhp->metadir, pkgname);
if (!prop_dictionary_externalize_to_file(propsd, buf)) {
fprintf(stderr, "%s: can't externalize plist: %s\n",
pkgname, strerror(errno));
return -1;
pkgdb = prop_dictionary_create();
assert(pkgdb);
for (i = 0; i < prop_array_count(array); i++) {
pkgd = prop_array_get(array, i);
prop_dictionary_get_cstring(pkgd, "pkgname", &pkgname);
rdeps = prop_dictionary_get(pkgd, "run_depends");
/* remove unneeded objs */
prop_dictionary_remove(pkgd, "pkgname");
prop_dictionary_remove(pkgd, "version");
if (prop_array_count(rdeps) == 0)
prop_dictionary_remove(pkgd, "run_depends");
prop_dictionary_set(pkgdb, pkgname, pkgd);
free(pkgname);
}
/* create sha256 hash for pkg plist */
sha256 = xbps_file_hash(buf);
free(buf);
assert(sha256);
prop_dictionary_set_cstring(pkgd, "metafile-sha256", sha256);
free(sha256);
/* Remove old files/dir */
if ((remove(propsf) == -1) || (remove(filesf) == -1))
fprintf(stderr, "%s: failed to remove %s: %s\n",
pkgname, propsf, strerror(errno));
if (prop_array_count(array) != prop_dictionary_count(pkgdb)) {
xbps_error_printf("failed conversion! unmatched obj count "
"(got %zu, need %zu)\n", prop_dictionary_count(pkgdb),
prop_array_count(array));
exit(EXIT_FAILURE);
}
buf = xbps_xasprintf("%s/metadata/%s/INSTALL", xhp->metadir, pkgname);
if (access(buf, R_OK) == 0)
remove(buf);
free(buf);
if (!prop_dictionary_externalize_to_file(pkgdb, plist_new)) {
xbps_error_printf("failed to write %s: %s\n",
plist_new, strerror(errno));
exit(EXIT_FAILURE);
}
buf = xbps_xasprintf("%s/metadata/%s/REMOVE", xhp->metadir, pkgname);
if (access(buf, R_OK) == 0)
remove(buf);
free(buf);
prop_object_release(array);
prop_object_release(pkgdb);
free(plist);
buf = xbps_xasprintf("%s/metadata/%s", xhp->metadir, pkgname);
remove(buf);
free(buf);
buf = xbps_xasprintf("%s/metadata", xhp->metadir);
remove(buf);
free(buf);
return 0;
printf("Conversion to 0.21 pkgdb format successfully\n");
}
void
convert_pkgdb_format(struct xbps_handle *xhp)
{
char *plist;
plist = xbps_xasprintf("%s/%s", xhp->metadir, XBPS_PKGDB);
if ((access(plist, R_OK) == -1) && (errno == ENOENT))
pkgdb_format_021(xhp, plist);
free(plist);
}

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2012 Juan Romero Pardines.
* Copyright (c) 2012-2013 Juan Romero Pardines.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -42,6 +42,6 @@ CHECK_PKG_DECL(rundeps);
CHECK_PKG_DECL(symlinks);
/* from convert.c */
int convert_pkgd_metadir(struct xbps_handle *, prop_dictionary_t);
void convert_pkgdb_format(struct xbps_handle *);
#endif /* !_XBPS_PKGDB_DEFS_H_ */

View File

@ -46,6 +46,7 @@ usage(bool fail)
" -h --help Print usage help\n"
" -m --mode <auto|manual> Change PKGNAME to automatic or manual mode\n"
" -r --rootdir <dir> Full path to rootdir\n"
" -u --update Update pkgdb to the latest format\n"
" -v --verbose Verbose messages\n"
" -V --version Show XBPS version\n");
exit(fail ? EXIT_FAILURE : EXIT_SUCCESS);
@ -73,7 +74,7 @@ change_pkg_instmode(struct xbps_handle *xhp,
int
main(int argc, char **argv)
{
const char *shortopts = "aC:dhm:r:Vv";
const char *shortopts = "aC:dhm:r:uVv";
const struct option longopts[] = {
{ "all", no_argument, NULL, 'a' },
{ "config", required_argument, NULL, 'C' },
@ -81,6 +82,7 @@ main(int argc, char **argv)
{ "help", no_argument, NULL, 'h' },
{ "mode", required_argument, NULL, 'm' },
{ "rootdir", required_argument, NULL, 'r' },
{ "update", no_argument, NULL, 'u' },
{ "verbose", no_argument, NULL, 'v' },
{ "version", no_argument, NULL, 'V' },
{ NULL, 0, NULL, 0 }
@ -88,7 +90,7 @@ main(int argc, char **argv)
struct xbps_handle xh;
const char *conffile = NULL, *rootdir = NULL, *instmode = NULL;
int c, i, rv, flags = 0;
bool all = false;
bool update_format = false, all = false;
while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) {
switch (c) {
@ -110,6 +112,9 @@ main(int argc, char **argv)
case 'r':
rootdir = optarg;
break;
case 'u':
update_format = true;
break;
case 'v':
flags |= XBPS_FLAG_VERBOSE;
break;
@ -122,7 +127,7 @@ main(int argc, char **argv)
/* NOTREACHED */
}
}
if (!all && (argc == optind))
if (!update_format && !all && (argc == optind))
usage(true);
memset(&xh, 0, sizeof(xh));
@ -136,7 +141,9 @@ main(int argc, char **argv)
exit(EXIT_FAILURE);
}
if (instmode) {
if (update_format)
convert_pkgdb_format(&xh);
else if (instmode) {
if ((strcmp(instmode, "auto")) && (strcmp(instmode, "manual")))
usage(true);

View File

@ -1,4 +1,4 @@
.Dd February 20, 2013
.Dd March 4, 2013
.Os Void Linux
.Dt xbps-pkgdb 8
.Sh NAME
@ -13,7 +13,8 @@ The
.Nm
utility can check/fix issues and modify the package database (pkgdb).
It's able to check for missing dependencies, modified files and symlinks,
and more errors that have been fixed in newer versions of xbps.
and more errors that have been fixed in newer versions of xbps. A mode to update
the format to the latest version is also available.
This is the list of things that
.Nm
currently does:
@ -29,6 +30,8 @@ Checks that all required dependencies for a package are resolved.
.It Sy OBSOLETE METADATA CHECK
Checks that the package database does not contain obsolete data from previous
XBPS versions and removes them if found.
.It Sy FORMAT CONVERSION
Updates the pkgdb format to the latest version.
.Sh OPTIONS
.Bl -tag -width -x
.It Fl a, Fl -all
@ -45,14 +48,23 @@ Switches
to the specified installation mode: automatic or manual mode.
.It Fl r, Fl -rootdir Ar dir
Specifies a full path for the target root directory.
.It Fl u, Fl -update
Updates the pkgdb format to the latest version making the necessary conversions
automatically. Usually this is needed only in rare circumstances.
.It Fl v, Fl -verbose
Enables verbose messages.
.It Fl V, Fl -version
Shows the XBPS version.
.Sh FILES
.Bl -tag -width xxxxxxxxxxxxxxxxxxxx
.Bl -tag -width /var/db/xbps/.<pkgname>.plist
.It Ar /etc/xbps/xbps.conf
Default XBPS configuration file.
Default configuration file.
.It Ar /var/db/xbps/.<pkgname>.plist
Package metadata properties.
.It Ar /var/db/xbps/pkgdb-0.21.plist
Default package database (0.21 format). Keeps track of installed packages and properties.
.It Ar /var/cache/xbps
Default cache directory to store downloaded binary packages.
.Sh SEE ALSO
.Xr xbps-create 8 ,
.Xr xbps-dgraph 8 ,