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

30
NEWS
View File

@ -1,5 +1,35 @@
xbps-0.21 (???): xbps-0.21 (???):
* xbps-query(8): a full dependency tree can now be shown in the
show-deps mode, by specifying -x twice (--show-deps), e.g:
$ xbps-query -xx perl
glibc>=2.8_1
gdbm>=1.10_1_1
glibc>=2.8_1
libdb>=4.8.24_1
glibc>=2.8_1
$
* When running a full system upgrade (xbps-install -u) check if there's
any update to the xbps package, and if true, update this only in
the running transaction. This ensures that we update the package
manager without any trouble in pkgdb.
* New repository index format (1.7): unnecessary and redundant objects
have been removed that are already stored in package metadata files.
This means that xbps-query(8) in repository mode will now fetch package
metadata from the binary package and not from index. Only necessary objects
for the transaction and searching are kept.
* xbps-pkgdb(8): new option -u --update to update the pkgdb format to
the latest available. Do not forget to run it after updating xbps to 0.21.
* New pkgdb format: redundant objects have been removed (empty run_depends,
pkgname, version) and it is now a dictionary. The pkgdb file has been
renamed to "pkgdb-0.21.plist" to make future upgrades easier to
handle/update.
* configure: misc tweaks to allow building with the musl C library. * configure: misc tweaks to allow building with the musl C library.
* xbps-query(8): packages can be matched by using virtual package * xbps-query(8): packages can be matched by using virtual package

1
TODO
View File

@ -1,7 +1,6 @@
libxbps: libxbps:
- transaction: avoid fetching the whole pkg when updating and only fetch - transaction: avoid fetching the whole pkg when updating and only fetch
modified files from target pkg. modified files from target pkg.
- properties: (update-first) still unimplemented.
- Add support to handle 'shlib-requires' and 'shlib-provides'. - Add support to handle 'shlib-requires' and 'shlib-provides'.
xbps-create: xbps-create:

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2011-2012 Juan Romero Pardines. * Copyright (c) 2011-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -27,6 +27,7 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <syslog.h> #include <syslog.h>
#include <assert.h>
#include <xbps_api.h> #include <xbps_api.h>
#include "defs.h" #include "defs.h"
@ -34,7 +35,8 @@ void
state_cb(struct xbps_state_cb_data *xscd, void *cbdata) state_cb(struct xbps_state_cb_data *xscd, void *cbdata)
{ {
prop_dictionary_t pkgd; prop_dictionary_t pkgd;
const char *version; const char *instver, *newver;
char *pkgname;
bool syslog_enabled = false; bool syslog_enabled = false;
(void)cbdata; (void)cbdata;
@ -59,36 +61,44 @@ state_cb(struct xbps_state_cb_data *xscd, void *cbdata)
printf("\n[*] Configuring unpacked packages\n"); printf("\n[*] Configuring unpacked packages\n");
break; break;
case XBPS_STATE_REPOSYNC: case XBPS_STATE_REPOSYNC:
printf("[*] Updating `%s' ...\n", xscd->arg0); printf("[*] Updating `%s' ...\n", xscd->arg);
break; break;
case XBPS_STATE_VERIFY: case XBPS_STATE_VERIFY:
printf("%s: checking binary pkg integrity ...\n", xscd->arg0); printf("%s: checking binary pkg integrity ...\n", xscd->arg);
break;
case XBPS_STATE_XBPS_UPDATE:
printf("A new update for xbps has been found; this package "
"must be updated independently. After this update you can "
"continue updating your system.\n\n");
break; break;
case XBPS_STATE_CONFIG_FILE: case XBPS_STATE_CONFIG_FILE:
if (xscd->desc != NULL) if (xscd->desc != NULL)
printf("%s\n", xscd->desc); printf("%s\n", xscd->desc);
break; break;
case XBPS_STATE_REMOVE: case XBPS_STATE_REMOVE:
printf("%s-%s: removing ...\n", xscd->arg0, xscd->arg1); printf("%s: removing ...\n", xscd->arg);
break; break;
case XBPS_STATE_CONFIGURE: case XBPS_STATE_CONFIGURE:
printf("%s-%s: configuring ...\n", xscd->arg0, xscd->arg1); printf("%s: configuring ...\n", xscd->arg);
break; break;
case XBPS_STATE_REGISTER: case XBPS_STATE_REGISTER:
case XBPS_STATE_UNREGISTER: case XBPS_STATE_UNREGISTER:
/* empty */ /* empty */
break; break;
case XBPS_STATE_UNPACK: case XBPS_STATE_UNPACK:
printf("%s-%s: unpacking ...\n", xscd->arg0, xscd->arg1); printf("%s: unpacking ...\n", xscd->arg);
break; break;
case XBPS_STATE_INSTALL: case XBPS_STATE_INSTALL:
/* empty */ /* empty */
break; break;
case XBPS_STATE_UPDATE: case XBPS_STATE_UPDATE:
pkgd = xbps_pkgdb_get_pkg(xscd->xhp, xscd->arg0); pkgname = xbps_pkg_name(xscd->arg);
prop_dictionary_get_cstring_nocopy(pkgd, "version", &version); assert(pkgname);
printf("%s-%s: updating to %s ...\n", xscd->arg0, newver = xbps_pkg_version(xscd->arg);
version, xscd->arg1); pkgd = xbps_pkgdb_get_pkg(xscd->xhp, pkgname);
prop_dictionary_get_cstring_nocopy(pkgd, "version", &instver);
printf("%s-%s: updating to %s ...\n", pkgname, instver, newver);
free(pkgname);
break; break;
/* success */ /* success */
case XBPS_STATE_REMOVE_FILE: case XBPS_STATE_REMOVE_FILE:
@ -101,27 +111,24 @@ state_cb(struct xbps_state_cb_data *xscd, void *cbdata)
} }
break; break;
case XBPS_STATE_INSTALL_DONE: case XBPS_STATE_INSTALL_DONE:
printf("%s-%s: installed successfully.\n", printf("%s: installed successfully.\n", xscd->arg);
xscd->arg0, xscd->arg1);
if (syslog_enabled) if (syslog_enabled)
syslog(LOG_NOTICE, "Installed `%s-%s' successfully " syslog(LOG_NOTICE, "Installed `%s' successfully "
"(rootdir: %s).", xscd->arg0, xscd->arg1, "(rootdir: %s).", xscd->arg,
xscd->xhp->rootdir); xscd->xhp->rootdir);
break; break;
case XBPS_STATE_UPDATE_DONE: case XBPS_STATE_UPDATE_DONE:
printf("%s-%s: updated successfully.\n", printf("%s: updated successfully.\n", xscd->arg);
xscd->arg0, xscd->arg1);
if (syslog_enabled) if (syslog_enabled)
syslog(LOG_NOTICE, "Updated `%s' to `%s' successfully " syslog(LOG_NOTICE, "Updated `%s' successfully "
"(rootdir: %s).", xscd->arg0, xscd->arg1, "(rootdir: %s).", xscd->arg,
xscd->xhp->rootdir); xscd->xhp->rootdir);
break; break;
case XBPS_STATE_REMOVE_DONE: case XBPS_STATE_REMOVE_DONE:
printf("%s-%s: removed successfully.\n", printf("%s: removed successfully.\n", xscd->arg);
xscd->arg0, xscd->arg1);
if (syslog_enabled) if (syslog_enabled)
syslog(LOG_NOTICE, "Removed `%s-%s' successfully " syslog(LOG_NOTICE, "Removed `%s' successfully "
"(rootdir: %s).", xscd->arg0, xscd->arg1, "(rootdir: %s).", xscd->arg,
xscd->xhp->rootdir); xscd->xhp->rootdir);
break; break;
/* errors */ /* errors */
@ -152,7 +159,7 @@ state_cb(struct xbps_state_cb_data *xscd, void *cbdata)
break; break;
default: default:
xbps_dbg_printf(xscd->xhp, xbps_dbg_printf(xscd->xhp,
"unknown state %d\n", xscd->state); "%s: unknown state %d\n", xscd->arg, xscd->state);
break; break;
} }
} }

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2009-2012 Juan Romero Pardines. * Copyright (c) 2009-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -75,20 +75,18 @@ static void
show_actions(prop_object_iterator_t iter) show_actions(prop_object_iterator_t iter)
{ {
prop_object_t obj; prop_object_t obj;
const char *repoloc, *trans, *pkgname, *version, *fname, *arch; const char *repoloc, *trans, *pkgver, *arch;
repoloc = trans = pkgname = version = fname = arch = NULL; repoloc = trans = pkgver = arch = NULL;
while ((obj = prop_object_iterator_next(iter)) != NULL) { while ((obj = prop_object_iterator_next(iter)) != NULL) {
prop_dictionary_get_cstring_nocopy(obj, "transaction", &trans); prop_dictionary_get_cstring_nocopy(obj, "transaction", &trans);
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
prop_dictionary_get_cstring_nocopy(obj, "version", &version);
printf("%s %s %s", pkgname, trans, version);
prop_dictionary_get_cstring_nocopy(obj, "repository", &repoloc);
prop_dictionary_get_cstring_nocopy(obj, "filename", &fname);
prop_dictionary_get_cstring_nocopy(obj, "architecture", &arch); prop_dictionary_get_cstring_nocopy(obj, "architecture", &arch);
if (repoloc && fname && arch) printf("%s %s %s", pkgver, arch, trans);
printf(" %s %s %s", repoloc, fname, arch); prop_dictionary_get_cstring_nocopy(obj, "repository", &repoloc);
if (repoloc)
printf(" %s", repoloc);
printf("\n"); printf("\n");
} }

View File

@ -1,4 +1,4 @@
.Dd February 20, 2013 .Dd March 4, 2013
.Os Void Linux .Os Void Linux
.Dt xbps-install 8 .Dt xbps-install 8
.Sh NAME .Sh NAME
@ -95,13 +95,13 @@ architecture.
.Sh FILES .Sh FILES
.Bl -tag -width /var/db/xbps/.<pkgname>.plist .Bl -tag -width /var/db/xbps/.<pkgname>.plist
.It Ar /etc/xbps/xbps.conf .It Ar /etc/xbps/xbps.conf
Default XBPS configuration file. Default configuration file.
.It Ar /var/db/xbps/.<pkgname>.plist .It Ar /var/db/xbps/.<pkgname>.plist
Package metadata properties. Package metadata properties.
.It Ar /var/db/xbps/pkgdb.plist .It Ar /var/db/xbps/pkgdb-0.21.plist
XBPS package database. Default package database (0.21 format). Keeps track of installed packages and properties.
.It Ar /var/cache/xbps .It Ar /var/cache/xbps
Default XBPS cache directory. Default cache directory to store downloaded binary packages.
.Sh SEE ALSO .Sh SEE ALSO
.Xr xbps-create 8 , .Xr xbps-create 8 ,
.Xr xbps-dgraph 8 , .Xr xbps-dgraph 8 ,

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2009-2012 Juan Romero Pardines. * Copyright (c) 2009-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -48,24 +48,34 @@ static void *
pkgdb_thread_worker(void *arg) pkgdb_thread_worker(void *arg)
{ {
prop_dictionary_t pkgd; prop_dictionary_t pkgd;
prop_array_t array;
prop_object_t obj;
struct thread_data *thd = arg; struct thread_data *thd = arg;
const char *pkgname, *pkgver; const char *pkgver;
char *pkgname;
unsigned int i; unsigned int i;
int rv; int rv;
array = prop_dictionary_all_keys(thd->xhp->pkgdb);
assert(array);
/* process pkgs from start until end */ /* process pkgs from start until end */
for (i = thd->start; i < thd->end; i++) { for (i = thd->start; i < thd->end; i++) {
pkgd = prop_array_get(thd->xhp->pkgdb, i); obj = prop_array_get(array, i);
prop_dictionary_get_cstring_nocopy(pkgd, "pkgname", &pkgname); pkgd = prop_dictionary_get_keysym(thd->xhp->pkgdb, obj);
prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver); prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
if (thd->xhp->flags & XBPS_FLAG_VERBOSE) if (thd->xhp->flags & XBPS_FLAG_VERBOSE)
printf("Checking %s ...\n", pkgver); printf("Checking %s ...\n", pkgver);
pkgname = xbps_pkg_name(pkgver);
assert(pkgname);
rv = check_pkg_integrity(thd->xhp, pkgd, pkgname); rv = check_pkg_integrity(thd->xhp, pkgd, pkgname);
free(pkgname);
if (rv != 0) if (rv != 0)
fprintf(stderr, "pkgdb[%d] failed for %s: %s\n", fprintf(stderr, "pkgdb[%d] failed for %s: %s\n",
thd->thread_num, pkgver, strerror(rv)); thd->thread_num, pkgver, strerror(rv));
} }
prop_object_release(array);
return NULL; return NULL;
} }
@ -84,7 +94,7 @@ check_pkg_integrity_all(struct xbps_handle *xhp)
thd = calloc(maxthreads, sizeof(*thd)); thd = calloc(maxthreads, sizeof(*thd));
assert(thd); assert(thd);
slicecount = prop_array_count(xhp->pkgdb) / maxthreads; slicecount = prop_dictionary_count(xhp->pkgdb) / maxthreads;
pkgcount = 0; pkgcount = 0;
for (i = 0; i < maxthreads; i++) { for (i = 0; i < maxthreads; i++) {
@ -92,7 +102,7 @@ check_pkg_integrity_all(struct xbps_handle *xhp)
thd[i].xhp = xhp; thd[i].xhp = xhp;
thd[i].start = pkgcount; thd[i].start = pkgcount;
if (i + 1 >= maxthreads) if (i + 1 >= maxthreads)
thd[i].end = prop_array_count(xhp->pkgdb); thd[i].end = prop_dictionary_count(xhp->pkgdb);
else else
thd[i].end = pkgcount + slicecount; thd[i].end = pkgcount + slicecount;
pthread_create(&thd[i].thread, NULL, pthread_create(&thd[i].thread, NULL,
@ -141,13 +151,8 @@ check_pkg_integrity(struct xbps_handle *xhp,
propsd = prop_dictionary_internalize_from_file(buf); propsd = prop_dictionary_internalize_from_file(buf);
free(buf); free(buf);
if (propsd == NULL) { if (propsd == NULL) {
printf("%s: unexistent metafile, converting to 0.18 " xbps_error_printf("%s: unexistent metafile!\n", pkgname);
"format...\n", pkgname); return EINVAL;
if ((rv = convert_pkgd_metadir(xhp, opkgd)) != 0)
return rv;
return 0;
} else if (prop_dictionary_count(propsd) == 0) { } else if (prop_dictionary_count(propsd) == 0) {
xbps_error_printf("%s: incomplete metadata file.\n", pkgname); xbps_error_printf("%s: incomplete metadata file.\n", pkgname);
prop_object_release(propsd); 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -38,136 +38,81 @@
#include <xbps_api.h> #include <xbps_api.h>
#include "defs.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 static void
convert_pkgd_metadir(struct xbps_handle *xhp, prop_dictionary_t pkgd) pkgdb_format_021(struct xbps_handle *xhp, const char *plist_new)
{ {
prop_dictionary_t filesd, propsd; prop_array_t array, rdeps;
prop_array_t array; prop_dictionary_t pkgdb, pkgd;
prop_data_t data; size_t i;
const char *pkgname; char *pkgname, *plist;
char *buf, *sha256, *propsf, *filesf;
prop_dictionary_get_cstring_nocopy(pkgd, "pkgname", &pkgname); plist = xbps_xasprintf("%s/pkgdb.plist", xhp->metadir);
if (access(plist, R_OK) == -1) {
/* Merge XBPS_PKGFILES */ if (errno == ENOENT) {
propsf = xbps_xasprintf("%s/metadata/%s/%s", xhp->metadir, /* missing file, no conversion needed */
pkgname, XBPS_PKGPROPS); free(plist);
propsd = prop_dictionary_internalize_from_zfile(propsf); return;
assert(propsd); }
xbps_error_printf("cannot read %s: %s\n",
filesf = xbps_xasprintf("%s/metadata/%s/%s", xhp->metadir, plist, strerror(errno));
pkgname, XBPS_PKGFILES); exit(EXIT_FAILURE);
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);
} }
/* Merge REMOVE script */
if ((data = create_script_blob(xhp, "REMOVE", pkgname))) { array = prop_array_internalize_from_zfile(plist);
prop_dictionary_set(propsd, "remove-script", data); if (prop_object_type(array) != PROP_TYPE_ARRAY) {
prop_object_release(data); 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); pkgdb = prop_dictionary_create();
if (!prop_dictionary_externalize_to_file(propsd, buf)) { assert(pkgdb);
fprintf(stderr, "%s: can't externalize plist: %s\n",
pkgname, strerror(errno)); for (i = 0; i < prop_array_count(array); i++) {
return -1; 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 (prop_array_count(array) != prop_dictionary_count(pkgdb)) {
if ((remove(propsf) == -1) || (remove(filesf) == -1)) xbps_error_printf("failed conversion! unmatched obj count "
fprintf(stderr, "%s: failed to remove %s: %s\n", "(got %zu, need %zu)\n", prop_dictionary_count(pkgdb),
pkgname, propsf, strerror(errno)); prop_array_count(array));
exit(EXIT_FAILURE);
}
buf = xbps_xasprintf("%s/metadata/%s/INSTALL", xhp->metadir, pkgname); if (!prop_dictionary_externalize_to_file(pkgdb, plist_new)) {
if (access(buf, R_OK) == 0) xbps_error_printf("failed to write %s: %s\n",
remove(buf); plist_new, strerror(errno));
free(buf); exit(EXIT_FAILURE);
}
buf = xbps_xasprintf("%s/metadata/%s/REMOVE", xhp->metadir, pkgname); prop_object_release(array);
if (access(buf, R_OK) == 0) prop_object_release(pkgdb);
remove(buf); free(plist);
free(buf);
buf = xbps_xasprintf("%s/metadata/%s", xhp->metadir, pkgname); printf("Conversion to 0.21 pkgdb format successfully\n");
remove(buf); }
free(buf);
void
buf = xbps_xasprintf("%s/metadata", xhp->metadir); convert_pkgdb_format(struct xbps_handle *xhp)
remove(buf); {
free(buf); char *plist;
return 0; 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -42,6 +42,6 @@ CHECK_PKG_DECL(rundeps);
CHECK_PKG_DECL(symlinks); CHECK_PKG_DECL(symlinks);
/* from convert.c */ /* 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_ */ #endif /* !_XBPS_PKGDB_DEFS_H_ */

View File

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

View File

@ -1,4 +1,4 @@
.Dd February 20, 2013 .Dd March 4, 2013
.Os Void Linux .Os Void Linux
.Dt xbps-pkgdb 8 .Dt xbps-pkgdb 8
.Sh NAME .Sh NAME
@ -13,7 +13,8 @@ The
.Nm .Nm
utility can check/fix issues and modify the package database (pkgdb). utility can check/fix issues and modify the package database (pkgdb).
It's able to check for missing dependencies, modified files and symlinks, 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 This is the list of things that
.Nm .Nm
currently does: currently does:
@ -29,6 +30,8 @@ Checks that all required dependencies for a package are resolved.
.It Sy OBSOLETE METADATA CHECK .It Sy OBSOLETE METADATA CHECK
Checks that the package database does not contain obsolete data from previous Checks that the package database does not contain obsolete data from previous
XBPS versions and removes them if found. XBPS versions and removes them if found.
.It Sy FORMAT CONVERSION
Updates the pkgdb format to the latest version.
.Sh OPTIONS .Sh OPTIONS
.Bl -tag -width -x .Bl -tag -width -x
.It Fl a, Fl -all .It Fl a, Fl -all
@ -45,14 +48,23 @@ Switches
to the specified installation mode: automatic or manual mode. to the specified installation mode: automatic or manual mode.
.It Fl r, Fl -rootdir Ar dir .It Fl r, Fl -rootdir Ar dir
Specifies a full path for the target root directory. 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 .It Fl v, Fl -verbose
Enables verbose messages. Enables verbose messages.
.It Fl V, Fl -version .It Fl V, Fl -version
Shows the XBPS version. Shows the XBPS version.
.Sh FILES .Sh FILES
.Bl -tag -width xxxxxxxxxxxxxxxxxxxx .Bl -tag -width /var/db/xbps/.<pkgname>.plist
.It Ar /etc/xbps/xbps.conf .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 .Sh SEE ALSO
.Xr xbps-create 8 , .Xr xbps-create 8 ,
.Xr xbps-dgraph 8 , .Xr xbps-dgraph 8 ,

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2009-2012 Juan Romero Pardines. * Copyright (c) 2009-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -33,9 +33,9 @@
#endif #endif
/* from show-deps.c */ /* from show-deps.c */
int show_pkg_deps(struct xbps_handle *, const char *); int show_pkg_deps(struct xbps_handle *, const char *, bool);
int show_pkg_revdeps(struct xbps_handle *, const char *); int show_pkg_revdeps(struct xbps_handle *, const char *);
int repo_show_pkg_deps(struct xbps_handle *, const char *); int repo_show_pkg_deps(struct xbps_handle *, const char *, bool);
int repo_show_pkg_revdeps(struct xbps_handle *, const char *); int repo_show_pkg_revdeps(struct xbps_handle *, const char *);
/* from show-info-files.c */ /* from show-info-files.c */
@ -56,8 +56,6 @@ int repo_ownedby(struct xbps_handle *, int, char **);
/* From list.c */ /* From list.c */
size_t get_maxcols(void); size_t get_maxcols(void);
int list_strings_sep_in_array(struct xbps_handle *,
prop_object_t, void *, bool *);
size_t find_longest_pkgver(struct xbps_handle *, prop_object_t); size_t find_longest_pkgver(struct xbps_handle *, prop_object_t);
int list_pkgs_in_dict(struct xbps_handle *, prop_object_t, void *, bool *); int list_pkgs_in_dict(struct xbps_handle *, prop_object_t, void *, bool *);

View File

@ -241,19 +241,3 @@ find_longest_pkgver(struct xbps_handle *xhp, prop_object_t o)
return ffl.len; return ffl.len;
} }
int
list_strings_sep_in_array(struct xbps_handle *xhp,
prop_object_t obj,
void *arg,
bool *loop_done)
{
const char *sep = arg;
(void)xhp;
(void)loop_done;
printf("%s%s\n", sep ? sep : "", prop_string_cstring_nocopy(obj));
return 0;
}

View File

@ -56,7 +56,7 @@ usage(bool fail)
" -s --search PATTERN(s) Search for packages matching PATTERN(s)\n" " -s --search PATTERN(s) Search for packages matching PATTERN(s)\n"
" -f --files Show files for PKGNAME\n" " -f --files Show files for PKGNAME\n"
" -p --property PROP,... Show properties for PKGNAME\n" " -p --property PROP,... Show properties for PKGNAME\n"
" -x --deps Show dependencies for PKGNAME\n" " -x --deps Show dependencies for PKGNAME (set it twice for a full dependency tree)\n"
" -X --revdeps Show reverse dependencies for PKGNAME\n"); " -X --revdeps Show reverse dependencies for PKGNAME\n");
exit(fail ? EXIT_FAILURE : EXIT_SUCCESS); exit(fail ? EXIT_FAILURE : EXIT_SUCCESS);
@ -90,16 +90,16 @@ main(int argc, char **argv)
}; };
struct xbps_handle xh; struct xbps_handle xh;
const char *rootdir, *cachedir, *conffile, *props, *defrepo; const char *rootdir, *cachedir, *conffile, *props, *defrepo;
int c, flags, rv; int c, flags, rv, show_deps = 0;
bool list_pkgs, list_repos, orphans, own; bool list_pkgs, list_repos, orphans, own;
bool list_manual, show_prop, show_files, show_deps, show_rdeps; bool list_manual, show_prop, show_files, show_rdeps;
bool show, search, repo_mode, opmode; bool show, search, repo_mode, opmode, fulldeptree;
rootdir = cachedir = conffile = defrepo = props = NULL; rootdir = cachedir = conffile = defrepo = props = NULL;
flags = rv = c = 0; flags = rv = c = 0;
list_pkgs = list_repos = orphans = search = own = false; list_pkgs = list_repos = orphans = search = own = false;
list_manual = show_prop = show_files = false; list_manual = show_prop = show_files = false;
show = show_deps = show_rdeps = false; show = show_rdeps = fulldeptree = false;
repo_mode = opmode = false; repo_mode = opmode = false;
while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) {
@ -157,7 +157,8 @@ main(int argc, char **argv)
printf("%s\n", XBPS_RELVER); printf("%s\n", XBPS_RELVER);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
case 'x': case 'x':
show_deps = opmode = true; show_deps++;
opmode = true;
break; break;
case 'X': case 'X':
show_rdeps = opmode = true; show_rdeps = opmode = true;
@ -234,10 +235,13 @@ main(int argc, char **argv)
} else if (show_deps) { } else if (show_deps) {
/* show-deps mode */ /* show-deps mode */
if (show_deps > 1)
fulldeptree = true;
if (repo_mode) if (repo_mode)
rv = repo_show_pkg_deps(&xh, argv[optind]); rv = repo_show_pkg_deps(&xh, argv[optind], fulldeptree);
else else
rv = show_pkg_deps(&xh, argv[optind]); rv = show_pkg_deps(&xh, argv[optind], fulldeptree);
} else if (show_rdeps) { } else if (show_rdeps) {
/* show-rdeps mode */ /* show-rdeps mode */

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2009-2012 Juan Romero Pardines. * Copyright (c) 2009-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -33,22 +33,64 @@
#include <xbps_api.h> #include <xbps_api.h>
#include "defs.h" #include "defs.h"
int static void
show_pkg_deps(struct xbps_handle *xhp, const char *pkgname) print_rdeps(struct xbps_handle *xhp, prop_array_t rdeps,
bool full, bool repo, bool origin, int *indent)
{ {
prop_dictionary_t propsd; prop_array_t currdeps;
int rv = 0; prop_dictionary_t pkgd;
const char *pkgdep;
size_t i;
int j;
assert(pkgname != NULL); if (!origin)
(*indent)++;
propsd = xbps_pkgdb_get_pkg_metadata(xhp, pkgname); for (i = 0; i < prop_array_count(rdeps); i++) {
if (propsd == NULL) prop_array_get_cstring_nocopy(rdeps, i, &pkgdep);
if (!origin || !full)
for (j = 0; j < *indent; j++)
putchar(' ');
printf("%s\n", pkgdep);
if (!full)
continue;
if (repo) {
pkgd = xbps_rpool_get_pkg(xhp, pkgdep);
if (pkgd == NULL)
pkgd = xbps_rpool_get_virtualpkg(xhp, pkgdep);
} else {
pkgd = xbps_pkgdb_get_pkg(xhp, pkgdep);
if (pkgd == NULL)
pkgd = xbps_pkgdb_get_virtualpkg(xhp, pkgdep);
}
if (pkgd != NULL) {
currdeps = prop_dictionary_get(pkgd, "run_depends");
if (currdeps != NULL)
print_rdeps(xhp, currdeps,
full, repo, false, indent);
}
}
(*indent)--;
}
int
show_pkg_deps(struct xbps_handle *xhp, const char *pkgname, bool full)
{
prop_array_t rdeps;
prop_dictionary_t pkgd;
int indent = 0;
pkgd = xbps_pkgdb_get_pkg(xhp, pkgname);
if (pkgd == NULL)
return ENOENT; return ENOENT;
rv = xbps_callback_array_iter_in_dict(xhp, propsd, "run_depends", rdeps = prop_dictionary_get(pkgd, "run_depends");
list_strings_sep_in_array, NULL); if (rdeps != NULL)
print_rdeps(xhp, rdeps, full, false, true, &indent);
return rv; return 0;
} }
int int
@ -58,8 +100,7 @@ show_pkg_revdeps(struct xbps_handle *xhp, const char *pkg)
const char *pkgdep; const char *pkgdep;
size_t i; size_t i;
reqby = xbps_pkgdb_get_pkg_revdeps(xhp, pkg); if ((reqby = xbps_pkgdb_get_pkg_revdeps(xhp, pkg)) != NULL) {
if (reqby) {
for (i = 0; i < prop_array_count(reqby); i++) { for (i = 0; i < prop_array_count(reqby); i++) {
prop_array_get_cstring_nocopy(reqby, i, &pkgdep); prop_array_get_cstring_nocopy(reqby, i, &pkgdep);
printf("%s\n", pkgdep); printf("%s\n", pkgdep);
@ -69,16 +110,19 @@ show_pkg_revdeps(struct xbps_handle *xhp, const char *pkg)
} }
int int
repo_show_pkg_deps(struct xbps_handle *xhp, const char *pattern) repo_show_pkg_deps(struct xbps_handle *xhp, const char *pattern, bool full)
{ {
prop_array_t rdeps;
prop_dictionary_t pkgd; prop_dictionary_t pkgd;
int indent = 0;
if (((pkgd = xbps_rpool_get_pkg(xhp, pattern)) == NULL) && if (((pkgd = xbps_rpool_get_pkg(xhp, pattern)) == NULL) &&
((pkgd = xbps_rpool_get_virtualpkg(xhp, pattern)) == NULL)) ((pkgd = xbps_rpool_get_virtualpkg(xhp, pattern)) == NULL))
return errno; return errno;
(void)xbps_callback_array_iter_in_dict(xhp, pkgd, rdeps = prop_dictionary_get(pkgd, "run_depends");
"run_depends", list_strings_sep_in_array, NULL); if (rdeps != NULL)
print_rdeps(xhp, rdeps, full, true, true, &indent);
return 0; return 0;
} }

View File

@ -295,8 +295,7 @@ repo_show_pkg_info(struct xbps_handle *xhp,
{ {
prop_dictionary_t pkgd; prop_dictionary_t pkgd;
if (((pkgd = xbps_rpool_get_pkg(xhp, pattern)) == NULL) && if ((pkgd = xbps_rpool_get_pkg_plist(xhp, pattern, "./props.plist")) == NULL)
((pkgd = xbps_rpool_get_virtualpkg(xhp, pattern)) == NULL))
return errno; return errno;
if (option) if (option)

View File

@ -1,4 +1,4 @@
.Dd February 20, 2013 .Dd March 4, 2013
.Os Void Linux .Os Void Linux
.Dt xbps-query 8 .Dt xbps-query 8
.Sh NAME .Sh NAME
@ -139,6 +139,7 @@ Multiple properties can be specified by delimiting them with commas.
.It Fl x, Fl -deps Ar PKG .It Fl x, Fl -deps Ar PKG
Show the required dependencies for Show the required dependencies for
.Ar PKG . .Ar PKG .
Only direct dependencies are shown. To see a full dependency tree set it twice.
.It Fl X, Fl -revdeps Ar PKG .It Fl X, Fl -revdeps Ar PKG
Show the reverse dependencies for Show the reverse dependencies for
.Ar PKG . .Ar PKG .
@ -152,13 +153,13 @@ architecture.
.Sh FILES .Sh FILES
.Bl -tag -width /var/db/xbps/.<pkgname>.plist .Bl -tag -width /var/db/xbps/.<pkgname>.plist
.It Ar /etc/xbps/xbps.conf .It Ar /etc/xbps/xbps.conf
Default XBPS configuration file. Default configuration file.
.It Ar /var/db/xbps/.<pkgname>.plist .It Ar /var/db/xbps/.<pkgname>.plist
Package metadata properties. Package metadata properties.
.It Ar /var/db/xbps/pkgdb.plist .It Ar /var/db/xbps/pkgdb-0.21.plist
XBPS package database. Default package database (0.21 format). Keeps track of installed packages and properties.
.It Ar /var/cache/xbps .It Ar /var/cache/xbps
Default XBPS cache directory. Default cache directory to store downloaded binary packages.
.Sh SEE ALSO .Sh SEE ALSO
.Xr xbps-create 8 , .Xr xbps-create 8 ,
.Xr xbps-dgraph 8 , .Xr xbps-dgraph 8 ,

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2012 Juan Romero Pardines. * Copyright (c) 2012-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -65,7 +65,7 @@ state_cb(struct xbps_state_cb_data *xscd, void *cbd)
switch (xscd->state) { switch (xscd->state) {
/* notifications */ /* notifications */
case XBPS_STATE_CONFIGURE: case XBPS_STATE_CONFIGURE:
printf("%s-%s: configuring ...\n", xscd->arg0, xscd->arg1); printf("%s: configuring ...\n", xscd->arg);
break; break;
/* errors */ /* errors */
case XBPS_STATE_CONFIGURE_FAIL: case XBPS_STATE_CONFIGURE_FAIL:
@ -75,7 +75,7 @@ state_cb(struct xbps_state_cb_data *xscd, void *cbd)
break; break;
default: default:
xbps_dbg_printf(xscd->xhp, xbps_dbg_printf(xscd->xhp,
"unknown state %d\n", xscd->state); "%s: unknown state %d\n", xscd->arg, xscd->state);
break; break;
} }
} }

View File

@ -1,4 +1,4 @@
.Dd November 6, 2012 .Dd March 4, 2013
.Os Void Linux .Os Void Linux
.Dt xbps-reconfigure 8 .Dt xbps-reconfigure 8
.Sh NAME .Sh NAME
@ -48,6 +48,16 @@ Specifies a full path for the target root directory.
Enables verbose messages. Enables verbose messages.
.It Fl V, Fl -version .It Fl V, Fl -version
Shows the XBPS version. Shows the XBPS version.
.Sh FILES
.Bl -tag -width /var/db/xbps/.<pkgname>.plist
.It Ar /etc/xbps/xbps.conf
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 .Sh SEE ALSO
.Xr xbps-create 8 , .Xr xbps-create 8 ,
.Xr xbps-dgraph 8 , .Xr xbps-dgraph 8 ,

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2008-2012 Juan Romero Pardines. * Copyright (c) 2008-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -79,7 +79,7 @@ state_cb_rm(struct xbps_state_cb_data *xscd, void *cbdata)
case XBPS_STATE_UNREGISTER: case XBPS_STATE_UNREGISTER:
break; break;
case XBPS_STATE_REMOVE: case XBPS_STATE_REMOVE:
printf("Removing `%s-%s' ...\n", xscd->arg0, xscd->arg1); printf("Removing `%s' ...\n", xscd->arg);
break; break;
/* success */ /* success */
case XBPS_STATE_REMOVE_FILE: case XBPS_STATE_REMOVE_FILE:
@ -92,11 +92,10 @@ state_cb_rm(struct xbps_state_cb_data *xscd, void *cbdata)
} }
break; break;
case XBPS_STATE_REMOVE_DONE: case XBPS_STATE_REMOVE_DONE:
printf("Removed `%s-%s' successfully.\n", printf("Removed `%s' successfully.\n", xscd->arg);
xscd->arg0, xscd->arg1);
if (syslog_enabled) if (syslog_enabled)
syslog(LOG_NOTICE, "Removed `%s-%s' successfully " syslog(LOG_NOTICE, "Removed `%s' successfully "
"(rootdir: %s).", xscd->arg0, xscd->arg1, "(rootdir: %s).", xscd->arg,
xscd->xhp->rootdir); xscd->xhp->rootdir);
break; break;
/* errors */ /* errors */
@ -119,8 +118,7 @@ state_cb_rm(struct xbps_state_cb_data *xscd, void *cbdata)
break; break;
default: default:
xbps_dbg_printf(xscd->xhp, xbps_dbg_printf(xscd->xhp,
"%s-%s: unknown state %d\n", "%s: unknown state %d\n", xscd->arg, xscd->state);
xscd->arg0, xscd->arg1, xscd->state);
break; break;
} }
} }

View File

@ -1,4 +1,4 @@
.Dd November 21, 2012 .Dd March 4, 2013
.Os Void Linux .Os Void Linux
.Dt xbps-remove 8 .Dt xbps-remove 8
.Sh NAME .Sh NAME
@ -87,13 +87,13 @@ Shows the XBPS version.
.Sh FILES .Sh FILES
.Bl -tag -width /var/db/xbps/.<pkgname>.plist .Bl -tag -width /var/db/xbps/.<pkgname>.plist
.It Ar /etc/xbps/xbps.conf .It Ar /etc/xbps/xbps.conf
Default XBPS configuration file. Default configuration file.
.It Ar /var/db/xbps/.<pkgname>.plist .It Ar /var/db/xbps/.<pkgname>.plist
Package metadata properties. Package metadata properties.
.It Ar /var/db/xbps/pkgdb.plist .It Ar /var/db/xbps/pkgdb-0.21.plist
XBPS package database. Default package database (0.21 format). Keeps track of installed packages and properties.
.It Ar /var/cache/xbps .It Ar /var/cache/xbps
Default XBPS cache directory. Default cache directory to store downloaded binary packages.
.Sh SEE ALSO .Sh SEE ALSO
.Xr xbps-create 8 , .Xr xbps-create 8 ,
.Xr xbps-dgraph 8 , .Xr xbps-dgraph 8 ,

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2012 Juan Romero Pardines. * Copyright (c) 2012-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -48,9 +48,8 @@ index_add(struct xbps_handle *xhp, int argc, char **argv)
prop_dictionary_t filespkgd; prop_dictionary_t filespkgd;
prop_object_t obj, fileobj; prop_object_t obj, fileobj;
struct stat st; struct stat st;
const char *pkgname, *version, *regver, *oldfilen, *oldpkgver; const char *oldpkgver, *arch, *oldarch;
const char *pkgver, *arch, *oldarch; char *pkgver, *pkgname, *sha256, *repodir, *buf;
char *sha256, *filen, *repodir, *buf;
char *tmpfilen, *tmprepodir, *plist, *plistf; char *tmpfilen, *tmprepodir, *plist, *plistf;
size_t x; size_t x;
int i, ret = 0; int i, ret = 0;
@ -100,7 +99,6 @@ index_add(struct xbps_handle *xhp, int argc, char **argv)
if ((tmpfilen = strdup(argv[i])) == NULL) if ((tmpfilen = strdup(argv[i])) == NULL)
return ENOMEM; return ENOMEM;
filen = basename(tmpfilen);
/* /*
* Read metadata props plist dictionary from binary package. * Read metadata props plist dictionary from binary package.
*/ */
@ -114,17 +112,15 @@ index_add(struct xbps_handle *xhp, int argc, char **argv)
} }
prop_dictionary_get_cstring_nocopy(newpkgd, "architecture", prop_dictionary_get_cstring_nocopy(newpkgd, "architecture",
&arch); &arch);
prop_dictionary_get_cstring_nocopy(newpkgd, "pkgver", &pkgver); prop_dictionary_get_cstring(newpkgd, "pkgver", &pkgver);
if (!xbps_pkg_arch_match(xhp, arch, NULL)) { if (!xbps_pkg_arch_match(xhp, arch, NULL)) {
fprintf(stderr, "index: ignoring %s, unmatched " fprintf(stderr, "index: ignoring %s, unmatched "
"arch (%s)\n", pkgver, arch); "arch (%s)\n", pkgver, arch);
prop_object_release(newpkgd); prop_object_release(newpkgd);
continue; continue;
} }
prop_dictionary_get_cstring_nocopy(newpkgd, "pkgname", pkgname = xbps_pkg_name(pkgver);
&pkgname); assert(pkgname);
prop_dictionary_get_cstring_nocopy(newpkgd, "version",
&version);
/* /*
* Check if this package exists already in the index, but first * Check if this package exists already in the index, but first
* checking the version. If current package version is greater * checking the version. If current package version is greater
@ -133,25 +129,26 @@ index_add(struct xbps_handle *xhp, int argc, char **argv)
*/ */
curpkgd = prop_dictionary_get(idx, pkgname); curpkgd = prop_dictionary_get(idx, pkgname);
if (curpkgd == NULL) { if (curpkgd == NULL) {
if (errno && errno != ENOENT) if (errno && errno != ENOENT) {
free(pkgver);
free(pkgname);
return errno; return errno;
}
} else { } else {
prop_dictionary_get_cstring_nocopy(curpkgd,
"filename", &oldfilen);
prop_dictionary_get_cstring_nocopy(curpkgd, prop_dictionary_get_cstring_nocopy(curpkgd,
"pkgver", &oldpkgver); "pkgver", &oldpkgver);
prop_dictionary_get_cstring_nocopy(curpkgd, prop_dictionary_get_cstring_nocopy(curpkgd,
"architecture", &oldarch); "architecture", &oldarch);
prop_dictionary_get_cstring_nocopy(curpkgd, ret = xbps_cmpver(pkgver, oldpkgver);
"version", &regver);
ret = xbps_cmpver(version, regver);
if (ret <= 0) { if (ret <= 0) {
/* Same version or index version greater */ /* Same version or index version greater */
fprintf(stderr, "index: skipping `%s-%s' " fprintf(stderr, "index: skipping `%s' "
"(%s), already registered.\n", "(%s), already registered.\n",
pkgname, version, arch); pkgver, arch);
prop_object_release(newpkgd); prop_object_release(newpkgd);
free(tmpfilen); free(tmpfilen);
free(pkgver);
free(pkgname);
continue; continue;
} }
/* /*
@ -167,32 +164,57 @@ index_add(struct xbps_handle *xhp, int argc, char **argv)
* We have the dictionary now, add the required * We have the dictionary now, add the required
* objects for the index. * objects for the index.
*/ */
if (!prop_dictionary_set_cstring(newpkgd, "filename", filen)) if ((sha256 = xbps_file_hash(argv[i])) == NULL) {
free(pkgver);
free(pkgname);
return errno; return errno;
}
if ((sha256 = xbps_file_hash(argv[i])) == NULL)
return errno;
if (!prop_dictionary_set_cstring(newpkgd, "filename-sha256", if (!prop_dictionary_set_cstring(newpkgd, "filename-sha256",
sha256)) sha256)) {
free(pkgver);
free(pkgname);
return errno; return errno;
}
free(sha256); free(sha256);
if (stat(argv[i], &st) == -1) if (stat(argv[i], &st) == -1) {
free(pkgver);
free(pkgname);
return errno; return errno;
}
if (!prop_dictionary_set_uint64(newpkgd, "filename-size", if (!prop_dictionary_set_uint64(newpkgd, "filename-size",
(uint64_t)st.st_size)) { (uint64_t)st.st_size)) {
free(pkgver);
free(pkgname);
return errno; return errno;
} }
/*
* Remove obsolete package objects.
*/
prop_dictionary_remove(newpkgd, "archive-compression-type");
prop_dictionary_remove(newpkgd, "build-date");
prop_dictionary_remove(newpkgd, "build_date");
prop_dictionary_remove(newpkgd, "conf_files");
prop_dictionary_remove(newpkgd, "filename");
prop_dictionary_remove(newpkgd, "homepage");
prop_dictionary_remove(newpkgd, "license");
prop_dictionary_remove(newpkgd, "maintainer");
prop_dictionary_remove(newpkgd, "packaged-with");
prop_dictionary_remove(newpkgd, "source-revisions");
prop_dictionary_remove(newpkgd, "long_desc");
prop_dictionary_remove(newpkgd, "pkgname");
prop_dictionary_remove(newpkgd, "version");
/* /*
* Add new pkg dictionary into the index. * Add new pkg dictionary into the index.
*/ */
if (!prop_dictionary_set(idx, pkgname, newpkgd)) if (!prop_dictionary_set(idx, pkgname, newpkgd)) {
free(pkgname);
return EINVAL; return EINVAL;
}
flush = true; flush = true;
printf("index: added `%s-%s' (%s).\n", pkgname, version, arch); printf("index: added `%s' (%s).\n", pkgver, arch);
free(tmpfilen); free(tmpfilen);
/* /*
* Add new pkg dictionary into the index-files. * Add new pkg dictionary into the index-files.
@ -200,8 +222,11 @@ index_add(struct xbps_handle *xhp, int argc, char **argv)
found = false; found = false;
newpkgfilesd = xbps_get_pkg_plist_from_binpkg(argv[i], newpkgfilesd = xbps_get_pkg_plist_from_binpkg(argv[i],
"./files.plist"); "./files.plist");
if (newpkgfilesd == NULL) if (newpkgfilesd == NULL) {
free(pkgver);
free(pkgname);
return EINVAL; return EINVAL;
}
/* Find out if binary pkg stored in index contain any file */ /* Find out if binary pkg stored in index contain any file */
pkg_cffiles = prop_dictionary_get(newpkgfilesd, "conf_files"); pkg_cffiles = prop_dictionary_get(newpkgfilesd, "conf_files");
@ -226,6 +251,8 @@ index_add(struct xbps_handle *xhp, int argc, char **argv)
if (!found) { if (!found) {
prop_object_release(newpkgfilesd); prop_object_release(newpkgfilesd);
prop_object_release(newpkgd); prop_object_release(newpkgd);
free(pkgver);
free(pkgname);
continue; continue;
} }
/* create pkg files array */ /* create pkg files array */
@ -276,6 +303,8 @@ index_add(struct xbps_handle *xhp, int argc, char **argv)
printf("index-files: added `%s' (%s)\n", pkgver, arch); printf("index-files: added `%s' (%s)\n", pkgver, arch);
files_flush = true; files_flush = true;
prop_object_release(newpkgd); prop_object_release(newpkgd);
free(pkgver);
free(pkgname);
} }
if (flush && !prop_dictionary_externalize_to_zfile(idx, plist)) { if (flush && !prop_dictionary_externalize_to_zfile(idx, plist)) {

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2012 Juan Romero Pardines. * Copyright (c) 2012-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -54,7 +54,8 @@ cleaner_thread(void *arg)
prop_dictionary_t pkgd; prop_dictionary_t pkgd;
prop_array_t array; prop_array_t array;
struct thread_data *thd = arg; struct thread_data *thd = arg;
const char *pkgver, *filen, *sha256; char *filen;
const char *pkgver, *arch, *sha256;
unsigned int i; unsigned int i;
/* process pkgs from start until end */ /* process pkgs from start until end */
@ -63,8 +64,9 @@ cleaner_thread(void *arg)
for (i = thd->start; i < thd->end; i++) { for (i = thd->start; i < thd->end; i++) {
obj = prop_array_get(array, i); obj = prop_array_get(array, i);
pkgd = prop_dictionary_get_keysym(thd->idx, obj); pkgd = prop_dictionary_get_keysym(thd->idx, obj);
prop_dictionary_get_cstring_nocopy(pkgd, "filename", &filen); prop_dictionary_get_cstring_nocopy(pkgd, "architecture", &arch);
prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver); prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
filen = xbps_xasprintf("%s.%s.xbps");
xbps_dbg_printf(thd->xhp, "thread[%d] checking %s\n", xbps_dbg_printf(thd->xhp, "thread[%d] checking %s\n",
thd->thread_num, pkgver); thd->thread_num, pkgver);
if (access(filen, R_OK) == -1) { if (access(filen, R_OK) == -1) {
@ -73,6 +75,7 @@ cleaner_thread(void *arg)
* broken or simply unexistent; either way, remove it. * broken or simply unexistent; either way, remove it.
*/ */
prop_array_add_cstring_nocopy(thd->result, pkgver); prop_array_add_cstring_nocopy(thd->result, pkgver);
free(filen);
continue; continue;
} }
/* /*
@ -82,6 +85,7 @@ cleaner_thread(void *arg)
"filename-sha256", &sha256); "filename-sha256", &sha256);
if (xbps_file_hash_check(filen, sha256) != 0) if (xbps_file_hash_check(filen, sha256) != 0)
prop_array_add_cstring_nocopy(thd->result, pkgver); prop_array_add_cstring_nocopy(thd->result, pkgver);
free(filen);
} }
prop_object_release(array); prop_object_release(array);

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2012 Juan Romero Pardines. * Copyright (c) 2012-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -46,9 +46,9 @@
* @def XBPS_PKGINDEX_VERSION * @def XBPS_PKGINDEX_VERSION
* Current version for the repository package index format. * Current version for the repository package index format.
*/ */
#define XBPS_PKGINDEX_VERSION "1.6" #define XBPS_PKGINDEX_VERSION "1.7"
#define XBPS_API_VERSION "20130220" #define XBPS_API_VERSION "20130304"
#ifndef XBPS_VERSION #ifndef XBPS_VERSION
#define XBPS_VERSION "UNSET" #define XBPS_VERSION "UNSET"
@ -81,7 +81,7 @@
* @def XBPS_PKGDB * @def XBPS_PKGDB
* Filename for the package database. * Filename for the package database.
*/ */
#define XBPS_PKGDB "pkgdb.plist" #define XBPS_PKGDB "pkgdb-0.21.plist"
/** /**
* @def XBPS_PKGPROPS * @def XBPS_PKGPROPS
@ -217,6 +217,7 @@ extern "C" {
* install, update, remove and replace. * install, update, remove and replace.
* - XBPS_STATE_TRANS_CONFIGURE: transaction is configuring all * - XBPS_STATE_TRANS_CONFIGURE: transaction is configuring all
* unpacked packages. * unpacked packages.
* - XBPS_STATE_XBPS_UPDATE: a new package update is available for XBPS.
* - XBPS_STATE_DOWNLOAD: a binary package is being downloaded. * - XBPS_STATE_DOWNLOAD: a binary package is being downloaded.
* - XBPS_STATE_VERIFY: a binary package is being verified. * - XBPS_STATE_VERIFY: a binary package is being verified.
* - XBPS_STATE_REMOVE: a package is being removed. * - XBPS_STATE_REMOVE: a package is being removed.
@ -290,7 +291,8 @@ typedef enum xbps_state {
XBPS_STATE_UNPACK_FAIL, XBPS_STATE_UNPACK_FAIL,
XBPS_STATE_REGISTER_FAIL, XBPS_STATE_REGISTER_FAIL,
XBPS_STATE_UNREGISTER_FAIL, XBPS_STATE_UNREGISTER_FAIL,
XBPS_STATE_REPOSYNC_FAIL XBPS_STATE_REPOSYNC_FAIL,
XBPS_STATE_XBPS_UPDATE
} xbps_state_t; } xbps_state_t;
/** /**
@ -318,19 +320,12 @@ struct xbps_state_cb_data {
*/ */
const char *desc; const char *desc;
/** /**
* @var arg0 * @var arg
* *
* State string argument 0. String set on this * State string argument. String set on this
* variable may change depending on \a state. * variable may change depending on \a state.
*/ */
const char *arg0; const char *arg;
/**
* @var arg1
*
* State string argument 1. String set on this
* variable may change depending on \a state.
*/
const char *arg1;
/** /**
* @var err * @var err
* *
@ -480,10 +475,10 @@ struct xbps_handle {
/** /**
* @private pkgdb. * @private pkgdb.
* *
* Internalized proplib array with the master package database * Internalized proplib dictionary with the master package database
* stored in XBPS_META_PATH/XBPS_PKGDB. * stored in XBPS_META_PATH/XBPS_PKGDB.
*/ */
prop_array_t pkgdb; prop_dictionary_t pkgdb;
/** /**
* @private * @private
* *
@ -801,37 +796,6 @@ prop_dictionary_t xbps_pkgdb_get_pkg_metadata(struct xbps_handle *xhp,
prop_array_t xbps_pkgdb_get_pkg_revdeps(struct xbps_handle *xhp, prop_array_t xbps_pkgdb_get_pkg_revdeps(struct xbps_handle *xhp,
const char *pkg); const char *pkg);
/**
* Removes a package dictionary from master package database (pkgdb) plist,
* matching pkgname or pkgver object in \a pkg.
*
* @param[in] xhp The pointer to the xbps_handle struct.
* @param[in] pkg Package name or pattern to match in a package dictionary.
* @param[in] flush If true, after successful replace the pkgdb contents
* in memory will be flushed atomically to storage.
*
* @return true on success, false otherwise.
*/
bool xbps_pkgdb_remove_pkg(struct xbps_handle *xhp, const char *pkg,
bool flush);
/**
* Replaces a package dictionary with \a dict in the master package database
* (pkgdb) plist, matching pkgname or pkgver object.
*
* @param[in] xhp The pointer to the xbps_handle struct.
* @param[in] pkgd Proplib dictionary to be added into pkgdb.
* @param[in] pkg Package name or pattern to match in a package dictionary.
* @param[in] flush If true, after successful replace the pkgdb contents in
* memory will be flushed atomically to storage.
*
* @return true on success, false otherwise.
*/
bool xbps_pkgdb_replace_pkg(struct xbps_handle *xhp,
prop_dictionary_t pkgd,
const char *pkg,
bool flush);
/** /**
* Updates the master package database (pkgdb) plist with new contents from * Updates the master package database (pkgdb) plist with new contents from
* disk to the cached copy in memory. * disk to the cached copy in memory.
@ -850,8 +814,7 @@ int xbps_pkgdb_update(struct xbps_handle *xhp, bool flush);
* @param[in] xhp The pointer to the xbps_handle struct. * @param[in] xhp The pointer to the xbps_handle struct.
* @param[in] blob The buffer pointer where the data is stored. * @param[in] blob The buffer pointer where the data is stored.
* @param[in] blobsiz The size of the buffer data. * @param[in] blobsiz The size of the buffer data.
* @param[in] pkgname The package name associated. * @param[in] pkgver The package name/version associated.
* @param[in] version The package version associated.
* @param[in] action The action to execute on the temporary file. * @param[in] action The action to execute on the temporary file.
* @param[in] update Set to true if package is being updated. * @param[in] update Set to true if package is being updated.
* *
@ -860,8 +823,7 @@ int xbps_pkgdb_update(struct xbps_handle *xhp, bool flush);
int xbps_pkg_exec_buffer(struct xbps_handle *xhp, int xbps_pkg_exec_buffer(struct xbps_handle *xhp,
const void *blob, const void *blob,
const size_t blobsiz, const size_t blobsiz,
const char *pkgname, const char *pkgver,
const char *version,
const char *action, const char *action,
bool update); bool update);
@ -1054,82 +1016,6 @@ prop_object_iterator_t xbps_array_iter_from_dict(prop_dictionary_t dict,
/*@}*/ /*@}*/
/** @addtogroup pkg_register */
/*@{*/
/**
* Register a package into the installed packages database.
*
* @param[in] xhp The pointer to the xbps_handle struct.
* @param[in] pkg_dict A dictionary with the following objects:
* \a pkgname, \a version, \a pkgver, \a short_desc (string),
* \a automatic-install (bool) and optionally \a provides (array of strings).
* @param[in] flush Set to true to make sure that pkgdb plist
* is written to storage on success.
*
* @return 0 on success, otherwise an errno value.
*/
int xbps_register_pkg(struct xbps_handle *xhp,
prop_dictionary_t pkg_dict,
bool flush);
/**
* Unregister a package from the package database.
*
* @param[in] xhp The pointer to the xbps_handle struct.
* @param[in] pkgver Package name-version to match.
* @param[in] flush Set to true to make sure that pkgdb plist
* is written to storage on success.
*
* @return 0 on success, otherwise an errno value.
*/
int xbps_unregister_pkg(struct xbps_handle *xhp, const char *pkgver,
bool flush);
/*@}*/
/** @addtogroup pkg_remove */
/*@{*/
/**
* Remove an installed package.
*
* @param[in] xhp The pointer to the xbps_handle struct.
* @param[in] pkgver Package name/version to match.
* @param[in] update If true, some steps will be skipped. See in the
* detailed description above for more information.
* @param[in] soft_replace If true, some steps will be skipped. See in
* the detailed description above for more information.
*
* @return 0 on success, otherwise an errno value.
*/
int xbps_remove_pkg(struct xbps_handle *xhp,
const char *pkgver,
bool update,
bool soft_replace);
/**
* Remove files defined in a proplib array as specified by \a key
* of an installed package.
*
* @param[in] xhp The pointer to the xbps_handle struct.
* @param[in] dict Proplib dictionary internalized from package's
* <b>XBPS_PKGFILES</b> definition in package's metadata directory.
* The image in Detailed description shows off its structure.
* @param[in] key Key of the array object to match, valid values are:
* <b>files</b>, <b>dirs</b>, <b>links</b> and <b>conf_files</b>.
* @param[in] pkgver Package/version string matching package dictionary,
* i.e `foo-1.0'.
*
* @return 0 on success, otherwise an errno value.
*/
int xbps_remove_pkg_files(struct xbps_handle *xhp,
prop_dictionary_t dict,
const char *key,
const char *pkgver);
/*@}*/
/** @addtogroup transaction */ /** @addtogroup transaction */
/*@{*/ /*@{*/
@ -1465,15 +1351,13 @@ int xbps_pkg_state_dictionary(prop_dictionary_t dict, pkg_state_t *state);
* Sets package state \a state in package \a pkgname. * Sets package state \a state in package \a pkgname.
* *
* @param[in] xhp The pointer to an xbps_handle struct. * @param[in] xhp The pointer to an xbps_handle struct.
* @param[in] pkgname Package name. * @param[in] pkgver Package name/version to match.
* @param[in] version Package version.
* @param[in] state Package state to be set. * @param[in] state Package state to be set.
* *
* @return 0 on success, otherwise an errno value. * @return 0 on success, otherwise an errno value.
*/ */
int xbps_set_pkg_state_installed(struct xbps_handle *xhp, int xbps_set_pkg_state_installed(struct xbps_handle *xhp,
const char *pkgname, const char *pkgver,
const char *version,
pkg_state_t state); pkg_state_t state);
/** /**

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2010-2012 Juan Romero Pardines. * Copyright (c) 2010-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -70,6 +70,9 @@
#define archive_read_finish(x) \ #define archive_read_finish(x) \
archive_read_free(x) archive_read_free(x)
#define archive_write_finish(x) \
archive_write_free(x)
#define archive_compression_name(x) \ #define archive_compression_name(x) \
archive_filter_name(x, 0) archive_filter_name(x, 0)
@ -144,7 +147,6 @@ int HIDDEN xbps_entry_install_conf_file(struct xbps_handle *,
prop_dictionary_t, prop_dictionary_t,
struct archive_entry *, struct archive_entry *,
const char *, const char *,
const char *,
const char *); const char *);
/** /**
* @private * @private
@ -156,7 +158,7 @@ prop_dictionary_t HIDDEN
/** /**
* @private * @private
* From lib/rpool_pkgdeps.c * From lib/rindex_pkgdeps.c
*/ */
int HIDDEN xbps_repository_find_deps(struct xbps_handle *, int HIDDEN xbps_repository_find_deps(struct xbps_handle *,
prop_array_t, prop_array_t,
@ -170,7 +172,10 @@ prop_dictionary_t HIDDEN xbps_find_pkg_in_array(prop_array_t, const char *);
prop_dictionary_t HIDDEN prop_dictionary_t HIDDEN
xbps_find_virtualpkg_in_array(struct xbps_handle *, prop_array_t, xbps_find_virtualpkg_in_array(struct xbps_handle *, prop_array_t,
const char *); const char *);
prop_dictionary_t HIDDEN xbps_find_pkg_in_dict(prop_dictionary_t, const char *);
prop_dictionary_t HIDDEN xbps_find_virtualpkg_in_dict(struct xbps_handle *,
prop_dictionary_t,
const char *);
/** /**
* @private * @private
* From lib/transaction_sortdeps.c * From lib/transaction_sortdeps.c
@ -212,7 +217,7 @@ int HIDDEN xbps_file_exec(struct xbps_handle *, const char *, ...);
void HIDDEN xbps_set_cb_fetch(struct xbps_handle *, off_t, off_t, off_t, void HIDDEN xbps_set_cb_fetch(struct xbps_handle *, off_t, off_t, off_t,
const char *, bool, bool, bool); const char *, bool, bool, bool);
void HIDDEN xbps_set_cb_state(struct xbps_handle *, xbps_state_t, int, void HIDDEN xbps_set_cb_state(struct xbps_handle *, xbps_state_t, int,
const char *, const char *, const char *, ...); const char *, const char *, ...);
/** /**
* @private * @private
@ -222,6 +227,21 @@ int HIDDEN xbps_unpack_binary_pkg(struct xbps_handle *, prop_dictionary_t);
int HIDDEN xbps_transaction_package_replace(struct xbps_handle *); int HIDDEN xbps_transaction_package_replace(struct xbps_handle *);
/**
* @private
* From lib/package_remove.c
*/
int HIDDEN xbps_remove_pkg(struct xbps_handle *, const char *, bool, bool);
int HIDDEN xbps_remove_pkg_files(struct xbps_handle *, prop_dictionary_t,
const char *, const char *);
/**
* @private
* From lib/package_register.c
*/
int HIDDEN xbps_register_pkg(struct xbps_handle *, prop_dictionary_t);
int HIDDEN xbps_unregister_pkg(struct xbps_handle *, const char *);
/** /**
* @private * @private
* From lib/package_conflicts.c * From lib/package_conflicts.c
@ -231,7 +251,7 @@ void HIDDEN xbps_pkg_find_conflicts(struct xbps_handle *,
prop_dictionary_t); prop_dictionary_t);
/** /**
* @private * @private
* From lib/rindex_get.c * From lib/plist_find.c
*/ */
const char HIDDEN *vpkg_user_conf(struct xbps_handle *, const char *, bool); const char HIDDEN *vpkg_user_conf(struct xbps_handle *, const char *, bool);

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2011-2012 Juan Romero Pardines. * Copyright (c) 2011-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -74,8 +74,7 @@ void HIDDEN
xbps_set_cb_state(struct xbps_handle *xhp, xbps_set_cb_state(struct xbps_handle *xhp,
xbps_state_t state, xbps_state_t state,
int err, int err,
const char *arg0, const char *arg,
const char *arg1,
const char *fmt, const char *fmt,
...) ...)
{ {
@ -90,8 +89,7 @@ xbps_set_cb_state(struct xbps_handle *xhp,
xscd.xhp = xhp; xscd.xhp = xhp;
xscd.state = state; xscd.state = state;
xscd.err = err; xscd.err = err;
xscd.arg0 = arg0; xscd.arg = arg;
xscd.arg1 = arg1;
if (fmt != NULL) { if (fmt != NULL) {
va_start(va, fmt); va_start(va, fmt);
retval = vasprintf(&buf, fmt, va); retval = vasprintf(&buf, fmt, va);

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2009-2012 Juan Romero Pardines. * Copyright (c) 2009-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -64,8 +64,7 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
prop_dictionary_t filesd, prop_dictionary_t filesd,
struct archive_entry *entry, struct archive_entry *entry,
const char *entry_pname, const char *entry_pname,
const char *pkgname, const char *pkgver)
const char *version)
{ {
prop_dictionary_t forigd; prop_dictionary_t forigd;
prop_object_t obj, obj2; prop_object_t obj, obj2;
@ -77,8 +76,7 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
assert(prop_object_type(filesd) == PROP_TYPE_DICTIONARY); assert(prop_object_type(filesd) == PROP_TYPE_DICTIONARY);
assert(entry != NULL); assert(entry != NULL);
assert(entry_pname != NULL); assert(entry_pname != NULL);
assert(pkgname != NULL); assert(pkgver != NULL);
assert(version != NULL);
iter = xbps_array_iter_from_dict(filesd, "conf_files"); iter = xbps_array_iter_from_dict(filesd, "conf_files");
if (iter == NULL) if (iter == NULL)
@ -88,13 +86,13 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
* Get original hash for the file from current * Get original hash for the file from current
* installed package. * installed package.
*/ */
xbps_dbg_printf(xhp, "%s-%s: processing conf_file %s\n", xbps_dbg_printf(xhp, "%s: processing conf_file %s\n",
pkgname, version, entry_pname); pkgver, entry_pname);
forigd = xbps_pkgdb_get_pkg_metadata(xhp, pkgname); forigd = xbps_pkgdb_get_pkg_metadata(xhp, pkgver);
if (forigd == NULL) { if (forigd == NULL) {
xbps_dbg_printf(xhp, "%s-%s: conf_file %s not currently " xbps_dbg_printf(xhp, "%s: conf_file %s not currently "
"installed\n", pkgname, version, entry_pname); "installed\n", pkgver, entry_pname);
rv = 1; rv = 1;
goto out; goto out;
} }
@ -120,8 +118,8 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
* First case: original hash not found, install new file. * First case: original hash not found, install new file.
*/ */
if (sha256_orig == NULL) { if (sha256_orig == NULL) {
xbps_dbg_printf(xhp, "%s-%s: conf_file %s not installed\n", xbps_dbg_printf(xhp, "%s: conf_file %s not installed\n",
pkgname, version, entry_pname); pkgver, entry_pname);
rv = 1; rv = 1;
goto out; goto out;
} }
@ -145,9 +143,8 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
/* /*
* File not installed, install new one. * File not installed, install new one.
*/ */
xbps_dbg_printf(xhp, "%s-%s: conf_file %s not " xbps_dbg_printf(xhp, "%s: conf_file %s not "
"installed\n", pkgname, version, "installed\n", pkgver, entry_pname);
entry_pname);
rv = 1; rv = 1;
break; break;
} else { } else {
@ -163,9 +160,8 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
if ((strcmp(sha256_orig, sha256_cur) == 0) && if ((strcmp(sha256_orig, sha256_cur) == 0) &&
(strcmp(sha256_orig, sha256_new) == 0) && (strcmp(sha256_orig, sha256_new) == 0) &&
(strcmp(sha256_cur, sha256_new) == 0)) { (strcmp(sha256_cur, sha256_new) == 0)) {
xbps_dbg_printf(xhp, "%s-%s: conf_file %s orig = X, " xbps_dbg_printf(xhp, "%s: conf_file %s orig = X, "
"cur = X, new = X\n", pkgname, version, "cur = X, new = X\n", pkgver, entry_pname);
entry_pname);
rv = 0; rv = 0;
break; break;
/* /*
@ -177,9 +173,9 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
(strcmp(sha256_orig, sha256_new)) && (strcmp(sha256_orig, sha256_new)) &&
(strcmp(sha256_cur, sha256_new))) { (strcmp(sha256_cur, sha256_new))) {
xbps_set_cb_state(xhp, XBPS_STATE_CONFIG_FILE, xbps_set_cb_state(xhp, XBPS_STATE_CONFIG_FILE,
0, pkgname, version, 0, pkgver,
"Updating configuration file `%s' provided " "Updating configuration file `%s' provided "
"by version `%s'.", cffile, version); "by `%s'.", cffile, pkgver);
rv = 1; rv = 1;
break; break;
/* /*
@ -193,7 +189,7 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
(strcmp(sha256_cur, sha256_new)) && (strcmp(sha256_cur, sha256_new)) &&
(strcmp(sha256_orig, sha256_cur))) { (strcmp(sha256_orig, sha256_cur))) {
xbps_set_cb_state(xhp, XBPS_STATE_CONFIG_FILE, xbps_set_cb_state(xhp, XBPS_STATE_CONFIG_FILE,
0, pkgname, version, 0, pkgver,
"Keeping modified configuration file `%s'.", "Keeping modified configuration file `%s'.",
cffile); cffile);
rv = 0; rv = 0;
@ -207,9 +203,8 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
} else if ((strcmp(sha256_cur, sha256_new) == 0) && } else if ((strcmp(sha256_cur, sha256_new) == 0) &&
(strcmp(sha256_orig, sha256_new)) && (strcmp(sha256_orig, sha256_new)) &&
(strcmp(sha256_orig, sha256_cur))) { (strcmp(sha256_orig, sha256_cur))) {
xbps_dbg_printf(xhp, "%s-%s: conf_file %s orig = X, " xbps_dbg_printf(xhp, "%s: conf_file %s orig = X, "
"cur = Y, new = Y\n", pkgname, version, "cur = Y, new = Y\n", pkgver, entry_pname);
entry_pname);
rv = 0; rv = 0;
break; break;
/* /*
@ -220,10 +215,14 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
} else if ((strcmp(sha256_orig, sha256_cur)) && } else if ((strcmp(sha256_orig, sha256_cur)) &&
(strcmp(sha256_cur, sha256_new)) && (strcmp(sha256_cur, sha256_new)) &&
(strcmp(sha256_orig, sha256_new))) { (strcmp(sha256_orig, sha256_new))) {
const char *version;
version = xbps_pkg_version(pkgver);
assert(version);
buf = xbps_xasprintf(".%s.new-%s", buf = xbps_xasprintf(".%s.new-%s",
cffile, version); cffile, version);
xbps_set_cb_state(xhp, XBPS_STATE_CONFIG_FILE, xbps_set_cb_state(xhp, XBPS_STATE_CONFIG_FILE,
0, pkgname, version, 0, pkgver, version,
"Installing new configuration file to " "Installing new configuration file to "
"`%s.new-%s'.", cffile, version); "`%s.new-%s'.", cffile, version);
archive_entry_set_pathname(entry, buf); archive_entry_set_pathname(entry, buf);
@ -241,8 +240,8 @@ out:
prop_object_iterator_release(iter); prop_object_iterator_release(iter);
xbps_dbg_printf(xhp, "%s-%s: conf_file %s returned %d\n", xbps_dbg_printf(xhp, "%s: conf_file %s returned %d\n",
pkgname, version, entry_pname, rv); pkgver, entry_pname, rv);
return rv; return rv;
} }

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2009-2012 Juan Romero Pardines. * Copyright (c) 2009-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -43,28 +43,30 @@
* *
* @note * @note
* If the \a XBPS_FLAG_FORCE_CONFIGURE is set through xbps_init() in the flags * If the \a XBPS_FLAG_FORCE_CONFIGURE is set through xbps_init() in the flags
* member, the package (or packages) will be reconfigured even if its member, the package (or packages) will be reconfigured even if its
* state is XBPS_PKG_STATE_INSTALLED. * state is XBPS_PKG_STATE_INSTALLED.
*/ */
int int
xbps_configure_packages(struct xbps_handle *xhp, bool flush) xbps_configure_packages(struct xbps_handle *xhp, bool flush)
{ {
prop_dictionary_t pkgd;
prop_object_t obj; prop_object_t obj;
prop_object_iterator_t iter; prop_object_iterator_t iter;
const char *pkgname; const char *pkgver;
int rv; int rv;
if ((rv = xbps_pkgdb_init(xhp)) != 0) if ((rv = xbps_pkgdb_init(xhp)) != 0)
return rv; return rv;
iter = prop_array_iterator(xhp->pkgdb); iter = prop_dictionary_iterator(xhp->pkgdb);
assert(iter); assert(iter);
while ((obj = prop_object_iterator_next(iter))) { while ((obj = prop_object_iterator_next(iter))) {
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); pkgd = prop_dictionary_get_keysym(xhp->pkgdb, obj);
rv = xbps_configure_pkg(xhp, pkgname, true, false, false); prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
rv = xbps_configure_pkg(xhp, pkgver, true, false, false);
if (rv != 0) { if (rv != 0) {
xbps_dbg_printf(xhp, "%s: failed to configure %s: %s\n", xbps_dbg_printf(xhp, "%s: failed to configure %s: %s\n",
__func__, pkgname, strerror(rv)); __func__, pkgver, strerror(rv));
break; break;
} }
} }
@ -78,32 +80,27 @@ xbps_configure_packages(struct xbps_handle *xhp, bool flush)
int int
xbps_configure_pkg(struct xbps_handle *xhp, xbps_configure_pkg(struct xbps_handle *xhp,
const char *pkgname, const char *pkgver,
bool check_state, bool check_state,
bool update, bool update,
bool flush) bool flush)
{ {
prop_dictionary_t pkgd, pkgmetad; prop_dictionary_t pkgd, pkgmetad;
const char *version, *pkgver; char *pkgname, *plist;
char *plist;
int rv = 0; int rv = 0;
pkg_state_t state = 0; pkg_state_t state = 0;
assert(pkgname != NULL); assert(pkgver != NULL);
pkgd = xbps_pkgdb_get_pkg(xhp, pkgname); pkgd = xbps_pkgdb_get_pkg(xhp, pkgver);
if (pkgd == NULL) if (pkgd == NULL)
return ENOENT; return ENOENT;
prop_dictionary_get_cstring_nocopy(pkgd, "version", &version);
prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
rv = xbps_pkg_state_dictionary(pkgd, &state); rv = xbps_pkg_state_dictionary(pkgd, &state);
xbps_dbg_printf(xhp, "%s: state %d rv %d\n", pkgname, state, rv); xbps_dbg_printf(xhp, "%s: state %d rv %d\n", pkgver, state, rv);
if (rv != 0) { if (rv != 0) {
xbps_dbg_printf(xhp, "%s: [configure] failed to get " xbps_dbg_printf(xhp, "%s: [configure] failed to get "
"pkg state: %s\n", pkgname, strerror(rv)); "pkg state: %s\n", pkgver, strerror(rv));
prop_object_release(pkgd);
return EINVAL; return EINVAL;
} }
@ -115,10 +112,13 @@ xbps_configure_pkg(struct xbps_handle *xhp,
return EINVAL; return EINVAL;
} }
xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE, 0, pkgname, version, NULL); xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE, 0, pkgver, NULL);
/* internalize pkg dictionary from metadir */ /* internalize pkg dictionary from metadir */
pkgname = xbps_pkg_name(pkgver);
assert(pkgname);
plist = xbps_xasprintf("%s/.%s.plist", xhp->metadir, pkgname); plist = xbps_xasprintf("%s/.%s.plist", xhp->metadir, pkgname);
free(pkgname);
pkgmetad = prop_dictionary_internalize_from_file(plist); pkgmetad = prop_dictionary_internalize_from_file(plist);
free(plist); free(plist);
assert(pkgmetad); assert(pkgmetad);
@ -126,7 +126,7 @@ xbps_configure_pkg(struct xbps_handle *xhp,
rv = xbps_pkg_exec_script(xhp, pkgmetad, "install-script", "post", update); rv = xbps_pkg_exec_script(xhp, pkgmetad, "install-script", "post", update);
if (rv != 0) { if (rv != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE_FAIL,
errno, pkgname, version, errno, pkgver,
"%s: [configure] INSTALL script failed to execute " "%s: [configure] INSTALL script failed to execute "
"the post ACTION: %s", pkgver, strerror(rv)); "the post ACTION: %s", pkgver, strerror(rv));
return rv; return rv;
@ -139,15 +139,13 @@ xbps_configure_pkg(struct xbps_handle *xhp,
rv = xbps_set_pkg_state_dictionary(pkgd, XBPS_PKG_STATE_INSTALLED); rv = xbps_set_pkg_state_dictionary(pkgd, XBPS_PKG_STATE_INSTALLED);
if (rv != 0) { if (rv != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE_FAIL, rv, xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE_FAIL, rv,
pkgname, version, pkgver, "%s: [configure] failed to set state to installed: %s",
"%s: [configure] failed to set state to installed: %s",
pkgver, strerror(rv)); pkgver, strerror(rv));
} }
if (flush) { if (flush) {
if ((rv = xbps_pkgdb_update(xhp, true)) != 0) { if ((rv = xbps_pkgdb_update(xhp, true)) != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE_FAIL, rv, xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE_FAIL, rv,
pkgname, version, pkgver, "%s: [configure] failed to update pkgdb: %s\n",
"%s: [configure] failed to update pkgdb: %s\n",
pkgver, strerror(rv)); pkgver, strerror(rv));
} }
} }

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2008-2012 Juan Romero Pardines. * Copyright (c) 2008-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -31,68 +31,48 @@
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
/** int HIDDEN
* @file lib/package_register.c xbps_register_pkg(struct xbps_handle *xhp, prop_dictionary_t pkgrd)
* @brief Package registration routines
* @defgroup pkg_register Package registration functions
*
* Register and unregister packages into/from the installed
* packages database.
*/
int
xbps_register_pkg(struct xbps_handle *xhp, prop_dictionary_t pkgrd, bool flush)
{ {
prop_dictionary_t pkgd; prop_dictionary_t pkgd;
prop_array_t provides, rundeps; prop_array_t provides, rundeps;
char outstr[64]; char outstr[64];
time_t t; time_t t;
struct tm *tmp; struct tm *tmp;
const char *pkgname, *version, *desc, *pkgver; const char *desc, *pkgver;
char *buf, *sha256; char *pkgname = NULL, *buf, *sha256;
int rv = 0; int rv = 0;
bool autoinst = false; bool autoinst = false;
assert(prop_object_type(pkgrd) == PROP_TYPE_DICTIONARY); assert(prop_object_type(pkgrd) == PROP_TYPE_DICTIONARY);
prop_dictionary_get_cstring_nocopy(pkgrd, "pkgname", &pkgname);
prop_dictionary_get_cstring_nocopy(pkgrd, "version", &version);
prop_dictionary_get_cstring_nocopy(pkgrd, "short_desc", &desc);
prop_dictionary_get_cstring_nocopy(pkgrd, "pkgver", &pkgver); prop_dictionary_get_cstring_nocopy(pkgrd, "pkgver", &pkgver);
prop_dictionary_get_cstring_nocopy(pkgrd, "short_desc", &desc);
prop_dictionary_get_bool(pkgrd, "automatic-install", &autoinst); prop_dictionary_get_bool(pkgrd, "automatic-install", &autoinst);
provides = prop_dictionary_get(pkgrd, "provides"); provides = prop_dictionary_get(pkgrd, "provides");
rundeps = prop_dictionary_get(pkgrd, "run_depends"); rundeps = prop_dictionary_get(pkgrd, "run_depends");
xbps_set_cb_state(xhp, XBPS_STATE_REGISTER, 0, pkgname, version, NULL); xbps_set_cb_state(xhp, XBPS_STATE_REGISTER, 0, pkgver, NULL);
assert(pkgname != NULL);
assert(version != NULL);
assert(desc != NULL);
assert(pkgver != NULL); assert(pkgver != NULL);
assert(desc != NULL);
pkgd = xbps_pkgdb_get_pkg(xhp, pkgname); pkgd = xbps_pkgdb_get_pkg(xhp, pkgver);
if (pkgd == NULL) { if (pkgd == NULL) {
rv = ENOENT; rv = ENOENT;
goto out; goto out;
} }
if (!prop_dictionary_set_cstring_nocopy(pkgd,
"version", version)) {
xbps_dbg_printf(xhp, "%s: invalid version for %s\n",
__func__, pkgname);
rv = EINVAL;
goto out;
}
if (!prop_dictionary_set_cstring_nocopy(pkgd, if (!prop_dictionary_set_cstring_nocopy(pkgd,
"pkgver", pkgver)) { "pkgver", pkgver)) {
xbps_dbg_printf(xhp, "%s: invalid pkgver for %s\n", xbps_dbg_printf(xhp, "%s: invalid pkgver for %s\n",
__func__, pkgname); __func__, pkgver);
rv = EINVAL; rv = EINVAL;
goto out; goto out;
} }
if (!prop_dictionary_set_cstring_nocopy(pkgd, if (!prop_dictionary_set_cstring_nocopy(pkgd,
"short_desc", desc)) { "short_desc", desc)) {
xbps_dbg_printf(xhp, "%s: invalid short_desc for %s\n", xbps_dbg_printf(xhp, "%s: invalid short_desc for %s\n",
__func__, pkgname); __func__, pkgver);
rv = EINVAL; rv = EINVAL;
goto out; goto out;
} }
@ -105,7 +85,7 @@ xbps_register_pkg(struct xbps_handle *xhp, prop_dictionary_t pkgrd, bool flush)
if (!prop_dictionary_set_bool(pkgd, if (!prop_dictionary_set_bool(pkgd,
"automatic-install", autoinst)) { "automatic-install", autoinst)) {
xbps_dbg_printf(xhp, "%s: invalid autoinst for %s\n", xbps_dbg_printf(xhp, "%s: invalid autoinst for %s\n",
__func__, pkgname); __func__, pkgver);
rv = EINVAL; rv = EINVAL;
goto out; goto out;
} }
@ -115,34 +95,31 @@ xbps_register_pkg(struct xbps_handle *xhp, prop_dictionary_t pkgrd, bool flush)
t = time(NULL); t = time(NULL);
if ((tmp = localtime(&t)) == NULL) { if ((tmp = localtime(&t)) == NULL) {
xbps_dbg_printf(xhp, "%s: localtime failed: %s\n", xbps_dbg_printf(xhp, "%s: localtime failed: %s\n",
pkgname, strerror(errno)); pkgver, strerror(errno));
rv = EINVAL; rv = EINVAL;
goto out; goto out;
} }
if (strftime(outstr, sizeof(outstr)-1, "%F %R %Z", tmp) == 0) { if (strftime(outstr, sizeof(outstr)-1, "%F %R %Z", tmp) == 0) {
xbps_dbg_printf(xhp, "%s: strftime failed: %s\n", xbps_dbg_printf(xhp, "%s: strftime failed: %s\n",
pkgname, strerror(errno)); pkgver, strerror(errno));
rv = EINVAL; rv = EINVAL;
goto out; goto out;
} }
if (!prop_dictionary_set_cstring(pkgd, "install-date", outstr)) { if (!prop_dictionary_set_cstring(pkgd, "install-date", outstr)) {
xbps_dbg_printf(xhp, "%s: install-date set failed!\n", pkgname); xbps_dbg_printf(xhp, "%s: install-date set failed!\n", pkgver);
rv = EINVAL; rv = EINVAL;
goto out; goto out;
} }
if (provides && !prop_dictionary_set(pkgd, "provides", provides)) { if (provides && !prop_dictionary_set(pkgd, "provides", provides)) {
xbps_dbg_printf(xhp, "%s: failed to set provides for %s\n", xbps_dbg_printf(xhp, "%s: failed to set provides for %s\n",
__func__, pkgname); __func__, pkgver);
rv = EINVAL; rv = EINVAL;
goto out; goto out;
} }
if (rundeps == NULL) if (rundeps && !prop_dictionary_set(pkgd, "run_depends", rundeps)) {
rundeps = prop_array_create();
if (!prop_dictionary_set(pkgd, "run_depends", rundeps)) {
xbps_dbg_printf(xhp, "%s: failed to set rundeps for %s\n", xbps_dbg_printf(xhp, "%s: failed to set rundeps for %s\n",
__func__, pkgname); __func__, pkgver);
rv = EINVAL; rv = EINVAL;
goto out; goto out;
} }
@ -150,6 +127,8 @@ xbps_register_pkg(struct xbps_handle *xhp, prop_dictionary_t pkgrd, bool flush)
/* /*
* Create a hash for the pkg's metafile. * Create a hash for the pkg's metafile.
*/ */
pkgname = xbps_pkg_name(pkgver);
assert(pkgname);
buf = xbps_xasprintf("%s/.%s.plist", xhp->metadir, pkgname); buf = xbps_xasprintf("%s/.%s.plist", xhp->metadir, pkgname);
sha256 = xbps_file_hash(buf); sha256 = xbps_file_hash(buf);
assert(sha256); assert(sha256);
@ -163,37 +142,42 @@ xbps_register_pkg(struct xbps_handle *xhp, prop_dictionary_t pkgrd, bool flush)
prop_dictionary_remove(pkgd, "transaction"); prop_dictionary_remove(pkgd, "transaction");
prop_dictionary_remove(pkgd, "skip-obsoletes"); prop_dictionary_remove(pkgd, "skip-obsoletes");
if (!xbps_pkgdb_replace_pkg(xhp, pkgd, pkgname, flush)) { if (!prop_dictionary_set(xhp->pkgdb, pkgname, pkgd)) {
xbps_dbg_printf(xhp, xbps_dbg_printf(xhp,
"%s: failed to replace pkgd dict for %s\n", "%s: failed to set pkgd for %s\n", __func__, pkgver);
__func__, pkgname);
goto out; goto out;
} }
(void)xbps_pkgdb_update(xhp, true);
out: out:
if (pkgname)
free(pkgname);
if (rv != 0) { if (rv != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_REGISTER_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_REGISTER_FAIL,
rv, pkgname, version, rv, pkgver, "%s: failed to register package: %s",
"%s: failed to register package: %s",
pkgver, strerror(rv)); pkgver, strerror(rv));
} }
return rv; return rv;
} }
int int HIDDEN
xbps_unregister_pkg(struct xbps_handle *xhp, const char *pkgver, bool flush) xbps_unregister_pkg(struct xbps_handle *xhp, const char *pkgver)
{ {
char *pkgname;
assert(xhp); assert(xhp);
assert(pkgver); assert(pkgver);
xbps_set_cb_state(xhp, XBPS_STATE_UNREGISTER, 0, pkgver, NULL, NULL); xbps_set_cb_state(xhp, XBPS_STATE_UNREGISTER, 0, pkgver, NULL, NULL);
if (!xbps_pkgdb_remove_pkg(xhp, pkgver, flush)) { pkgname = xbps_pkg_name(pkgver);
xbps_set_cb_state(xhp, XBPS_STATE_UNREGISTER_FAIL, assert(pkgname);
errno, pkgver, NULL, prop_dictionary_remove(xhp->pkgdb, pkgname);
"%s: failed to unregister package: %s", free(pkgname);
pkgver, strerror(errno));
return errno; (void)xbps_pkgdb_update(xhp, true);
}
return 0; return 0;
} }

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2009-2012 Juan Romero Pardines. * Copyright (c) 2009-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -33,45 +33,7 @@
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
/** int HIDDEN
* @file lib/package_remove.c
* @brief Package removal routines
* @defgroup pkg_remove Package removal functions
*
* These functions will remove a package or only a subset of its
* files. Package removal steps:
* -# Its <b>pre-remove</b> target specified in the REMOVE script
* will be executed.
* -# Its links, files, conf_files and dirs will be removed.
* Modified files (not matchings its sha256 hash) are preserved, unless
* XBPS_FLAG_FORCE_REMOVE_FILES flag is set via xbps_init::flags member.
* -# Its <b>post-remove</b> target specified in the REMOVE script
* will be executed.
* -# Its state will be changed to XBPS_PKG_STATE_HALF_REMOVED.
* -# Its <b>purge-remove</b> target specified in the REMOVE script
* will be executed.
* -# Its package metadata file will be removed.
* -# Package will be unregistered from package database.
*
* @note
* -# If a package is going to be updated, only steps <b>1</b> and <b>4</b>
* will be executed.
* -# If a package is going to be removed, all steps will be executed.
*
* The following image shows the structure of an internalized package's
* files.plist dictionary:
*
* @image html images/xbps_pkg_files_dictionary.png
*
* Legend:
* - <b>Salmon bg box</b>: XBPS_PKGFILES plist file.
* - <b>White bg box</b>: mandatory objects.
* - <b>Grey bg box</b>: optional objects.
*
* Text inside of white boxes are the key associated with the object, its
* data type is specified on its edge, i.e string, array, integer, dictionary.
*/
int
xbps_remove_pkg_files(struct xbps_handle *xhp, xbps_remove_pkg_files(struct xbps_handle *xhp,
prop_dictionary_t dict, prop_dictionary_t dict,
const char *key, const char *key,
@ -81,7 +43,7 @@ xbps_remove_pkg_files(struct xbps_handle *xhp,
prop_array_t array; prop_array_t array;
prop_object_iterator_t iter; prop_object_iterator_t iter;
prop_object_t obj; prop_object_t obj;
const char *file, *sha256, *version, *curobj = NULL; const char *file, *sha256, *curobj = NULL;
char *path = NULL, *pkgname = NULL; char *path = NULL, *pkgname = NULL;
char buf[PATH_MAX]; char buf[PATH_MAX];
int rv = 0; int rv = 0;
@ -109,7 +71,6 @@ xbps_remove_pkg_files(struct xbps_handle *xhp,
pkgname = xbps_pkg_name(pkgver); pkgname = xbps_pkg_name(pkgver);
assert(pkgname); assert(pkgname);
version = xbps_pkg_version(pkgver);
while ((obj = prop_object_iterator_next(iter))) { while ((obj = prop_object_iterator_next(iter))) {
prop_dictionary_get_cstring_nocopy(obj, "file", &file); prop_dictionary_get_cstring_nocopy(obj, "file", &file);
@ -128,7 +89,7 @@ xbps_remove_pkg_files(struct xbps_handle *xhp,
/* missing file, ignore it */ /* missing file, ignore it */
xbps_set_cb_state(xhp, xbps_set_cb_state(xhp,
XBPS_STATE_REMOVE_FILE_HASH_FAIL, XBPS_STATE_REMOVE_FILE_HASH_FAIL,
rv, pkgname, version, rv, pkgver,
"%s: failed to check hash for %s `%s': %s", "%s: failed to check hash for %s `%s': %s",
pkgver, curobj, file, strerror(rv)); pkgver, curobj, file, strerror(rv));
free(path); free(path);
@ -140,7 +101,7 @@ xbps_remove_pkg_files(struct xbps_handle *xhp,
XBPS_FLAG_FORCE_REMOVE_FILES) == 0) { XBPS_FLAG_FORCE_REMOVE_FILES) == 0) {
xbps_set_cb_state(xhp, xbps_set_cb_state(xhp,
XBPS_STATE_REMOVE_FILE_HASH_FAIL, XBPS_STATE_REMOVE_FILE_HASH_FAIL,
0, pkgname, version, 0, pkgver,
"%s: %s `%s' SHA256 mismatch, " "%s: %s `%s' SHA256 mismatch, "
"preserving file", pkgver, "preserving file", pkgver,
curobj, file); curobj, file);
@ -149,7 +110,7 @@ xbps_remove_pkg_files(struct xbps_handle *xhp,
} else { } else {
xbps_set_cb_state(xhp, xbps_set_cb_state(xhp,
XBPS_STATE_REMOVE_FILE_HASH_FAIL, XBPS_STATE_REMOVE_FILE_HASH_FAIL,
0, pkgname, version, 0, pkgver,
"%s: %s `%s' SHA256 mismatch, " "%s: %s `%s' SHA256 mismatch, "
"forcing removal", pkgver, "forcing removal", pkgver,
curobj, file); curobj, file);
@ -157,7 +118,7 @@ xbps_remove_pkg_files(struct xbps_handle *xhp,
} else if (rv != 0 && rv != ERANGE) { } else if (rv != 0 && rv != ERANGE) {
xbps_set_cb_state(xhp, xbps_set_cb_state(xhp,
XBPS_STATE_REMOVE_FILE_HASH_FAIL, XBPS_STATE_REMOVE_FILE_HASH_FAIL,
rv, pkgname, version, rv, pkgver,
"%s: [remove] failed to check hash for " "%s: [remove] failed to check hash for "
"%s `%s': %s", pkgver, curobj, file, "%s `%s': %s", pkgver, curobj, file,
strerror(rv)); strerror(rv));
@ -186,15 +147,14 @@ xbps_remove_pkg_files(struct xbps_handle *xhp,
*/ */
if (remove(path) == -1) { if (remove(path) == -1) {
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE_FAIL,
errno, pkgname, version, errno, pkgver,
"%s: failed to remove %s `%s': %s", pkgver, "%s: failed to remove %s `%s': %s", pkgver,
curobj, file, strerror(errno)); curobj, file, strerror(errno));
errno = 0; errno = 0;
} else { } else {
/* success */ /* success */
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE, xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE,
0, pkgname, version, 0, pkgver, "Removed %s `%s'", curobj, file);
"Removed %s `%s'", curobj, file);
} }
free(path); free(path);
} }
@ -204,7 +164,7 @@ xbps_remove_pkg_files(struct xbps_handle *xhp,
return rv; return rv;
} }
int int HIDDEN
xbps_remove_pkg(struct xbps_handle *xhp, xbps_remove_pkg(struct xbps_handle *xhp,
const char *pkgver, const char *pkgver,
bool update, bool update,
@ -231,12 +191,12 @@ xbps_remove_pkg(struct xbps_handle *xhp,
pkgver, state); pkgver, state);
if (!update) if (!update)
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE, 0, pkgname, version, NULL); xbps_set_cb_state(xhp, XBPS_STATE_REMOVE, 0, pkgver, NULL);
if (chdir(xhp->rootdir) == -1) { if (chdir(xhp->rootdir) == -1) {
rv = errno; rv = errno;
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL,
rv, pkgname, version, rv, pkgver,
"%s: [remove] failed to chdir to rootdir `%s': %s", "%s: [remove] failed to chdir to rootdir `%s': %s",
pkgver, xhp->rootdir, strerror(rv)); pkgver, xhp->rootdir, strerror(rv));
goto out; goto out;
@ -248,7 +208,7 @@ xbps_remove_pkg(struct xbps_handle *xhp,
free(buf); free(buf);
if (pkgd == NULL) if (pkgd == NULL)
xbps_dbg_printf(xhp, "WARNING: metaplist for %s " xbps_dbg_printf(xhp, "WARNING: metaplist for %s "
"doesn't exist!\n", pkgname); "doesn't exist!\n", pkgver);
/* If package was "half-removed", remove it fully. */ /* If package was "half-removed", remove it fully. */
if (state == XBPS_PKG_STATE_HALF_REMOVED) if (state == XBPS_PKG_STATE_HALF_REMOVED)
@ -261,7 +221,7 @@ xbps_remove_pkg(struct xbps_handle *xhp,
"pre", update); "pre", update);
if (rv != 0) { if (rv != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL,
errno, pkgname, version, errno, pkgver,
"%s: [remove] REMOVE script failed to " "%s: [remove] REMOVE script failed to "
"execute pre ACTION: %s", "execute pre ACTION: %s",
pkgver, strerror(rv)); pkgver, strerror(rv));
@ -307,7 +267,7 @@ xbps_remove_pkg(struct xbps_handle *xhp,
rv = xbps_pkg_exec_script(xhp, pkgd, "remove-script", "post", false); rv = xbps_pkg_exec_script(xhp, pkgd, "remove-script", "post", false);
if (rv != 0) { if (rv != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL,
rv, pkgname, version, rv, pkgver,
"%s: [remove] REMOVE script failed to execute " "%s: [remove] REMOVE script failed to execute "
"post ACTION: %s", pkgver, strerror(rv)); "post ACTION: %s", pkgver, strerror(rv));
goto out; goto out;
@ -318,11 +278,11 @@ softreplace:
/* /*
* Set package state to "half-removed". * Set package state to "half-removed".
*/ */
rv = xbps_set_pkg_state_installed(xhp, pkgname, version, rv = xbps_set_pkg_state_installed(xhp, pkgver,
XBPS_PKG_STATE_HALF_REMOVED); XBPS_PKG_STATE_HALF_REMOVED);
if (rv != 0) { if (rv != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL,
rv, pkgname, version, rv, pkgver,
"%s: [remove] failed to set state to half-removed: %s", "%s: [remove] failed to set state to half-removed: %s",
pkgver, strerror(rv)); pkgver, strerror(rv));
goto out; goto out;
@ -336,7 +296,7 @@ purge:
rv = xbps_pkg_exec_script(xhp, pkgd, "remove-script", "purge", false); rv = xbps_pkg_exec_script(xhp, pkgd, "remove-script", "purge", false);
if (rv != 0) { if (rv != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL,
rv, pkgname, version, rv, pkgver,
"%s: REMOVE script failed to execute " "%s: REMOVE script failed to execute "
"purge ACTION: %s", pkgver, strerror(rv)); "purge ACTION: %s", pkgver, strerror(rv));
goto out; goto out;
@ -350,7 +310,7 @@ purge:
if (remove(buf) == -1) { if (remove(buf) == -1) {
if (errno != ENOENT) { if (errno != ENOENT) {
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL,
rv, pkgname, version, rv, pkgver,
"%s: failed to remove metadata file: %s", "%s: failed to remove metadata file: %s",
pkgver, strerror(errno)); pkgver, strerror(errno));
} }
@ -359,13 +319,12 @@ purge:
/* /*
* Unregister package from pkgdb. * Unregister package from pkgdb.
*/ */
if ((rv = xbps_unregister_pkg(xhp, pkgver, true)) != 0) if ((rv = xbps_unregister_pkg(xhp, pkgver)) != 0)
goto out; goto out;
xbps_dbg_printf(xhp, "[remove] unregister %s returned %d\n", pkgver, rv); xbps_dbg_printf(xhp, "[remove] unregister %s returned %d\n", pkgver, rv);
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_DONE, xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_DONE, 0, pkgver, NULL);
0, pkgname, version, NULL);
out: out:
if (pkgname != NULL) if (pkgname != NULL)
free(pkgname); free(pkgname);

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2012 Juan Romero Pardines. * Copyright (c) 2012-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -35,8 +35,7 @@ int
xbps_pkg_exec_buffer(struct xbps_handle *xhp, xbps_pkg_exec_buffer(struct xbps_handle *xhp,
const void *blob, const void *blob,
const size_t blobsiz, const size_t blobsiz,
const char *pkgname, const char *pkgver,
const char *version,
const char *action, const char *action,
bool update) bool update)
{ {
@ -46,8 +45,7 @@ xbps_pkg_exec_buffer(struct xbps_handle *xhp,
int fd, rv; int fd, rv;
assert(blob); assert(blob);
assert(pkgname); assert(pkgver);
assert(version);
assert(action); assert(action);
if (strcmp(xhp->rootdir, "/") == 0) { if (strcmp(xhp->rootdir, "/") == 0) {
@ -87,7 +85,7 @@ xbps_pkg_exec_buffer(struct xbps_handle *xhp,
close(fd); close(fd);
/* exec script */ /* exec script */
rv = xbps_file_exec(xhp, fpath, action, pkgname, version, rv = xbps_file_exec(xhp, fpath, action, pkgver,
update ? "yes" : "no", update ? "yes" : "no",
xhp->conffile, NULL); xhp->conffile, NULL);
@ -105,7 +103,7 @@ xbps_pkg_exec_script(struct xbps_handle *xhp,
bool update) bool update)
{ {
prop_data_t data; prop_data_t data;
const char *pkgname, *version; const char *pkgver;
assert(xhp); assert(xhp);
assert(d); assert(d);
@ -116,10 +114,8 @@ xbps_pkg_exec_script(struct xbps_handle *xhp,
if (data == NULL) if (data == NULL)
return 0; return 0;
prop_dictionary_get_cstring_nocopy(d, "pkgname", &pkgname); prop_dictionary_get_cstring_nocopy(d, "pkgver", &pkgver);
prop_dictionary_get_cstring_nocopy(d, "version", &version);
return xbps_pkg_exec_buffer(xhp, prop_data_data(data), return xbps_pkg_exec_buffer(xhp, prop_data_data(data),
prop_data_size(data), pkgname, version, prop_data_size(data), pkgver, action, update);
action, update);
} }

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2009-2012 Juan Romero Pardines. * Copyright (c) 2009-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -93,15 +93,15 @@ get_state(prop_dictionary_t dict)
int int
xbps_pkg_state_installed(struct xbps_handle *xhp, xbps_pkg_state_installed(struct xbps_handle *xhp,
const char *pkgname, const char *pkgver,
pkg_state_t *state) pkg_state_t *state)
{ {
prop_dictionary_t pkgd; prop_dictionary_t pkgd;
assert(pkgname != NULL); assert(pkgver != NULL);
assert(state != NULL); assert(state != NULL);
pkgd = xbps_pkgdb_get_pkg(xhp, pkgname); pkgd = xbps_pkgdb_get_pkg(xhp, pkgver);
if (pkgd == NULL) if (pkgd == NULL)
return ENOENT; return ENOENT;
@ -133,46 +133,32 @@ xbps_set_pkg_state_dictionary(prop_dictionary_t dict, pkg_state_t state)
} }
static int static int
set_pkg_objs(prop_dictionary_t pkgd, const char *name, const char *version) set_pkg_objs(prop_dictionary_t pkgd, const char *pkgver)
{ {
char *pkgver; if (!prop_dictionary_set_cstring_nocopy(pkgd, "pkgver", pkgver))
if (!prop_dictionary_set_cstring_nocopy(pkgd, "pkgname", name))
return EINVAL; return EINVAL;
if (!prop_dictionary_set_cstring_nocopy(pkgd, "version", version))
return EINVAL;
pkgver = xbps_xasprintf("%s-%s", name, version);
assert(pkgver != NULL);
if (!prop_dictionary_set_cstring_nocopy(pkgd, "pkgver", pkgver)) {
free(pkgver);
return EINVAL;
}
free(pkgver);
return 0; return 0;
} }
int int
xbps_set_pkg_state_installed(struct xbps_handle *xhp, xbps_set_pkg_state_installed(struct xbps_handle *xhp,
const char *pkgname, const char *pkgver,
const char *version,
pkg_state_t state) pkg_state_t state)
{ {
prop_dictionary_t pkgd; prop_dictionary_t pkgd;
char *pkgname;
int rv = 0; int rv = 0;
assert(pkgname != NULL); assert(pkgver != NULL);
pkgd = xbps_pkgdb_get_pkg(xhp, pkgname); pkgd = xbps_pkgdb_get_pkg(xhp, pkgver);
if (pkgd == NULL) { if (pkgd == NULL) {
pkgd = prop_dictionary_create(); pkgd = prop_dictionary_create();
if (pkgd == NULL) if (pkgd == NULL)
return ENOMEM; return ENOMEM;
if ((rv = set_pkg_objs(pkgd, pkgname, version)) != 0) { if ((rv = set_pkg_objs(pkgd, pkgver)) != 0) {
prop_object_release(pkgd); prop_object_release(pkgd);
return rv; return rv;
} }
@ -180,17 +166,25 @@ xbps_set_pkg_state_installed(struct xbps_handle *xhp,
prop_object_release(pkgd); prop_object_release(pkgd);
return rv; return rv;
} }
if (!xbps_add_obj_to_array(xhp->pkgdb, pkgd)) { pkgname = xbps_pkg_name(pkgver);
assert(pkgname);
if (!prop_dictionary_set(xhp->pkgdb, pkgname, pkgd)) {
prop_object_release(pkgd); prop_object_release(pkgd);
free(pkgname);
return EINVAL; return EINVAL;
} }
free(pkgname);
} else { } else {
if ((rv = set_new_state(pkgd, state)) != 0) if ((rv = set_new_state(pkgd, state)) != 0)
return rv; return rv;
if ((rv = xbps_array_replace_dict_by_name(xhp->pkgdb, pkgname = xbps_pkg_name(pkgver);
pkgd, pkgname)) != 0) assert(pkgname);
return rv; if (!prop_dictionary_set(xhp->pkgdb, pkgname, pkgd)) {
free(pkgname);
return EINVAL;
}
free(pkgname);
} }
return rv; return rv;

View File

@ -82,9 +82,11 @@ find_pkg_symlink_target(prop_dictionary_t d, const char *file)
static int static int
unpack_archive(struct xbps_handle *xhp, unpack_archive(struct xbps_handle *xhp,
prop_dictionary_t pkg_repod, prop_dictionary_t pkg_repod,
const char *pkgver,
const char *fname,
struct archive *ar) struct archive *ar)
{ {
prop_dictionary_t pkg_metad = NULL, filesd = NULL, old_filesd = NULL; prop_dictionary_t pkg_metad, propsd, filesd, old_filesd;
prop_array_t array, obsoletes; prop_array_t array, obsoletes;
prop_object_t obj; prop_object_t obj;
prop_data_t data; prop_data_t data;
@ -93,12 +95,10 @@ unpack_archive(struct xbps_handle *xhp,
struct stat st; struct stat st;
struct xbps_unpack_cb_data xucd; struct xbps_unpack_cb_data xucd;
struct archive_entry *entry; struct archive_entry *entry;
size_t i, entry_idx = 0; size_t i, entry_idx = 0, instbufsiz, rembufsiz;
size_t instbufsiz, rembufsiz;
ssize_t entry_size; ssize_t entry_size;
const char *file, *entry_pname, *transact, *pkgname; const char *file, *entry_pname, *transact, *tgtlnk;
const char *version, *pkgver, *fname, *tgtlnk; char *pkgname, *dname, *buf, *buf2, *p, *p2;
char *dname, *buf, *buf2, *p, *p2;
int ar_rv, rv, rv_stat, flags; int ar_rv, rv, rv_stat, flags;
bool preserve, update, conf_file, file_exists, skip_obsoletes; bool preserve, update, conf_file, file_exists, skip_obsoletes;
bool softreplace, skip_extract, force; bool softreplace, skip_extract, force;
@ -107,6 +107,7 @@ unpack_archive(struct xbps_handle *xhp,
assert(prop_object_type(pkg_repod) == PROP_TYPE_DICTIONARY); assert(prop_object_type(pkg_repod) == PROP_TYPE_DICTIONARY);
assert(ar != NULL); assert(ar != NULL);
pkg_metad = propsd = filesd = old_filesd = NULL;
force = preserve = update = conf_file = file_exists = false; force = preserve = update = conf_file = file_exists = false;
skip_obsoletes = softreplace = false; skip_obsoletes = softreplace = false;
@ -115,10 +116,6 @@ unpack_archive(struct xbps_handle *xhp,
prop_dictionary_get_bool(pkg_repod, "softreplace", &softreplace); prop_dictionary_get_bool(pkg_repod, "softreplace", &softreplace);
prop_dictionary_get_cstring_nocopy(pkg_repod, prop_dictionary_get_cstring_nocopy(pkg_repod,
"transaction", &transact); "transaction", &transact);
prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgname", &pkgname);
prop_dictionary_get_cstring_nocopy(pkg_repod, "version", &version);
prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgver", &pkgver);
prop_dictionary_get_cstring_nocopy(pkg_repod, "filename", &fname);
euid = geteuid(); euid = geteuid();
@ -141,7 +138,7 @@ unpack_archive(struct xbps_handle *xhp,
} }
if (chdir(xhp->rootdir) == -1) { if (chdir(xhp->rootdir) == -1) {
xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL,
errno, pkgname, version, errno, pkgver,
"%s: [unpack] failed to chdir to rootdir `%s': %s", "%s: [unpack] failed to chdir to rootdir `%s': %s",
pkgver, xhp->rootdir, strerror(errno)); pkgver, xhp->rootdir, strerror(errno));
rv = errno; rv = errno;
@ -197,11 +194,11 @@ unpack_archive(struct xbps_handle *xhp,
} }
rv = xbps_pkg_exec_buffer(xhp, instbuf, instbufsiz, rv = xbps_pkg_exec_buffer(xhp, instbuf, instbufsiz,
pkgname, version, "pre", update); pkgver, "pre", update);
if (rv != 0) { if (rv != 0) {
xbps_set_cb_state(xhp, xbps_set_cb_state(xhp,
XBPS_STATE_UNPACK_FAIL, XBPS_STATE_UNPACK_FAIL,
rv, pkgname, version, rv, pkgver,
"%s: [unpack] INSTALL script failed " "%s: [unpack] INSTALL script failed "
"to execute pre ACTION: %s", "to execute pre ACTION: %s",
pkgver, strerror(rv)); pkgver, strerror(rv));
@ -236,15 +233,18 @@ unpack_archive(struct xbps_handle *xhp,
} }
continue; continue;
} else if (strcmp("./props.plist", entry_pname) == 0) { } else if (strcmp("./props.plist", entry_pname) == 0) {
/* ignore this one; we use pkg data from repo index */ propsd = xbps_dictionary_from_archive_entry(ar, entry);
archive_read_data_skip(ar); if (propsd == NULL) {
rv = errno;
goto out;
}
continue; continue;
} }
/* /*
* If XBPS_PKGFILES or XBPS_PKGPROPS weren't found * If XBPS_PKGFILES or XBPS_PKGPROPS weren't found
* in the archive at this phase, skip all data. * in the archive at this phase, skip all data.
*/ */
if (filesd == NULL) { if (propsd == NULL || filesd == NULL) {
archive_read_data_skip(ar); archive_read_data_skip(ar);
/* /*
* If we have processed 4 entries and the two * If we have processed 4 entries and the two
@ -254,7 +254,7 @@ unpack_archive(struct xbps_handle *xhp,
if (entry_idx >= 3) { if (entry_idx >= 3) {
xbps_set_cb_state(xhp, xbps_set_cb_state(xhp,
XBPS_STATE_UNPACK_FAIL, XBPS_STATE_UNPACK_FAIL,
ENODEV, pkgname, version, ENODEV, pkgver,
"%s: [unpack] invalid binary package `%s'.", "%s: [unpack] invalid binary package `%s'.",
pkgver, fname); pkgver, fname);
rv = ENODEV; rv = ENODEV;
@ -301,14 +301,13 @@ unpack_archive(struct xbps_handle *xhp,
* "conf_files" array on its XBPS_PKGPROPS * "conf_files" array on its XBPS_PKGPROPS
* dictionary. * dictionary.
*/ */
if (xbps_entry_is_a_conf_file(pkg_repod, buf)) { if (xbps_entry_is_a_conf_file(propsd, buf)) {
conf_file = true; conf_file = true;
if (xhp->unpack_cb != NULL) if (xhp->unpack_cb != NULL)
xucd.entry_is_conf = true; xucd.entry_is_conf = true;
rv = xbps_entry_install_conf_file(xhp, rv = xbps_entry_install_conf_file(xhp,
filesd, entry, entry_pname, filesd, entry, entry_pname, pkgver);
pkgname, version);
if (rv == -1) { if (rv == -1) {
/* error */ /* error */
goto out; goto out;
@ -324,10 +323,9 @@ unpack_archive(struct xbps_handle *xhp,
if (rv == -1) { if (rv == -1) {
/* error */ /* error */
xbps_dbg_printf(xhp, xbps_dbg_printf(xhp,
"%s-%s: failed to check" "%s: failed to check"
" hash for `%s': %s\n", " hash for `%s': %s\n",
pkgname, version, pkgver, entry_pname,
entry_pname,
strerror(errno)); strerror(errno));
goto out; goto out;
} else if (rv == 0) { } else if (rv == 0) {
@ -335,10 +333,10 @@ unpack_archive(struct xbps_handle *xhp,
* hash match, skip extraction. * hash match, skip extraction.
*/ */
xbps_dbg_printf(xhp, xbps_dbg_printf(xhp,
"%s-%s: file %s " "%s: file %s "
"matches existing SHA256, " "matches existing SHA256, "
"skipping...\n", pkgname, "skipping...\n",
version, entry_pname); pkgver, entry_pname);
skip_extract = true; skip_extract = true;
} }
} }
@ -372,9 +370,9 @@ unpack_archive(struct xbps_handle *xhp,
"new: %s\n", pkgver, entry_pname, p, p2); "new: %s\n", pkgver, entry_pname, p, p2);
if (strcmp(p, p2) == 0) { if (strcmp(p, p2) == 0) {
xbps_dbg_printf(xhp, "%s-%s: symlink " xbps_dbg_printf(xhp, "%s: symlink "
"%s matched, skipping...\n", "%s matched, skipping...\n",
pkgname, version, entry_pname); pkgver, entry_pname);
skip_extract = true; skip_extract = true;
} }
free(buf); free(buf);
@ -389,17 +387,16 @@ unpack_archive(struct xbps_handle *xhp,
if (chmod(entry_pname, if (chmod(entry_pname,
entry_statp->st_mode) != 0) { entry_statp->st_mode) != 0) {
xbps_dbg_printf(xhp, xbps_dbg_printf(xhp,
"%s-%s: failed " "%s: failed "
"to set perms %s to %s: %s\n", "to set perms %s to %s: %s\n",
pkgname, version, pkgver, archive_entry_strmode(entry),
archive_entry_strmode(entry),
entry_pname, entry_pname,
strerror(errno)); strerror(errno));
rv = EINVAL; rv = EINVAL;
goto out; goto out;
} }
xbps_dbg_printf(xhp, "%s-%s: entry %s changed file " xbps_dbg_printf(xhp, "%s: entry %s changed file "
"mode to %s.\n", pkgname, version, entry_pname, "mode to %s.\n", pkgver, entry_pname,
archive_entry_strmode(entry)); archive_entry_strmode(entry));
} }
/* /*
@ -412,15 +409,13 @@ unpack_archive(struct xbps_handle *xhp,
if (chown(entry_pname, if (chown(entry_pname,
entry_statp->st_uid, entry_statp->st_gid) != 0) { entry_statp->st_uid, entry_statp->st_gid) != 0) {
xbps_dbg_printf(xhp, xbps_dbg_printf(xhp,
"%s-%s: failed " "%s: failed "
"to set uid/gid to %u:%u (%s)\n", "to set uid/gid to %u:%u (%s)\n",
pkgname, version, pkgver, entry_statp->st_uid, entry_statp->st_gid,
entry_statp->st_uid, entry_statp->st_gid,
strerror(errno)); strerror(errno));
} else { } else {
xbps_dbg_printf(xhp, "%s-%s: entry %s changed " xbps_dbg_printf(xhp, "%s: entry %s changed "
"uid/gid to %u:%u.\n", pkgname, version, "uid/gid to %u:%u.\n", pkgver, entry_pname,
entry_pname,
entry_statp->st_uid, entry_statp->st_gid); entry_statp->st_uid, entry_statp->st_gid);
} }
} }
@ -435,8 +430,7 @@ unpack_archive(struct xbps_handle *xhp,
free(buf); free(buf);
buf = NULL; buf = NULL;
xbps_set_cb_state(xhp, xbps_set_cb_state(xhp,
XBPS_STATE_CONFIG_FILE, 0, XBPS_STATE_CONFIG_FILE, 0, pkgver,
pkgname, version,
"Renamed old configuration file " "Renamed old configuration file "
"`%s' to `%s.old'.", entry_pname, entry_pname); "`%s' to `%s.old'.", entry_pname, entry_pname);
} }
@ -456,7 +450,7 @@ unpack_archive(struct xbps_handle *xhp,
if (archive_read_extract(ar, entry, flags) != 0) { if (archive_read_extract(ar, entry, flags) != 0) {
rv = archive_errno(ar); rv = archive_errno(ar);
xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL,
rv, pkgname, version, rv, pkgver, NULL,
"%s: [unpack] failed to extract file `%s': %s", "%s: [unpack] failed to extract file `%s': %s",
pkgver, entry_pname, strerror(rv)); pkgver, entry_pname, strerror(rv));
} else { } else {
@ -471,7 +465,7 @@ unpack_archive(struct xbps_handle *xhp,
*/ */
if ((rv = archive_errno(ar)) != 0) { if ((rv = archive_errno(ar)) != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL,
rv, pkgname, version, rv, pkgver, NULL,
"%s: [unpack] failed to extract files: %s", "%s: [unpack] failed to extract files: %s",
pkgver, fname, archive_error_string(ar)); pkgver, fname, archive_error_string(ar));
goto out; goto out;
@ -490,7 +484,7 @@ unpack_archive(struct xbps_handle *xhp,
* - Package upgrade. * - Package upgrade.
* - Package with "softreplace" keyword. * - Package with "softreplace" keyword.
*/ */
old_filesd = xbps_pkgdb_get_pkg_metadata(xhp, pkgname); old_filesd = xbps_pkgdb_get_pkg_metadata(xhp, pkgver);
if (old_filesd == NULL) if (old_filesd == NULL)
goto out1; goto out1;
@ -501,21 +495,21 @@ unpack_archive(struct xbps_handle *xhp,
if (remove(file) == -1) { if (remove(file) == -1) {
xbps_set_cb_state(xhp, xbps_set_cb_state(xhp,
XBPS_STATE_REMOVE_FILE_OBSOLETE_FAIL, XBPS_STATE_REMOVE_FILE_OBSOLETE_FAIL,
errno, pkgname, version, errno, pkgver, NULL,
"%s: failed to remove obsolete entry `%s': %s", "%s: failed to remove obsolete entry `%s': %s",
pkgver, file, strerror(errno)); pkgver, file, strerror(errno));
continue; continue;
} }
xbps_set_cb_state(xhp, xbps_set_cb_state(xhp,
XBPS_STATE_REMOVE_FILE_OBSOLETE, XBPS_STATE_REMOVE_FILE_OBSOLETE,
0, pkgname, version, 0, pkgver, NULL,
"%s: removed obsolete entry: %s", pkgver, file); "%s: removed obsolete entry: %s", pkgver, file);
prop_object_release(obj); prop_object_release(obj);
} }
out1: out1:
prop_dictionary_make_immutable(pkg_repod); prop_dictionary_make_immutable(propsd);
pkg_metad = prop_dictionary_copy_mutable(pkg_repod); pkg_metad = prop_dictionary_copy_mutable(propsd);
/* Add objects from XBPS_PKGFILES */ /* Add objects from XBPS_PKGFILES */
array = prop_dictionary_get(filesd, "files"); array = prop_dictionary_get(filesd, "files");
@ -550,6 +544,8 @@ out1:
prop_dictionary_remove(pkg_metad, "remove-and-update"); prop_dictionary_remove(pkg_metad, "remove-and-update");
prop_dictionary_remove(pkg_metad, "transaction"); prop_dictionary_remove(pkg_metad, "transaction");
prop_dictionary_remove(pkg_metad, "state"); prop_dictionary_remove(pkg_metad, "state");
prop_dictionary_remove(pkg_metad, "pkgname");
prop_dictionary_remove(pkg_metad, "version");
/* /*
* Externalize pkg dictionary to metadir. * Externalize pkg dictionary to metadir.
@ -562,22 +558,29 @@ out1:
goto out; goto out;
} }
} }
pkgname = xbps_pkg_name(pkgver);
assert(pkgname);
buf = xbps_xasprintf("%s/.%s.plist", XBPS_META_PATH, pkgname); buf = xbps_xasprintf("%s/.%s.plist", XBPS_META_PATH, pkgname);
if (!prop_dictionary_externalize_to_file(pkg_metad, buf)) { if (!prop_dictionary_externalize_to_file(pkg_metad, buf)) {
rv = errno; rv = errno;
xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL,
errno, pkgname, version, errno, pkgver,
"%s: [unpack] failed to extract metadata file `%s': %s", "%s: [unpack] failed to extract metadata file `%s': %s",
pkgver, buf, strerror(errno)); pkgver, buf, strerror(errno));
free(buf); free(buf);
free(pkgname);
goto out; goto out;
} }
free(buf); free(buf);
free(pkgname);
out: out:
if (prop_object_type(pkg_metad) == PROP_TYPE_DICTIONARY) if (prop_object_type(pkg_metad) == PROP_TYPE_DICTIONARY)
prop_object_release(pkg_metad); prop_object_release(pkg_metad);
if (prop_object_type(filesd) == PROP_TYPE_DICTIONARY) if (prop_object_type(filesd) == PROP_TYPE_DICTIONARY)
prop_object_release(filesd); prop_object_release(filesd);
if (prop_object_type(propsd) == PROP_TYPE_DICTIONARY)
prop_object_release(propsd);
return rv; return rv;
} }
@ -586,22 +589,19 @@ int HIDDEN
xbps_unpack_binary_pkg(struct xbps_handle *xhp, prop_dictionary_t pkg_repod) xbps_unpack_binary_pkg(struct xbps_handle *xhp, prop_dictionary_t pkg_repod)
{ {
struct archive *ar = NULL; struct archive *ar = NULL;
const char *pkgname, *version, *pkgver; const char *pkgver;
char *bpkg; char *bpkg;
int pkg_fd, rv = 0; int pkg_fd, rv = 0;
assert(prop_object_type(pkg_repod) == PROP_TYPE_DICTIONARY); assert(prop_object_type(pkg_repod) == PROP_TYPE_DICTIONARY);
prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgname", &pkgname);
prop_dictionary_get_cstring_nocopy(pkg_repod, "version", &version);
prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgver", &pkgver); prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgver", &pkgver);
xbps_set_cb_state(xhp, XBPS_STATE_UNPACK, 0, pkgver, NULL, NULL);
xbps_set_cb_state(xhp, XBPS_STATE_UNPACK, 0, pkgname, version, NULL);
bpkg = xbps_repository_pkg_path(xhp, pkg_repod); bpkg = xbps_repository_pkg_path(xhp, pkg_repod);
if (bpkg == NULL) { if (bpkg == NULL) {
xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL,
errno, pkgname, version, errno, pkgver,
"%s: [unpack] cannot determine binary package " "%s: [unpack] cannot determine binary package "
"file for `%s': %s", pkgver, bpkg, strerror(errno)); "file for `%s': %s", pkgver, bpkg, strerror(errno));
return errno; return errno;
@ -623,7 +623,7 @@ xbps_unpack_binary_pkg(struct xbps_handle *xhp, prop_dictionary_t pkg_repod)
if (pkg_fd == -1) { if (pkg_fd == -1) {
rv = archive_errno(ar); rv = archive_errno(ar);
xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL,
rv, pkgname, version, rv, pkgver,
"%s: [unpack] failed to open binary package `%s': %s", "%s: [unpack] failed to open binary package `%s': %s",
pkgver, bpkg, strerror(rv)); pkgver, bpkg, strerror(rv));
free(bpkg); free(bpkg);
@ -631,14 +631,13 @@ xbps_unpack_binary_pkg(struct xbps_handle *xhp, prop_dictionary_t pkg_repod)
return rv; return rv;
} }
archive_read_open_fd(ar, pkg_fd, ARCHIVE_READ_BLOCKSIZE); archive_read_open_fd(ar, pkg_fd, ARCHIVE_READ_BLOCKSIZE);
free(bpkg);
/* /*
* Extract archive files. * Extract archive files.
*/ */
if ((rv = unpack_archive(xhp, pkg_repod, ar)) != 0) { if ((rv = unpack_archive(xhp, pkg_repod, pkgver, bpkg, ar)) != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL,
rv, pkgname, version, rv, pkgver,
"%s: [unpack] failed to unpack files from archive: %s", "%s: [unpack] failed to unpack files from archive: %s",
pkgver, strerror(rv)); pkgver, strerror(rv));
goto out; goto out;
@ -646,10 +645,10 @@ xbps_unpack_binary_pkg(struct xbps_handle *xhp, prop_dictionary_t pkg_repod)
/* /*
* Set package state to unpacked. * Set package state to unpacked.
*/ */
if ((rv = xbps_set_pkg_state_installed(xhp, pkgname, version, if ((rv = xbps_set_pkg_state_installed(xhp, pkgver,
XBPS_PKG_STATE_UNPACKED)) != 0) { XBPS_PKG_STATE_UNPACKED)) != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL,
rv, pkgname, version, rv, pkgver,
"%s: [unpack] failed to set state to unpacked: %s", "%s: [unpack] failed to set state to unpacked: %s",
pkgver, strerror(rv)); pkgver, strerror(rv));
} }
@ -657,6 +656,8 @@ out:
close(pkg_fd); close(pkg_fd);
if (ar) if (ar)
archive_read_free(ar); archive_read_free(ar);
if (bpkg)
free(bpkg);
return rv; return rv;
} }

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2012 Juan Romero Pardines. * Copyright (c) 2012-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -79,7 +79,7 @@ xbps_pkgdb_init(struct xbps_handle *xhp)
int int
xbps_pkgdb_update(struct xbps_handle *xhp, bool flush) xbps_pkgdb_update(struct xbps_handle *xhp, bool flush)
{ {
prop_array_t pkgdb_storage; prop_dictionary_t pkgdb_storage;
char *plist; char *plist;
static int cached_rv; static int cached_rv;
int rv = 0; int rv = 0;
@ -89,11 +89,11 @@ xbps_pkgdb_update(struct xbps_handle *xhp, bool flush)
plist = xbps_xasprintf("%s/%s", xhp->metadir, XBPS_PKGDB); plist = xbps_xasprintf("%s/%s", xhp->metadir, XBPS_PKGDB);
if (xhp->pkgdb && flush) { if (xhp->pkgdb && flush) {
pkgdb_storage = prop_array_internalize_from_zfile(plist); pkgdb_storage = prop_dictionary_internalize_from_file(plist);
if (pkgdb_storage == NULL || if (pkgdb_storage == NULL ||
!prop_array_equals(xhp->pkgdb, pkgdb_storage)) { !prop_dictionary_equals(xhp->pkgdb, pkgdb_storage)) {
/* flush dictionary to storage */ /* flush dictionary to storage */
if (!prop_array_externalize_to_file(xhp->pkgdb, plist)) { if (!prop_dictionary_externalize_to_file(xhp->pkgdb, plist)) {
free(plist); free(plist);
return errno; return errno;
} }
@ -106,9 +106,9 @@ xbps_pkgdb_update(struct xbps_handle *xhp, bool flush)
cached_rv = 0; cached_rv = 0;
} }
/* update copy in memory */ /* update copy in memory */
if ((xhp->pkgdb = prop_array_internalize_from_zfile(plist)) == NULL) { if ((xhp->pkgdb = prop_dictionary_internalize_from_file(plist)) == NULL) {
if (errno == ENOENT) if (errno == ENOENT)
xhp->pkgdb = prop_array_create(); xhp->pkgdb = prop_dictionary_create();
else else
xbps_error_printf("cannot access to pkgdb: %s\n", strerror(errno)); xbps_error_printf("cannot access to pkgdb: %s\n", strerror(errno));
@ -135,31 +135,33 @@ xbps_pkgdb_release(struct xbps_handle *xhp)
xbps_dbg_printf(xhp, "[pkgdb] released ok.\n"); xbps_dbg_printf(xhp, "[pkgdb] released ok.\n");
} }
static int
foreach_pkg_cb(struct xbps_handle *xhp,
int (*fn)(struct xbps_handle *, prop_object_t, void *, bool *),
void *arg,
bool reverse)
{
int rv;
if ((rv = xbps_pkgdb_init(xhp)) != 0)
return rv;
if (reverse)
rv = xbps_callback_array_iter_reverse(xhp, xhp->pkgdb, fn, arg);
else
rv = xbps_callback_array_iter(xhp, xhp->pkgdb, fn, arg);
return rv;
}
int int
xbps_pkgdb_foreach_reverse_cb(struct xbps_handle *xhp, xbps_pkgdb_foreach_reverse_cb(struct xbps_handle *xhp,
int (*fn)(struct xbps_handle *, prop_object_t, void *, bool *), int (*fn)(struct xbps_handle *, prop_object_t, void *, bool *),
void *arg) void *arg)
{ {
return foreach_pkg_cb(xhp, fn, arg, true); prop_array_t allkeys;
prop_object_t obj;
prop_dictionary_t pkgd;
size_t i;
int rv;
bool done = false;
if ((rv = xbps_pkgdb_init(xhp)) != 0)
return rv;
allkeys = prop_dictionary_all_keys(xhp->pkgdb);
assert(allkeys);
for (i = prop_array_count(allkeys); i > 0; i--) {
obj = prop_array_get(allkeys, i);
pkgd = prop_dictionary_get_keysym(xhp->pkgdb, obj);
rv = (*fn)(xhp, pkgd, arg, &done);
if (rv != 0 || done)
break;
}
prop_object_release(allkeys);
return rv;
} }
int int
@ -167,7 +169,25 @@ xbps_pkgdb_foreach_cb(struct xbps_handle *xhp,
int (*fn)(struct xbps_handle *, prop_object_t, void *, bool *), int (*fn)(struct xbps_handle *, prop_object_t, void *, bool *),
void *arg) void *arg)
{ {
return foreach_pkg_cb(xhp, fn, arg, false); prop_object_t obj;
prop_object_iterator_t iter;
prop_dictionary_t pkgd;
int rv;
bool done = false;
if ((rv = xbps_pkgdb_init(xhp)) != 0)
return rv;
iter = prop_dictionary_iterator(xhp->pkgdb);
assert(iter);
while ((obj = prop_object_iterator_next(iter))) {
pkgd = prop_dictionary_get_keysym(xhp->pkgdb, obj);
rv = (*fn)(xhp, pkgd, arg, &done);
if (rv != 0 || done)
break;
}
prop_object_iterator_release(iter);
return rv;
} }
prop_dictionary_t prop_dictionary_t
@ -176,7 +196,7 @@ xbps_pkgdb_get_pkg(struct xbps_handle *xhp, const char *pkg)
if (xbps_pkgdb_init(xhp) != 0) if (xbps_pkgdb_init(xhp) != 0)
return NULL; return NULL;
return xbps_find_pkg_in_array(xhp->pkgdb, pkg); return xbps_find_pkg_in_dict(xhp->pkgdb, pkg);
} }
prop_dictionary_t prop_dictionary_t
@ -185,28 +205,32 @@ xbps_pkgdb_get_virtualpkg(struct xbps_handle *xhp, const char *vpkg)
if (xbps_pkgdb_init(xhp) != 0) if (xbps_pkgdb_init(xhp) != 0)
return NULL; return NULL;
return xbps_find_virtualpkg_in_array(xhp, xhp->pkgdb, vpkg); return xbps_find_virtualpkg_in_dict(xhp, xhp->pkgdb, vpkg);
} }
static prop_dictionary_t static prop_dictionary_t
get_pkg_metadata(struct xbps_handle *xhp, prop_dictionary_t pkgd) get_pkg_metadata(struct xbps_handle *xhp, prop_dictionary_t pkgd)
{ {
prop_dictionary_t pkg_metad; prop_dictionary_t pkg_metad;
const char *pkgname; const char *pkgver;
char *plist; char *pkgname, *plist;
prop_dictionary_get_cstring_nocopy(pkgd, "pkgname", &pkgname); prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
pkgname = xbps_pkg_name(pkgver);
assert(pkgname);
if ((pkg_metad = prop_dictionary_get(xhp->pkg_metad, pkgname)) != NULL) if ((pkg_metad = prop_dictionary_get(xhp->pkg_metad, pkgname)) != NULL) {
free(pkgname);
return pkg_metad; return pkg_metad;
}
plist = xbps_xasprintf("%s/.%s.plist", xhp->metadir, pkgname); plist = xbps_xasprintf("%s/.%s.plist", xhp->metadir, pkgname);
pkg_metad = prop_dictionary_internalize_from_zfile(plist); pkg_metad = prop_dictionary_internalize_from_file(plist);
free(plist); free(plist);
if (pkg_metad == NULL) { if (pkg_metad == NULL) {
xbps_dbg_printf(xhp, "[pkgdb] cannot read %s metadata: %s\n", xbps_dbg_printf(xhp, "[pkgdb] cannot read %s metadata: %s\n",
pkgname, strerror(errno)); pkgver, strerror(errno));
free(pkgname);
return NULL; return NULL;
} }
@ -215,6 +239,7 @@ get_pkg_metadata(struct xbps_handle *xhp, prop_dictionary_t pkgd)
prop_dictionary_set(xhp->pkg_metad, pkgname, pkg_metad); prop_dictionary_set(xhp->pkg_metad, pkgname, pkg_metad);
prop_object_release(pkg_metad); prop_object_release(pkg_metad);
free(pkgname);
return pkg_metad; return pkg_metad;
} }
@ -223,7 +248,7 @@ static void
generate_full_revdeps_tree(struct xbps_handle *xhp) generate_full_revdeps_tree(struct xbps_handle *xhp)
{ {
prop_array_t rundeps, pkg; prop_array_t rundeps, pkg;
prop_dictionary_t pkgmetad; prop_dictionary_t pkgmetad, pkgd;
prop_object_t obj; prop_object_t obj;
prop_object_iterator_t iter; prop_object_iterator_t iter;
const char *pkgver, *pkgdep, *vpkgname; const char *pkgver, *pkgdep, *vpkgname;
@ -236,17 +261,18 @@ generate_full_revdeps_tree(struct xbps_handle *xhp)
xhp->pkgdb_revdeps = prop_dictionary_create(); xhp->pkgdb_revdeps = prop_dictionary_create();
iter = prop_array_iterator(xhp->pkgdb); iter = prop_dictionary_iterator(xhp->pkgdb);
assert(iter); assert(iter);
while ((obj = prop_object_iterator_next(iter))) { while ((obj = prop_object_iterator_next(iter))) {
pkgd = prop_dictionary_get_keysym(xhp->pkgdb, obj);
/* /*
* If run_depends is in pkgdb use it, otherwise fallback to * If run_depends is in pkgdb use it, otherwise fallback to
* the slower pkg metadata method. * the slower pkg metadata method.
*/ */
rundeps = prop_dictionary_get(obj, "run_depends"); rundeps = prop_dictionary_get(pkgd, "run_depends");
if (rundeps == NULL) { if (rundeps == NULL) {
pkgmetad = get_pkg_metadata(xhp, obj); pkgmetad = get_pkg_metadata(xhp, pkgd);
assert(pkgmetad); assert(pkgmetad);
rundeps = prop_dictionary_get(pkgmetad, "run_depends"); rundeps = prop_dictionary_get(pkgmetad, "run_depends");
} }
@ -269,7 +295,7 @@ generate_full_revdeps_tree(struct xbps_handle *xhp)
alloc = true; alloc = true;
pkg = prop_array_create(); pkg = prop_array_create();
} }
prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver); prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
prop_array_add_cstring_nocopy(pkg, pkgver); prop_array_add_cstring_nocopy(pkg, pkgver);
prop_dictionary_set(xhp->pkgdb_revdeps, vpkgname, pkg); prop_dictionary_set(xhp->pkgdb_revdeps, vpkgname, pkg);
free(curpkgname); free(curpkgname);
@ -283,16 +309,21 @@ generate_full_revdeps_tree(struct xbps_handle *xhp)
prop_array_t prop_array_t
xbps_pkgdb_get_pkg_revdeps(struct xbps_handle *xhp, const char *pkg) xbps_pkgdb_get_pkg_revdeps(struct xbps_handle *xhp, const char *pkg)
{ {
prop_array_t res;
prop_dictionary_t pkgd; prop_dictionary_t pkgd;
const char *pkgname; const char *pkgver;
char *pkgname;
if ((pkgd = xbps_pkgdb_get_pkg(xhp, pkg)) == NULL) if ((pkgd = xbps_pkgdb_get_pkg(xhp, pkg)) == NULL)
return NULL; return NULL;
generate_full_revdeps_tree(xhp); generate_full_revdeps_tree(xhp);
prop_dictionary_get_cstring_nocopy(pkgd, "pkgname", &pkgname); prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
pkgname = xbps_pkg_name(pkgver);
res = prop_dictionary_get(xhp->pkgdb_revdeps, pkgname);
free(pkgname);
return prop_dictionary_get(xhp->pkgdb_revdeps, pkgname); return res;
} }
prop_dictionary_t prop_dictionary_t
@ -306,52 +337,3 @@ xbps_pkgdb_get_pkg_metadata(struct xbps_handle *xhp, const char *pkg)
return get_pkg_metadata(xhp, pkgd); return get_pkg_metadata(xhp, pkgd);
} }
bool
xbps_pkgdb_remove_pkg(struct xbps_handle *xhp, const char *pkg, bool flush)
{
bool rv = false;
if (xbps_pkgdb_init(xhp) != 0)
return false;
if (xbps_pkgpattern_version(pkg))
rv = xbps_remove_pkg_from_array_by_pattern(xhp->pkgdb, pkg);
else if (xbps_pkg_version(pkg))
rv = xbps_remove_pkg_from_array_by_pkgver(xhp->pkgdb, pkg);
else
rv = xbps_remove_pkg_from_array_by_name(xhp->pkgdb, pkg);
if (!flush || !rv)
return rv;
if ((xbps_pkgdb_update(xhp, true)) != 0)
return false;
return true;
}
bool
xbps_pkgdb_replace_pkg(struct xbps_handle *xhp,
prop_dictionary_t pkgd,
const char *pkg,
bool flush)
{
int rv;
if (xbps_pkgdb_init(xhp) != 0)
return false;
if (xbps_pkgpattern_version(pkg))
rv = xbps_array_replace_dict_by_pattern(xhp->pkgdb, pkgd, pkg);
else
rv = xbps_array_replace_dict_by_name(xhp->pkgdb, pkgd, pkg);
if (!flush)
return rv != 0 ? false : true;
if ((xbps_pkgdb_update(xhp, true)) != 0)
return false;
return true;
}

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2008-2012 Juan Romero Pardines. * Copyright (c) 2008-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -121,7 +121,7 @@ xbps_callback_array_iter_in_dict(struct xbps_handle *xhp,
array = prop_dictionary_get(dict, key); array = prop_dictionary_get(dict, key);
if (prop_object_type(array) != PROP_TYPE_ARRAY) if (prop_object_type(array) != PROP_TYPE_ARRAY)
return EINVAL; return ENOENT;
for (i = 0; i < prop_array_count(array); i++) { for (i = 0; i < prop_array_count(array); i++) {
obj = prop_array_get(array, i); obj = prop_array_get(array, i);
@ -213,7 +213,8 @@ array_replace_dict(prop_array_t array,
{ {
prop_object_t obj; prop_object_t obj;
size_t i; size_t i;
const char *curpkgname; const char *curpkgver;
char *curpkgname;
assert(prop_object_type(array) == PROP_TYPE_ARRAY); assert(prop_object_type(array) == PROP_TYPE_ARRAY);
assert(prop_object_type(dict) == PROP_TYPE_DICTIONARY); assert(prop_object_type(dict) == PROP_TYPE_DICTIONARY);
@ -226,8 +227,8 @@ array_replace_dict(prop_array_t array,
if (bypattern) { if (bypattern) {
/* pkgpattern match */ /* pkgpattern match */
prop_dictionary_get_cstring_nocopy(obj, prop_dictionary_get_cstring_nocopy(obj,
"pkgver", &curpkgname); "pkgver", &curpkgver);
if (xbps_pkgpattern_match(curpkgname, str)) { if (xbps_pkgpattern_match(curpkgver, str)) {
if (!prop_array_set(array, i, dict)) if (!prop_array_set(array, i, dict))
return EINVAL; return EINVAL;
@ -236,13 +237,18 @@ array_replace_dict(prop_array_t array,
} else { } else {
/* pkgname match */ /* pkgname match */
prop_dictionary_get_cstring_nocopy(obj, prop_dictionary_get_cstring_nocopy(obj,
"pkgname", &curpkgname); "pkgver", &curpkgver);
curpkgname = xbps_pkg_name(curpkgver);
assert(curpkgname);
if (strcmp(curpkgname, str) == 0) { if (strcmp(curpkgname, str) == 0) {
if (!prop_array_set(array, i, dict)) if (!prop_array_set(array, i, dict)) {
free(curpkgname);
return EINVAL; return EINVAL;
}
free(curpkgname);
return 0; return 0;
} }
free(curpkgname);
} }
} }
/* no match */ /* no match */
@ -252,9 +258,9 @@ array_replace_dict(prop_array_t array,
int HIDDEN int HIDDEN
xbps_array_replace_dict_by_name(prop_array_t array, xbps_array_replace_dict_by_name(prop_array_t array,
prop_dictionary_t dict, prop_dictionary_t dict,
const char *pkgname) const char *pkgver)
{ {
return array_replace_dict(array, dict, pkgname, false); return array_replace_dict(array, dict, pkgver, false);
} }
int HIDDEN int HIDDEN

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2009-2012 Juan Romero Pardines. * Copyright (c) 2009-2013 Juan Romero Pardines.
* Copyright (c) 2008, 2009 Joerg Sonnenberger <joerg (at) NetBSD.org> * Copyright (c) 2008, 2009 Joerg Sonnenberger <joerg (at) NetBSD.org>
* All rights reserved. * All rights reserved.
* *
@ -190,7 +190,6 @@ xbps_get_pkg_plist_from_binpkg(const char *fname, const char *plistf)
break; break;
} }
archive_read_close(a);
archive_read_free(a); archive_read_free(a);
return plistd; return plistd;

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2008-2012 Juan Romero Pardines. * Copyright (c) 2008-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -36,7 +36,8 @@ get_pkg_in_array(prop_array_t array, const char *str, bool virtual)
{ {
prop_object_t obj = NULL; prop_object_t obj = NULL;
prop_object_iterator_t iter; prop_object_iterator_t iter;
const char *pkgver, *dpkgn; const char *pkgver;
char *dpkgn;
bool found = false; bool found = false;
iter = prop_array_iterator(array); iter = prop_array_iterator(array);
@ -76,12 +77,16 @@ get_pkg_in_array(prop_array_t array, const char *str, bool virtual)
} else { } else {
/* match by pkgname */ /* match by pkgname */
if (!prop_dictionary_get_cstring_nocopy(obj, if (!prop_dictionary_get_cstring_nocopy(obj,
"pkgname", &dpkgn)) "pkgver", &pkgver))
continue; continue;
dpkgn = xbps_pkg_name(pkgver);
assert(dpkgn);
if (strcmp(dpkgn, str) == 0) { if (strcmp(dpkgn, str) == 0) {
free(dpkgn);
found = true; found = true;
break; break;
} }
free(dpkgn);
} }
} }
prop_object_iterator_release(iter); prop_object_iterator_release(iter);
@ -121,3 +126,171 @@ xbps_find_virtualpkg_in_array(struct xbps_handle *x,
return get_pkg_in_array(a, s, true); return get_pkg_in_array(a, s, true);
} }
static prop_dictionary_t
match_pkg_by_pkgver(prop_dictionary_t repod, const char *p)
{
prop_dictionary_t d = NULL;
const char *pkgver;
char *pkgname;
/* exact match by pkgver */
if ((pkgname = xbps_pkg_name(p)) == NULL)
return NULL;
d = prop_dictionary_get(repod, pkgname);
if (d) {
prop_dictionary_get_cstring_nocopy(d, "pkgver", &pkgver);
if (strcmp(pkgver, p))
d = NULL;
}
free(pkgname);
return d;
}
static prop_dictionary_t
match_pkg_by_pattern(prop_dictionary_t repod, const char *p)
{
prop_dictionary_t d = NULL;
const char *pkgver;
char *pkgname;
/* match by pkgpattern in pkgver */
if ((pkgname = xbps_pkgpattern_name(p)) == NULL) {
if ((pkgname = xbps_pkg_name(p)))
return match_pkg_by_pkgver(repod, p);
return NULL;
}
d = prop_dictionary_get(repod, pkgname);
if (d) {
prop_dictionary_get_cstring_nocopy(d, "pkgver", &pkgver);
assert(pkgver);
if (!xbps_pkgpattern_match(pkgver, p))
d = NULL;
}
free(pkgname);
return d;
}
const char HIDDEN *
vpkg_user_conf(struct xbps_handle *xhp,
const char *vpkg,
bool bypattern)
{
const char *vpkgver, *pkg = NULL;
char *vpkgname = NULL, *tmp;
size_t i, j, cnt;
if (xhp->cfg == NULL)
return NULL;
if ((cnt = cfg_size(xhp->cfg, "virtual-package")) == 0) {
/* no virtual packages configured */
return NULL;
}
for (i = 0; i < cnt; i++) {
cfg_t *sec = cfg_getnsec(xhp->cfg, "virtual-package", i);
for (j = 0; j < cfg_size(sec, "targets"); j++) {
tmp = NULL;
vpkgver = cfg_getnstr(sec, "targets", j);
if (strchr(vpkgver, '_') == NULL) {
tmp = xbps_xasprintf("%s_1", vpkgver);
vpkgname = xbps_pkg_name(tmp);
free(tmp);
} else {
vpkgname = xbps_pkg_name(vpkgver);
}
if (vpkgname == NULL)
break;
if (bypattern) {
if (!xbps_pkgpattern_match(vpkgver, vpkg)) {
free(vpkgname);
continue;
}
} else {
if (strcmp(vpkg, vpkgname)) {
free(vpkgname);
continue;
}
}
/* virtual package matched in conffile */
pkg = cfg_title(sec);
xbps_dbg_printf(xhp,
"matched vpkg in conf `%s' for %s\n",
pkg, vpkg);
free(vpkgname);
break;
}
}
return pkg;
}
prop_dictionary_t
xbps_find_virtualpkg_in_dict(struct xbps_handle *xhp,
prop_dictionary_t d,
const char *pkg)
{
prop_object_t obj;
prop_object_iterator_t iter;
prop_dictionary_t pkgd = NULL;
const char *vpkg;
bool found = false, bypattern = false;
if (xbps_pkgpattern_version(pkg))
bypattern = true;
/* Try matching vpkg from configuration files */
vpkg = vpkg_user_conf(xhp, pkg, bypattern);
if (vpkg != NULL) {
if (xbps_pkgpattern_version(vpkg))
pkgd = match_pkg_by_pattern(d, vpkg);
else if (xbps_pkg_version(vpkg))
pkgd = match_pkg_by_pkgver(d, vpkg);
else
pkgd = prop_dictionary_get(d, vpkg);
if (pkgd) {
found = true;
goto out;
}
}
/* ... otherwise match the first one in dictionary */
iter = prop_dictionary_iterator(d);
assert(iter);
while ((obj = prop_object_iterator_next(iter))) {
pkgd = prop_dictionary_get_keysym(d, obj);
if (xbps_match_virtual_pkg_in_dict(pkgd, pkg, bypattern)) {
found = true;
break;
}
}
prop_object_iterator_release(iter);
out:
if (found)
return pkgd;
return NULL;
}
prop_dictionary_t
xbps_find_pkg_in_dict(prop_dictionary_t d, const char *pkg)
{
prop_dictionary_t pkgd = NULL;
if (xbps_pkgpattern_version(pkg))
pkgd = match_pkg_by_pattern(d, pkg);
else if (xbps_pkg_version(pkg))
pkgd = match_pkg_by_pkgver(d, pkg);
else
pkgd = prop_dictionary_get(d, pkg);
return pkgd;
}

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2012 Juan Romero Pardines. * Copyright (c) 2012-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -36,152 +36,13 @@
* @brief Repository index functions * @brief Repository index functions
* @defgroup rindex Repository index functions * @defgroup rindex Repository index functions
*/ */
static prop_dictionary_t
match_pkg_by_pkgver(prop_dictionary_t repod, const char *p)
{
prop_dictionary_t d = NULL;
const char *pkgver;
char *pkgname;
/* exact match by pkgver */
if ((pkgname = xbps_pkg_name(p)) == NULL)
return NULL;
d = prop_dictionary_get(repod, pkgname);
if (d) {
prop_dictionary_get_cstring_nocopy(d, "pkgver", &pkgver);
if (strcmp(pkgver, p))
d = NULL;
}
free(pkgname);
return d;
}
static prop_dictionary_t
match_pkg_by_pattern(prop_dictionary_t repod, const char *p)
{
prop_dictionary_t d = NULL;
const char *pkgver;
char *pkgname;
/* match by pkgpattern in pkgver */
if ((pkgname = xbps_pkgpattern_name(p)) == NULL) {
if ((pkgname = xbps_pkg_name(p)))
return match_pkg_by_pkgver(repod, p);
return NULL;
}
d = prop_dictionary_get(repod, pkgname);
if (d) {
prop_dictionary_get_cstring_nocopy(d, "pkgver", &pkgver);
assert(pkgver);
if (!xbps_pkgpattern_match(pkgver, p))
d = NULL;
}
free(pkgname);
return d;
}
const char HIDDEN *
vpkg_user_conf(struct xbps_handle *xhp,
const char *vpkg,
bool bypattern)
{
const char *vpkgver, *pkg = NULL;
char *vpkgname = NULL, *tmp;
size_t i, j, cnt;
if (xhp->cfg == NULL)
return NULL;
if ((cnt = cfg_size(xhp->cfg, "virtual-package")) == 0) {
/* no virtual packages configured */
return NULL;
}
for (i = 0; i < cnt; i++) {
cfg_t *sec = cfg_getnsec(xhp->cfg, "virtual-package", i);
for (j = 0; j < cfg_size(sec, "targets"); j++) {
tmp = NULL;
vpkgver = cfg_getnstr(sec, "targets", j);
if (strchr(vpkgver, '_') == NULL) {
tmp = xbps_xasprintf("%s_1", vpkgver);
vpkgname = xbps_pkg_name(tmp);
free(tmp);
} else {
vpkgname = xbps_pkg_name(vpkgver);
}
if (vpkgname == NULL)
break;
if (bypattern) {
if (!xbps_pkgpattern_match(vpkgver, vpkg)) {
free(vpkgname);
continue;
}
} else {
if (strcmp(vpkg, vpkgname)) {
free(vpkgname);
continue;
}
}
/* virtual package matched in conffile */
pkg = cfg_title(sec);
xbps_dbg_printf(xhp,
"matched vpkg in conf `%s' for %s\n",
pkg, vpkg);
free(vpkgname);
break;
}
}
return pkg;
}
prop_dictionary_t prop_dictionary_t
xbps_rindex_get_virtualpkg(struct xbps_rindex *rpi, const char *pkg) xbps_rindex_get_virtualpkg(struct xbps_rindex *rpi, const char *pkg)
{ {
prop_object_t obj; prop_dictionary_t pkgd;
prop_object_iterator_t iter;
prop_dictionary_t pkgd = NULL;
const char *vpkg;
bool found = false, bypattern = false;
if (xbps_pkgpattern_version(pkg)) pkgd = xbps_find_virtualpkg_in_dict(rpi->xhp, rpi->repod, pkg);
bypattern = true; if (pkgd) {
/* Try matching vpkg from configuration files */
vpkg = vpkg_user_conf(rpi->xhp, pkg, bypattern);
if (vpkg != NULL) {
if (xbps_pkgpattern_version(vpkg))
pkgd = match_pkg_by_pattern(rpi->repod, vpkg);
else if (xbps_pkg_version(vpkg))
pkgd = match_pkg_by_pkgver(rpi->repod, vpkg);
else
pkgd = prop_dictionary_get(rpi->repod, vpkg);
if (pkgd) {
found = true;
goto out;
}
}
/* ... otherwise match the first one in dictionary */
iter = prop_dictionary_iterator(rpi->repod);
assert(iter);
while ((obj = prop_object_iterator_next(iter))) {
pkgd = prop_dictionary_get_keysym(rpi->repod, obj);
if (xbps_match_virtual_pkg_in_dict(pkgd, pkg, bypattern)) {
found = true;
break;
}
}
prop_object_iterator_release(iter);
out:
if (found) {
prop_dictionary_set_cstring_nocopy(pkgd, prop_dictionary_set_cstring_nocopy(pkgd,
"repository", rpi->uri); "repository", rpi->uri);
return pkgd; return pkgd;
@ -192,15 +53,9 @@ out:
prop_dictionary_t prop_dictionary_t
xbps_rindex_get_pkg(struct xbps_rindex *rpi, const char *pkg) xbps_rindex_get_pkg(struct xbps_rindex *rpi, const char *pkg)
{ {
prop_dictionary_t pkgd = NULL; prop_dictionary_t pkgd;
if (xbps_pkgpattern_version(pkg))
pkgd = match_pkg_by_pattern(rpi->repod, pkg);
else if (xbps_pkg_version(pkg))
pkgd = match_pkg_by_pkgver(rpi->repod, pkg);
else
pkgd = prop_dictionary_get(rpi->repod, pkg);
pkgd = xbps_find_pkg_in_dict(rpi->repod, pkg);
if (pkgd) { if (pkgd) {
prop_dictionary_set_cstring_nocopy(pkgd, prop_dictionary_set_cstring_nocopy(pkgd,
"repository", rpi->uri); "repository", rpi->uri);

View File

@ -158,8 +158,8 @@ find_repo_deps(struct xbps_handle *xhp,
prop_array_t curpkgrdeps; prop_array_t curpkgrdeps;
pkg_state_t state; pkg_state_t state;
size_t x; size_t x;
const char *reqpkg, *reqpkgname, *pkgver_q, *reason = NULL; const char *reqpkg, *pkgver_q, *reason = NULL;
char *pkgname; char *pkgname, *reqpkgname;
int rv = 0; int rv = 0;
if (*depth >= MAX_DEPTH) if (*depth >= MAX_DEPTH)
@ -317,8 +317,8 @@ find_repo_deps(struct xbps_handle *xhp,
} }
prop_dictionary_get_cstring_nocopy(curpkgd, prop_dictionary_get_cstring_nocopy(curpkgd,
"pkgver", &pkgver_q); "pkgver", &pkgver_q);
prop_dictionary_get_cstring_nocopy(curpkgd, reqpkgname = xbps_pkg_name(pkgver_q);
"pkgname", &reqpkgname); assert(reqpkgname);
/* /*
* Check dependency validity. * Check dependency validity.
*/ */
@ -329,9 +329,11 @@ find_repo_deps(struct xbps_handle *xhp,
"%s (depends on itself)]\n", "%s (depends on itself)]\n",
reqpkg); reqpkg);
free(pkgname); free(pkgname);
free(reqpkgname);
continue; continue;
} }
free(pkgname); free(pkgname);
free(reqpkgname);
/* /*
* Check if package has matched conflicts. * Check if package has matched conflicts.

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2009-2012 Juan Romero Pardines. * Copyright (c) 2009-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2009-2012 Juan Romero Pardines. * Copyright (c) 2009-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -193,6 +193,7 @@ xbps_rpool_get_pkg_plist(struct xbps_handle *xhp,
const char *plistf) const char *plistf)
{ {
prop_dictionary_t pkgd = NULL, plistd = NULL; prop_dictionary_t pkgd = NULL, plistd = NULL;
const char *repo;
char *url; char *url;
assert(pkg != NULL); assert(pkg != NULL);
@ -206,8 +207,8 @@ xbps_rpool_get_pkg_plist(struct xbps_handle *xhp,
* This will work locally and remotely, thanks to libarchive and * This will work locally and remotely, thanks to libarchive and
* libfetch! * libfetch!
*/ */
pkgd = xbps_rpool_get_pkg(xhp, pkg); if (((pkgd = xbps_rpool_get_pkg(xhp, pkg)) == NULL) &&
if (pkgd == NULL) ((pkgd = xbps_rpool_get_virtualpkg(xhp, pkg)) == NULL))
goto out; goto out;
url = xbps_repository_pkg_path(xhp, pkgd); url = xbps_repository_pkg_path(xhp, pkgd);
@ -216,6 +217,10 @@ xbps_rpool_get_pkg_plist(struct xbps_handle *xhp,
goto out; goto out;
} }
plistd = xbps_get_pkg_plist_from_binpkg(url, plistf); plistd = xbps_get_pkg_plist_from_binpkg(url, plistf);
if (plistd) {
prop_dictionary_get_cstring_nocopy(pkgd, "repository", &repo);
prop_dictionary_set_cstring_nocopy(plistd, "repository", repo);
}
free(url); free(url);
out: out:

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2009-2012 Juan Romero Pardines. * Copyright (c) 2009-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -60,9 +60,8 @@ static int
check_binpkgs_hash(struct xbps_handle *xhp, prop_object_iterator_t iter) check_binpkgs_hash(struct xbps_handle *xhp, prop_object_iterator_t iter)
{ {
prop_object_t obj; prop_object_t obj;
const char *pkgver, *repoloc, *filen, *sha256, *trans; const char *pkgver, *arch, *repoloc, *sha256, *trans;
const char *pkgname, *version; char *binfile, *filen;
char *binfile;
int rv = 0; int rv = 0;
while ((obj = prop_object_iterator_next(iter)) != NULL) { while ((obj = prop_object_iterator_next(iter)) != NULL) {
@ -71,11 +70,9 @@ check_binpkgs_hash(struct xbps_handle *xhp, prop_object_iterator_t iter)
(strcmp(trans, "configure") == 0)) (strcmp(trans, "configure") == 0))
continue; continue;
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); prop_dictionary_get_cstring_nocopy(obj, "architecture", &arch);
prop_dictionary_get_cstring_nocopy(obj, "version", &version);
prop_dictionary_get_cstring_nocopy(obj, "repository", &repoloc); prop_dictionary_get_cstring_nocopy(obj, "repository", &repoloc);
prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver); prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
prop_dictionary_get_cstring_nocopy(obj, "filename", &filen);
prop_dictionary_get_cstring_nocopy(obj, prop_dictionary_get_cstring_nocopy(obj,
"filename-sha256", &sha256); "filename-sha256", &sha256);
@ -84,18 +81,22 @@ check_binpkgs_hash(struct xbps_handle *xhp, prop_object_iterator_t iter)
rv = EINVAL; rv = EINVAL;
break; break;
} }
xbps_set_cb_state(xhp, XBPS_STATE_VERIFY, 0, pkgver, filen, filen = xbps_xasprintf("%s.%s.xbps", pkgver, arch);
xbps_set_cb_state(xhp, XBPS_STATE_VERIFY, 0, pkgver,
"Verifying `%s' package integrity...", filen, repoloc); "Verifying `%s' package integrity...", filen, repoloc);
rv = xbps_file_hash_check(binfile, sha256); rv = xbps_file_hash_check(binfile, sha256);
if (rv != 0) { if (rv != 0) {
free(binfile); free(binfile);
free(filen);
xbps_set_cb_state(xhp, XBPS_STATE_VERIFY_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_VERIFY_FAIL,
rv, pkgname, version, rv, pkgver,
"Failed to verify `%s' package integrity: %s", "Failed to verify `%s' package integrity: %s",
filen, strerror(rv)); filen, strerror(rv));
break; break;
} }
free(binfile); free(binfile);
free(filen);
} }
prop_object_iterator_reset(iter); prop_object_iterator_reset(iter);
@ -106,9 +107,8 @@ static int
download_binpkgs(struct xbps_handle *xhp, prop_object_iterator_t iter) download_binpkgs(struct xbps_handle *xhp, prop_object_iterator_t iter)
{ {
prop_object_t obj; prop_object_t obj;
const char *pkgver, *repoloc, *filen, *trans; const char *pkgver, *arch, *fetchstr, *repoloc, *trans;
const char *pkgname, *version, *fetchstr; char *binfile, *filen;
char *binfile;
int rv = 0; int rv = 0;
bool state_dload = false; bool state_dload = false;
@ -118,11 +118,9 @@ download_binpkgs(struct xbps_handle *xhp, prop_object_iterator_t iter)
(strcmp(trans, "configure") == 0)) (strcmp(trans, "configure") == 0))
continue; continue;
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); prop_dictionary_get_cstring_nocopy(obj, "architecture", &arch);
prop_dictionary_get_cstring_nocopy(obj, "version", &version);
prop_dictionary_get_cstring_nocopy(obj, "repository", &repoloc); prop_dictionary_get_cstring_nocopy(obj, "repository", &repoloc);
prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver); prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
prop_dictionary_get_cstring_nocopy(obj, "filename", &filen);
binfile = xbps_repository_pkg_path(xhp, obj); binfile = xbps_repository_pkg_path(xhp, obj);
if (binfile == NULL) { if (binfile == NULL) {
@ -142,7 +140,7 @@ download_binpkgs(struct xbps_handle *xhp, prop_object_iterator_t iter)
if (access(xhp->cachedir, R_OK|X_OK|W_OK) == -1) { if (access(xhp->cachedir, R_OK|X_OK|W_OK) == -1) {
if (xbps_mkpath(xhp->cachedir, 0755) == -1) { if (xbps_mkpath(xhp->cachedir, 0755) == -1) {
xbps_set_cb_state(xhp, XBPS_STATE_DOWNLOAD_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_DOWNLOAD_FAIL,
errno, pkgname, version, errno, pkgver,
"%s: [trans] cannot create cachedir `%s':" "%s: [trans] cannot create cachedir `%s':"
"%s", pkgver, xhp->cachedir, "%s", pkgver, xhp->cachedir,
strerror(errno)); strerror(errno));
@ -153,24 +151,25 @@ download_binpkgs(struct xbps_handle *xhp, prop_object_iterator_t iter)
} }
if (state_dload == false) { if (state_dload == false) {
xbps_set_cb_state(xhp, XBPS_STATE_TRANS_DOWNLOAD, xbps_set_cb_state(xhp, XBPS_STATE_TRANS_DOWNLOAD,
0, NULL, NULL, NULL); 0, NULL, NULL);
state_dload = true; state_dload = true;
} }
filen = xbps_xasprintf("%s.%s.xbps", pkgver, arch);
xbps_set_cb_state(xhp, XBPS_STATE_DOWNLOAD, xbps_set_cb_state(xhp, XBPS_STATE_DOWNLOAD,
0, pkgname, version, 0, pkgver, "Downloading binary package `%s' (from `%s')...",
"Downloading binary package `%s' (from `%s')...",
filen, repoloc); filen, repoloc);
/* /*
* Fetch binary package. * Fetch binary package.
*/ */
if (chdir(xhp->cachedir) == -1) { if (chdir(xhp->cachedir) == -1) {
xbps_set_cb_state(xhp, XBPS_STATE_DOWNLOAD_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_DOWNLOAD_FAIL,
errno, pkgname, version, errno, pkgver,
"%s: [trans] failed to change dir to cachedir" "%s: [trans] failed to change dir to cachedir"
"`%s': %s", pkgver, xhp->cachedir, "`%s': %s", pkgver, xhp->cachedir,
strerror(errno)); strerror(errno));
rv = errno; rv = errno;
free(binfile); free(binfile);
free(filen);
break; break;
} }
@ -179,15 +178,16 @@ download_binpkgs(struct xbps_handle *xhp, prop_object_iterator_t iter)
fetchstr = xbps_fetch_error_string(); fetchstr = xbps_fetch_error_string();
xbps_set_cb_state(xhp, XBPS_STATE_DOWNLOAD_FAIL, xbps_set_cb_state(xhp, XBPS_STATE_DOWNLOAD_FAIL,
fetchLastErrCode != 0 ? fetchLastErrCode : errno, fetchLastErrCode != 0 ? fetchLastErrCode : errno,
pkgname, version, pkgver, "%s: [trans] failed to download binary package "
"%s: [trans] failed to download binary package "
"`%s' from `%s': %s", pkgver, filen, repoloc, "`%s' from `%s': %s", pkgver, filen, repoloc,
fetchstr ? fetchstr : strerror(errno)); fetchstr ? fetchstr : strerror(errno));
free(binfile); free(binfile);
free(filen);
break; break;
} }
rv = 0; rv = 0;
free(binfile); free(binfile);
free(filen);
} }
prop_object_iterator_reset(iter); prop_object_iterator_reset(iter);
@ -199,7 +199,7 @@ xbps_transaction_commit(struct xbps_handle *xhp)
{ {
prop_object_t obj; prop_object_t obj;
prop_object_iterator_t iter; prop_object_iterator_t iter;
const char *pkgname, *version, *pkgver, *tract; const char *pkgver, *tract;
int rv = 0; int rv = 0;
bool update, install, sr; bool update, install, sr;
@ -217,20 +217,18 @@ xbps_transaction_commit(struct xbps_handle *xhp)
/* /*
* Check SHA256 hashes for binary packages in transaction. * Check SHA256 hashes for binary packages in transaction.
*/ */
xbps_set_cb_state(xhp, XBPS_STATE_TRANS_VERIFY, 0, NULL, NULL, NULL); xbps_set_cb_state(xhp, XBPS_STATE_TRANS_VERIFY, 0, NULL, NULL);
if ((rv = check_binpkgs_hash(xhp, iter)) != 0) if ((rv = check_binpkgs_hash(xhp, iter)) != 0)
goto out; goto out;
/* /*
* Install, update, configure or remove packages as specified * Install, update, configure or remove packages as specified
* in the transaction dictionary. * in the transaction dictionary.
*/ */
xbps_set_cb_state(xhp, XBPS_STATE_TRANS_RUN, 0, NULL, NULL, NULL); xbps_set_cb_state(xhp, XBPS_STATE_TRANS_RUN, 0, NULL, NULL);
while ((obj = prop_object_iterator_next(iter)) != NULL) { while ((obj = prop_object_iterator_next(iter)) != NULL) {
update = false; update = false;
prop_dictionary_get_cstring_nocopy(obj, "transaction", &tract); prop_dictionary_get_cstring_nocopy(obj, "transaction", &tract);
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname);
prop_dictionary_get_cstring_nocopy(obj, "version", &version);
prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver); prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
if (strcmp(tract, "remove") == 0) { if (strcmp(tract, "remove") == 0) {
@ -245,14 +243,14 @@ xbps_transaction_commit(struct xbps_handle *xhp)
rv = xbps_remove_pkg(xhp, pkgver, update, sr); rv = xbps_remove_pkg(xhp, pkgver, update, sr);
if (rv != 0) { if (rv != 0) {
xbps_dbg_printf(xhp, "[trans] failed to " xbps_dbg_printf(xhp, "[trans] failed to "
"remove %s-%s\n", pkgname, version); "remove %s\n", pkgver);
goto out; goto out;
} }
} else if (strcmp(tract, "configure") == 0) { } else if (strcmp(tract, "configure") == 0) {
/* /*
* Reconfigure pending package. * Reconfigure pending package.
*/ */
rv = xbps_configure_pkg(xhp, pkgname, false, false, false); rv = xbps_configure_pkg(xhp, pkgver, false, false, false);
if (rv != 0) if (rv != 0)
goto out; goto out;
} else { } else {
@ -264,27 +262,27 @@ xbps_transaction_commit(struct xbps_handle *xhp)
else else
install = true; install = true;
if (update && xbps_pkgdb_get_pkg(xhp, pkgname)) { if (update && xbps_pkgdb_get_pkg(xhp, pkgver)) {
/* /*
* Update a package: execute pre-remove * Update a package: execute pre-remove
* action if found before unpacking. * action if found before unpacking.
*/ */
xbps_set_cb_state(xhp, XBPS_STATE_UPDATE, 0, xbps_set_cb_state(xhp, XBPS_STATE_UPDATE, 0,
pkgname, version, NULL); pkgver, NULL);
rv = xbps_remove_pkg(xhp, pkgver, true, false); rv = xbps_remove_pkg(xhp, pkgver, true, false);
if (rv != 0) { if (rv != 0) {
xbps_set_cb_state(xhp, xbps_set_cb_state(xhp,
XBPS_STATE_UPDATE_FAIL, XBPS_STATE_UPDATE_FAIL,
rv, pkgname, version, rv, pkgver,
"%s: [trans] failed to update " "%s: [trans] failed to update "
"package to `%s': %s", pkgver, "package `%s'", pkgver,
version, strerror(rv)); strerror(rv));
goto out; goto out;
} }
} else { } else {
/* Install a package */ /* Install a package */
xbps_set_cb_state(xhp, XBPS_STATE_INSTALL, xbps_set_cb_state(xhp, XBPS_STATE_INSTALL,
0, pkgname, version, NULL); 0, pkgver, NULL);
} }
/* /*
* Unpack binary package. * Unpack binary package.
@ -294,7 +292,7 @@ xbps_transaction_commit(struct xbps_handle *xhp)
/* /*
* Register package. * Register package.
*/ */
if ((rv = xbps_register_pkg(xhp, obj, true)) != 0) if ((rv = xbps_register_pkg(xhp, obj)) != 0)
goto out; goto out;
} }
} }
@ -307,7 +305,7 @@ xbps_transaction_commit(struct xbps_handle *xhp)
/* /*
* Configure all unpacked packages. * Configure all unpacked packages.
*/ */
xbps_set_cb_state(xhp, XBPS_STATE_TRANS_CONFIGURE, 0, NULL, NULL, NULL); xbps_set_cb_state(xhp, XBPS_STATE_TRANS_CONFIGURE, 0, NULL, NULL);
while ((obj = prop_object_iterator_next(iter)) != NULL) { while ((obj = prop_object_iterator_next(iter)) != NULL) {
prop_dictionary_get_cstring_nocopy(obj, "transaction", &tract); prop_dictionary_get_cstring_nocopy(obj, "transaction", &tract);
@ -315,16 +313,15 @@ xbps_transaction_commit(struct xbps_handle *xhp)
(strcmp(tract, "configure") == 0)) (strcmp(tract, "configure") == 0))
continue; continue;
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
prop_dictionary_get_cstring_nocopy(obj, "version", &version);
update = false; update = false;
if (strcmp(tract, "update") == 0) if (strcmp(tract, "update") == 0)
update = true; update = true;
rv = xbps_configure_pkg(xhp, pkgname, false, update, true); rv = xbps_configure_pkg(xhp, pkgver, false, update, true);
if (rv != 0) { if (rv != 0) {
xbps_dbg_printf(xhp, "%s: configure failed for " xbps_dbg_printf(xhp, "%s: configure failed for "
"%s-%s: %s\n", pkgname, version, strerror(rv)); "%s: %s\n", pkgver, strerror(rv));
goto out; goto out;
} }
/* /*
@ -333,10 +330,10 @@ xbps_transaction_commit(struct xbps_handle *xhp)
*/ */
if (update) { if (update) {
xbps_set_cb_state(xhp, XBPS_STATE_UPDATE_DONE, 0, xbps_set_cb_state(xhp, XBPS_STATE_UPDATE_DONE, 0,
pkgname, version, NULL); pkgver, NULL);
} else { } else {
xbps_set_cb_state(xhp, XBPS_STATE_INSTALL_DONE, 0, xbps_set_cb_state(xhp, XBPS_STATE_INSTALL_DONE, 0,
pkgname, version, NULL); pkgver, NULL);
} }
} }

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2009-2012 Juan Romero Pardines. * Copyright (c) 2009-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -61,7 +61,7 @@ compute_transaction_stats(struct xbps_handle *xhp)
uint64_t tsize, dlsize, instsize, rmsize; uint64_t tsize, dlsize, instsize, rmsize;
uint32_t inst_pkgcnt, up_pkgcnt, cf_pkgcnt, rm_pkgcnt; uint32_t inst_pkgcnt, up_pkgcnt, cf_pkgcnt, rm_pkgcnt;
int rv = 0; int rv = 0;
const char *tract, *pkgname, *repo; const char *tract, *pkgver, *repo;
inst_pkgcnt = up_pkgcnt = cf_pkgcnt = rm_pkgcnt = 0; inst_pkgcnt = up_pkgcnt = cf_pkgcnt = rm_pkgcnt = 0;
tsize = dlsize = instsize = rmsize = 0; tsize = dlsize = instsize = rmsize = 0;
@ -75,7 +75,7 @@ compute_transaction_stats(struct xbps_handle *xhp)
* Count number of pkgs to be removed, configured, * Count number of pkgs to be removed, configured,
* installed and updated. * installed and updated.
*/ */
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
prop_dictionary_get_cstring_nocopy(obj, "transaction", &tract); prop_dictionary_get_cstring_nocopy(obj, "transaction", &tract);
prop_dictionary_get_cstring_nocopy(obj, "repository", &repo); prop_dictionary_get_cstring_nocopy(obj, "repository", &repo);
@ -97,7 +97,7 @@ compute_transaction_stats(struct xbps_handle *xhp)
*/ */
if ((strcmp(tract, "remove") == 0) || if ((strcmp(tract, "remove") == 0) ||
(strcmp(tract, "update") == 0)) { (strcmp(tract, "update") == 0)) {
pkg_metad = xbps_pkgdb_get_pkg_metadata(xhp, pkgname); pkg_metad = xbps_pkgdb_get_pkg_metadata(xhp, pkgver);
if (pkg_metad == NULL) if (pkg_metad == NULL)
continue; continue;
prop_dictionary_get_uint64(pkg_metad, prop_dictionary_get_uint64(pkg_metad,

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2009-2012 Juan Romero Pardines. * Copyright (c) 2009-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -60,9 +60,10 @@ enum {
static int static int
trans_find_pkg(struct xbps_handle *xhp, const char *pkg, int action) trans_find_pkg(struct xbps_handle *xhp, const char *pkg, int action)
{ {
prop_dictionary_t pkg_pkgdb, pkg_repod; prop_dictionary_t pkg_pkgdb = NULL, pkg_repod;
prop_array_t unsorted; prop_array_t unsorted;
const char *pkgname, *repoloc, *repover, *repopkgver, *instver, *reason; const char *repoloc, *repover, *repopkgver, *instpkgver, *reason;
char *pkgname;
int rv = 0; int rv = 0;
pkg_state_t state = 0; pkg_state_t state = 0;
@ -88,29 +89,35 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, int action)
return ENOENT; return ENOENT;
} }
} }
prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgname", &pkgname);
prop_dictionary_get_cstring_nocopy(pkg_repod, "version", &repover);
prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgver", &repopkgver); prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgver", &repopkgver);
prop_dictionary_get_cstring_nocopy(pkg_repod, "repository", &repoloc); prop_dictionary_get_cstring_nocopy(pkg_repod, "repository", &repoloc);
pkgname = xbps_pkg_name(repopkgver);
assert(pkgname);
repover = xbps_pkg_version(repopkgver);
assert(repover);
if (action == TRANS_UPDATE) { if (action == TRANS_UPDATE) {
/* /*
* Compare installed version vs best pkg available in repos. * Compare installed version vs best pkg available in repos.
*/ */
prop_dictionary_get_cstring_nocopy(pkg_pkgdb, prop_dictionary_get_cstring_nocopy(pkg_pkgdb,
"version", &instver); "pkgver", &instpkgver);
if (xbps_cmpver(repover, instver) <= 0) { if (xbps_cmpver(repopkgver, instpkgver) <= 0) {
xbps_dbg_printf(xhp, "[rpool] Skipping `%s-%s' " xbps_dbg_printf(xhp, "[rpool] Skipping `%s' "
"(installed: %s-%s) from repository `%s'\n", "(installed: %s) from repository `%s'\n",
pkgname, repover, pkgname, instver, repoloc); repopkgver, instpkgver, repoloc);
free(pkgname);
return EEXIST; return EEXIST;
} }
} }
/* /*
* Prepare transaction dictionary. * Prepare transaction dictionary.
*/ */
if ((rv = xbps_transaction_init(xhp)) != 0) if ((rv = xbps_transaction_init(xhp)) != 0) {
free(pkgname);
return rv; return rv;
}
unsorted = prop_dictionary_get(xhp->transd, "unsorted_deps"); unsorted = prop_dictionary_get(xhp->transd, "unsorted_deps");
/* /*
@ -126,24 +133,33 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, int action)
if (xbps_find_pkg_in_array(unsorted, repopkgver)) { if (xbps_find_pkg_in_array(unsorted, repopkgver)) {
xbps_dbg_printf(xhp, "[update] `%s' already queued in " xbps_dbg_printf(xhp, "[update] `%s' already queued in "
"transaction.\n", repopkgver); "transaction.\n", repopkgver);
free(pkgname);
return EEXIST; return EEXIST;
} }
} }
if ((rv = xbps_repository_find_deps(xhp, unsorted, pkg_repod)) != 0) if ((rv = xbps_repository_find_deps(xhp, unsorted, pkg_repod)) != 0) {
free(pkgname);
return rv; return rv;
}
/* /*
* Set package state in dictionary with same state than the * Set package state in dictionary with same state than the
* package currently uses, otherwise not-installed. * package currently uses, otherwise not-installed.
*/ */
if ((rv = xbps_pkg_state_installed(xhp, pkgname, &state)) != 0) { if ((rv = xbps_pkg_state_installed(xhp, pkgname, &state)) != 0) {
if (rv != ENOENT) if (rv != ENOENT) {
free(pkgname);
return rv; return rv;
}
/* Package not installed, don't error out */ /* Package not installed, don't error out */
state = XBPS_PKG_STATE_NOT_INSTALLED; state = XBPS_PKG_STATE_NOT_INSTALLED;
} }
if ((rv = xbps_set_pkg_state_dictionary(pkg_repod, state)) != 0) free(pkgname);
if ((rv = xbps_set_pkg_state_dictionary(pkg_repod, state)) != 0) {
free(pkgname);
return rv; return rv;
}
if ((action == TRANS_INSTALL) && (state == XBPS_PKG_STATE_UNPACKED)) if ((action == TRANS_INSTALL) && (state == XBPS_PKG_STATE_UNPACKED))
reason = "configure"; reason = "configure";
@ -165,8 +181,8 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, int action)
if (!prop_array_add(unsorted, pkg_repod)) if (!prop_array_add(unsorted, pkg_repod))
return EINVAL; return EINVAL;
xbps_dbg_printf(xhp, "%s-%s: added into the transaction (%s).\n", xbps_dbg_printf(xhp, "%s: added into the transaction (%s).\n",
pkgname, repover, repoloc); repopkgver, repoloc);
return 0; return 0;
} }
@ -174,9 +190,11 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, int action)
int int
xbps_transaction_update_packages(struct xbps_handle *xhp) xbps_transaction_update_packages(struct xbps_handle *xhp)
{ {
prop_dictionary_t pkgd;
prop_object_t obj; prop_object_t obj;
prop_object_iterator_t iter; prop_object_iterator_t iter;
const char *pkgname, *holdpkg; const char *pkgver, *holdpkg;
char *pkgname;
bool foundhold = false, newpkg_found = false; bool foundhold = false, newpkg_found = false;
int rv = 0; int rv = 0;
size_t x; size_t x;
@ -184,11 +202,31 @@ xbps_transaction_update_packages(struct xbps_handle *xhp)
if ((rv = xbps_pkgdb_init(xhp)) != 0) if ((rv = xbps_pkgdb_init(xhp)) != 0)
return rv; return rv;
iter = prop_array_iterator(xhp->pkgdb); iter = prop_dictionary_iterator(xhp->pkgdb);
assert(iter); assert(iter);
/*
* Check if there's a new update for XBPS before starting
* a full system upgrade.
*/
if (xbps_pkgdb_get_pkg(xhp, "xbps")) {
if (trans_find_pkg(xhp, "xbps", TRANS_UPDATE) == 0) {
xbps_set_cb_state(xhp, XBPS_STATE_XBPS_UPDATE, 0, NULL, NULL);
return 0;
}
}
if (xbps_pkgdb_get_pkg(xhp, "xbps-git")) {
if (trans_find_pkg(xhp, "xbps-git", TRANS_UPDATE) == 0) {
xbps_set_cb_state(xhp, XBPS_STATE_XBPS_UPDATE, 0, NULL, NULL);
return 0;
}
}
while ((obj = prop_object_iterator_next(iter))) { while ((obj = prop_object_iterator_next(iter))) {
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); pkgd = prop_dictionary_get_keysym(xhp->pkgdb, obj);
prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
pkgname = xbps_pkg_name(pkgver);
assert(pkgname);
for (x = 0; x < cfg_size(xhp->cfg, "PackagesOnHold"); x++) { for (x = 0; x < cfg_size(xhp->cfg, "PackagesOnHold"); x++) {
holdpkg = cfg_getnstr(xhp->cfg, "PackagesOnHold", x); holdpkg = cfg_getnstr(xhp->cfg, "PackagesOnHold", x);
@ -214,6 +252,7 @@ xbps_transaction_update_packages(struct xbps_handle *xhp)
*/ */
rv = 0; rv = 0;
} }
free(pkgname);
} }
prop_object_iterator_release(iter); prop_object_iterator_release(iter);

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2011-2012 Juan Romero Pardines. * Copyright (c) 2011-2013 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -40,8 +40,8 @@ xbps_transaction_package_replace(struct xbps_handle *xhp)
prop_dictionary_t instd, reppkgd, filesd; prop_dictionary_t instd, reppkgd, filesd;
prop_object_t obj, obj2; prop_object_t obj, obj2;
prop_object_iterator_t iter; prop_object_iterator_t iter;
const char *pattern, *pkgname, *curpkgname, *pkgver, *curpkgver; const char *pattern, *pkgver, *curpkgver;
char *buf; char *buf, *pkgname, *curpkgname;
bool instd_auto, sr; bool instd_auto, sr;
size_t i; size_t i;
@ -66,20 +66,23 @@ xbps_transaction_package_replace(struct xbps_handle *xhp)
((instd = xbps_pkgdb_get_virtualpkg(xhp, pattern)) == NULL)) ((instd = xbps_pkgdb_get_virtualpkg(xhp, pattern)) == NULL))
continue; continue;
prop_dictionary_get_cstring_nocopy(obj,
"pkgname", &pkgname);
prop_dictionary_get_cstring_nocopy(obj, prop_dictionary_get_cstring_nocopy(obj,
"pkgver", &pkgver); "pkgver", &pkgver);
prop_dictionary_get_cstring_nocopy(instd,
"pkgname", &curpkgname);
prop_dictionary_get_cstring_nocopy(instd, prop_dictionary_get_cstring_nocopy(instd,
"pkgver", &curpkgver); "pkgver", &curpkgver);
pkgname = xbps_pkg_name(pkgver);
assert(pkgname);
curpkgname = xbps_pkg_name(curpkgver);
assert(curpkgver);
/* /*
* Check that we are not replacing the same package, * Check that we are not replacing the same package,
* due to virtual packages. * due to virtual packages.
*/ */
if (strcmp(pkgname, curpkgname) == 0) if (strcmp(pkgname, curpkgname) == 0) {
free(pkgname);
free(curpkgname);
continue; continue;
}
xbps_dbg_printf(xhp, xbps_dbg_printf(xhp,
"Package `%s' will be replaced by `%s', " "Package `%s' will be replaced by `%s', "
@ -126,15 +129,17 @@ xbps_transaction_package_replace(struct xbps_handle *xhp)
"softreplace", true); "softreplace", true);
buf = xbps_xasprintf("%s/.%s.plist", buf = xbps_xasprintf("%s/.%s.plist",
xhp->metadir, curpkgname); xhp->metadir, curpkgname);
filesd = prop_dictionary_internalize_from_zfile(buf); filesd = prop_dictionary_internalize_from_file(buf);
free(buf); free(buf);
assert(filesd != NULL); assert(filesd != NULL);
buf = xbps_xasprintf("%s/.%s.plist", buf = xbps_xasprintf("%s/.%s.plist",
xhp->metadir, pkgname); xhp->metadir, pkgname);
if (!prop_dictionary_externalize_to_zfile(filesd, buf)) { if (!prop_dictionary_externalize_to_file(filesd, buf)) {
free(buf); free(buf);
prop_object_release(filesd); prop_object_release(filesd);
prop_object_iterator_release(iter); prop_object_iterator_release(iter);
free(pkgname);
free(curpkgname);
return errno; return errno;
} }
prop_object_release(filesd); prop_object_release(filesd);
@ -147,6 +152,8 @@ xbps_transaction_package_replace(struct xbps_handle *xhp)
prop_dictionary_set_cstring_nocopy(instd, prop_dictionary_set_cstring_nocopy(instd,
"transaction", "remove"); "transaction", "remove");
prop_array_add(unsorted, instd); prop_array_add(unsorted, instd);
free(pkgname);
free(curpkgname);
} }
prop_object_iterator_release(iter); prop_object_iterator_release(iter);
} }

View File

@ -217,14 +217,17 @@ xbps_pkg_index_files_plist(struct xbps_handle *xhp, const char *uri)
char HIDDEN * char HIDDEN *
xbps_repository_pkg_path(struct xbps_handle *xhp, prop_dictionary_t pkg_repod) xbps_repository_pkg_path(struct xbps_handle *xhp, prop_dictionary_t pkg_repod)
{ {
const char *filen, *repoloc; const char *pkgver, *arch, *repoloc;
char *lbinpkg = NULL; char *lbinpkg = NULL;
assert(xhp); assert(xhp);
assert(prop_object_type(pkg_repod) == PROP_TYPE_DICTIONARY); assert(prop_object_type(pkg_repod) == PROP_TYPE_DICTIONARY);
if (!prop_dictionary_get_cstring_nocopy(pkg_repod, if (!prop_dictionary_get_cstring_nocopy(pkg_repod,
"filename", &filen)) "pkgver", &pkgver))
return NULL;
if (!prop_dictionary_get_cstring_nocopy(pkg_repod,
"architecture", &arch))
return NULL; return NULL;
if (!prop_dictionary_get_cstring_nocopy(pkg_repod, if (!prop_dictionary_get_cstring_nocopy(pkg_repod,
"repository", &repoloc)) "repository", &repoloc))
@ -234,7 +237,8 @@ xbps_repository_pkg_path(struct xbps_handle *xhp, prop_dictionary_t pkg_repod)
/* /*
* First check if binpkg is available in cachedir. * First check if binpkg is available in cachedir.
*/ */
lbinpkg = xbps_xasprintf("%s/%s", xhp->cachedir, filen); lbinpkg = xbps_xasprintf("%s/%s.%s.xbps", xhp->cachedir,
pkgver, arch);
if (access(lbinpkg, R_OK) == 0) if (access(lbinpkg, R_OK) == 0)
return lbinpkg; return lbinpkg;
@ -243,7 +247,7 @@ xbps_repository_pkg_path(struct xbps_handle *xhp, prop_dictionary_t pkg_repod)
/* /*
* Local and remote repositories use the same path. * Local and remote repositories use the same path.
*/ */
return xbps_xasprintf("%s/%s", repoloc, filen); return xbps_xasprintf("%s/%s.%s.xbps", repoloc, pkgver, arch);
} }
bool bool