Major API/ABI cleanup bringing performance improvements and fixes.

These are the core interfaces in the new API:

rpool - Interface to interact with the repository pool.
rindex - Interface to interact with repository indexes.
pkgdb - Interface to interact with local packages.
transaction - Interface to interact with a transaction.

This also brings new repository index format, making the index file
per architecture and being incompatible with previous versions.

The transaction frequency flush option has been removed, and due to
the nature of package states it was causing more harm than good.

More changes coming soon, but the API shall remain stable from now on.
This commit is contained in:
Juan RP
2012-11-30 07:11:51 +01:00
parent 16e18313da
commit 63c1883201
57 changed files with 1437 additions and 2640 deletions

View File

@@ -2,7 +2,7 @@ TOPDIR = ../..
-include $(TOPDIR)/config.mk
BIN = xbps-rindex
OBJS = main.o index.o index-files.o remove-obsoletes.o common.o
OBJS = main.o index.o remove-obsoletes.o common.o
MAN = $(BIN).8
include $(TOPDIR)/mk/prog.mk

View File

@@ -56,11 +56,13 @@ remove_pkg(const char *repodir, const char *arch, const char *file)
filepath = xbps_xasprintf("%s/%s", repodir, file);
if (remove(filepath) == -1) {
rv = errno;
xbps_error_printf("failed to remove old binpkg `%s': %s\n",
file, strerror(rv));
free(filepath);
return rv;
if (errno != ENOENT) {
rv = errno;
xbps_error_printf("failed to remove old binpkg "
"`%s': %s\n", file, strerror(rv));
free(filepath);
return rv;
}
}
free(filepath);

View File

@@ -1,377 +0,0 @@
/*-
* Copyright (c) 2012 Juan Romero Pardines.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <errno.h>
#include <libgen.h>
#include <assert.h>
#include <xbps_api.h>
#include "defs.h"
int
index_files_clean(struct xbps_handle *xhp, const char *repodir)
{
prop_object_t obj;
prop_array_t idx, idxfiles, obsoletes;
char *plist, *plistf, *pkgver, *str;
const char *p, *arch, *ipkgver, *iarch;
size_t x, i;
int rv = 0;
bool flush = false;
plist = plistf = pkgver = str = NULL;
idx = idxfiles = obsoletes = NULL;
/* Internalize index-files.plist if found */
if ((plistf = xbps_pkg_index_files_plist(xhp, repodir)) == NULL)
return EINVAL;
if ((idxfiles = prop_array_internalize_from_zfile(plistf)) == NULL) {
free(plistf);
return 0;
}
/* Internalize index.plist */
if ((plist = xbps_pkg_index_plist(xhp, repodir)) == NULL) {
rv = EINVAL;
goto out;
}
if ((idx = prop_array_internalize_from_zfile(plist)) == NULL) {
rv = EINVAL;
goto out;
}
printf("Cleaning `%s' index-files, please wait...\n", repodir);
/*
* Iterate over index-files array to find obsolete entries.
*/
obsoletes = prop_array_create();
assert(obsoletes);
for (x = 0; x < prop_array_count(idxfiles); x++) {
obj = prop_array_get(idxfiles, x);
prop_dictionary_get_cstring_nocopy(obj, "pkgver", &ipkgver);
prop_dictionary_get_cstring_nocopy(obj, "architecture", &iarch);
if (xbps_find_pkg_in_array_by_pkgver(xhp, idx, ipkgver, iarch)) {
/* pkg found, do nothing */
continue;
}
str = xbps_xasprintf("%s,%s", ipkgver, iarch);
if (!prop_array_add_cstring(obsoletes, str)) {
free(str);
rv = EINVAL;
goto out;
}
free(str);
}
/*
* Iterate over the obsoletes and array and remove entries
* from index-files array.
*/
for (i = 0; i < prop_array_count(obsoletes); i++) {
prop_array_get_cstring_nocopy(obsoletes, i, &p);
pkgver = strdup(p);
for (x = 0; x < strlen(p); x++) {
if ((pkgver[x] = p[x]) == ',') {
pkgver[x] = '\0';
break;
}
}
arch = strchr(p, ',') + 1;
if (!xbps_remove_pkg_from_array_by_pkgver(
xhp, idxfiles, pkgver, arch)) {
free(pkgver);
rv = EINVAL;
goto out;
}
printf("index-files: removed obsolete entry `%s' "
"(%s)\n", pkgver, arch);
free(pkgver);
flush = true;
}
/* Externalize index-files array to plist when necessary */
if (flush && !prop_array_externalize_to_zfile(idxfiles, plistf))
rv = errno;
printf("index-files: %u packages registered.\n",
prop_array_count(idxfiles));
out:
if (obsoletes)
prop_object_release(obsoletes);
if (idx)
prop_object_release(idx);
if (idxfiles)
prop_object_release(idxfiles);
if (plist)
free(plist);
if (plistf)
free(plistf);
return rv;
}
int
index_files_add(struct xbps_handle *xhp, int argc, char **argv)
{
prop_array_t idxfiles = NULL;
prop_object_t obj, fileobj;
prop_dictionary_t pkgprops, pkg_filesd, pkgd;
prop_array_t files, pkg_cffiles, pkg_files, pkg_links;
const char *binpkg, *pkgver, *arch, *version;
char *plist, *repodir, *p, *pkgname;
size_t x;
int i, rv = 0;
bool found, flush;
found = flush = false;
plist = repodir = p = NULL;
obj = fileobj = NULL;
pkgprops = pkg_filesd = pkgd = NULL;
files = NULL;
if ((p = strdup(argv[0])) == NULL) {
rv = ENOMEM;
goto out;
}
repodir = dirname(p);
if ((plist = xbps_pkg_index_files_plist(xhp, repodir)) == NULL) {
rv = ENOMEM;
goto out;
}
/*
* Internalize index-files.plist if found and process argv.
*/
if ((idxfiles = prop_array_internalize_from_zfile(plist)) == NULL) {
if (errno == ENOENT) {
idxfiles = prop_array_create();
assert(idxfiles);
} else {
rv = errno;
goto out;
}
}
for (i = 0; i < argc; i++) {
found = false;
pkgprops = xbps_dictionary_metadata_plist_by_url(argv[i],
"./props.plist");
if (pkgprops == NULL) {
fprintf(stderr, "index-files: cannot internalize "
"%s props.plist: %s\n", argv[i], strerror(errno));
continue;
}
prop_dictionary_get_cstring_nocopy(pkgprops,
"filename", &binpkg);
prop_dictionary_get_cstring_nocopy(pkgprops,
"pkgver", &pkgver);
prop_dictionary_get_cstring_nocopy(pkgprops,
"architecture", &arch);
if (xbps_find_pkg_in_array_by_pkgver(xhp, idxfiles,
pkgver, arch)) {
fprintf(stderr, "index-files: skipping `%s' (%s), "
"already registered.\n", pkgver, arch);
prop_object_release(pkgprops);
pkgprops = NULL;
continue;
}
/* internalize files.plist from binary package archive */
pkg_filesd = xbps_dictionary_metadata_plist_by_url(argv[i],
"./files.plist");
if (pkg_filesd == NULL) {
prop_object_release(pkgprops);
rv = EINVAL;
goto out;
}
/* Find out if binary pkg stored in index contain any file */
pkg_cffiles = prop_dictionary_get(pkg_filesd, "conf_files");
if (pkg_cffiles != NULL && prop_array_count(pkg_cffiles))
found = true;
else
pkg_cffiles = NULL;
pkg_files = prop_dictionary_get(pkg_filesd, "files");
if (pkg_files != NULL && prop_array_count(pkg_files))
found = true;
else
pkg_files = NULL;
pkg_links = prop_dictionary_get(pkg_filesd, "links");
if (pkg_links != NULL && prop_array_count(pkg_links))
found = true;
else
pkg_links = NULL;
/* If pkg does not contain any file, ignore it */
if (!found) {
prop_object_release(pkgprops);
prop_object_release(pkg_filesd);
continue;
}
/* create pkg dictionary */
if ((pkgd = prop_dictionary_create()) == NULL) {
prop_object_release(pkgprops);
prop_object_release(pkg_filesd);
rv = EINVAL;
goto out;
}
/* add pkgver and architecture objects into pkg dictionary */
if (!prop_dictionary_set_cstring(pkgd, "architecture", arch)) {
prop_object_release(pkgprops);
prop_object_release(pkg_filesd);
prop_object_release(pkgd);
rv = EINVAL;
goto out;
}
if (!prop_dictionary_set_cstring(pkgd, "pkgver", pkgver)) {
prop_object_release(pkgprops);
prop_object_release(pkg_filesd);
prop_object_release(pkgd);
rv = EINVAL;
goto out;
}
/* add files array obj into pkg dictionary */
if ((files = prop_array_create()) == NULL) {
prop_object_release(pkgprops);
prop_object_release(pkg_filesd);
prop_object_release(pkgd);
rv = EINVAL;
goto out;
}
if (!prop_dictionary_set(pkgd, "files", files)) {
prop_object_release(pkgprops);
prop_object_release(pkg_filesd);
prop_object_release(files);
prop_object_release(pkgd);
rv = EINVAL;
goto out;
}
/* add conf_files in pkgd */
if (pkg_cffiles != NULL) {
for (x = 0; x < prop_array_count(pkg_cffiles); x++) {
obj = prop_array_get(pkg_cffiles, x);
fileobj = prop_dictionary_get(obj, "file");
if (!prop_array_add(files, fileobj)) {
prop_object_release(pkgprops);
prop_object_release(pkg_filesd);
prop_object_release(files);
prop_object_release(pkgd);
rv = EINVAL;
goto out;
}
}
}
/* add files array in pkgd */
if (pkg_files != NULL) {
for (x = 0; x < prop_array_count(pkg_files); x++) {
obj = prop_array_get(pkg_files, x);
fileobj = prop_dictionary_get(obj, "file");
if (!prop_array_add(files, fileobj)) {
prop_object_release(pkgprops);
prop_object_release(pkg_filesd);
prop_object_release(files);
prop_object_release(pkgd);
rv = EINVAL;
goto out;
}
}
}
/* add links array in pkgd */
if (pkg_links != NULL) {
for (x = 0; x < prop_array_count(pkg_links); x++) {
obj = prop_array_get(pkg_links, x);
fileobj = prop_dictionary_get(obj, "file");
if (!prop_array_add(files, fileobj)) {
prop_object_release(pkgprops);
prop_object_release(pkg_filesd);
prop_object_release(files);
prop_object_release(pkgd);
rv = EINVAL;
goto out;
}
}
}
/* add pkgd into the index-files array */
if (!prop_array_add(idxfiles, pkgd)) {
prop_object_release(pkgprops);
prop_object_release(pkg_filesd);
prop_object_release(files);
prop_object_release(pkgd);
rv = EINVAL;
goto out;
}
flush = true;
printf("index-files: added `%s' (%s)\n", pkgver, arch);
prop_object_release(pkg_filesd);
prop_object_release(files);
prop_object_release(pkgd);
pkg_filesd = pkgd = NULL;
files = NULL;
/*
* Remove old entry (if exists).
*/
pkgname = xbps_pkg_name(pkgver);
assert(pkgname);
version = xbps_pkg_version(pkgver);
assert(version);
p = xbps_xasprintf("%s<%s", pkgname, version);
pkgd = xbps_find_pkg_in_array_by_pattern(xhp, idxfiles, p, NULL);
if (pkgd) {
prop_dictionary_get_cstring_nocopy(pkgd,
"pkgver", &pkgver);
prop_dictionary_get_cstring_nocopy(pkgd,
"architecture", &arch);
printf("index-files: remove obsolete entry `%s' (%s)\n",
pkgver, arch);
xbps_remove_pkg_from_array_by_pkgver(xhp,
idxfiles, pkgver, NULL);
}
prop_object_release(pkgprops);
free(pkgname);
}
if (flush && !prop_array_externalize_to_zfile(idxfiles, plist)) {
fprintf(stderr, "failed to externalize %s: %s\n",
plist, strerror(errno));
rv = errno;
}
printf("index-files: %u packages registered.\n",
prop_array_count(idxfiles));
out:
if (p)
free(p);
if (plist)
free(plist);
if (idxfiles)
prop_object_release(idxfiles);
return rv;
}

View File

@@ -43,21 +43,24 @@
int
index_clean(struct xbps_handle *xhp, const char *repodir)
{
prop_array_t array;
prop_dictionary_t pkgd;
const char *filen, *pkgver, *arch;
char *plist;
size_t i, idx = 0;
prop_array_t array, result = NULL;
prop_dictionary_t idx, idxfiles, pkgd;
prop_dictionary_keysym_t ksym;
const char *filen, *pkgver, *arch, *keyname;
char *plist, *plistf;
size_t i;
int rv = 0;
bool flush = false;
if ((plist = xbps_pkg_index_plist(xhp, repodir)) == NULL)
return -1;
plist = xbps_pkg_index_plist(xhp, repodir);
assert(plist);
plistf = xbps_pkg_index_files_plist(xhp, repodir);
assert(plistf);
array = prop_array_internalize_from_zfile(plist);
if (array == NULL) {
idx = prop_dictionary_internalize_from_zfile(plist);
if (idx == NULL) {
if (errno != ENOENT) {
xbps_error_printf("xbps-repo: cannot read `%s': %s\n",
fprintf(stderr, "index: cannot read `%s': %s\n",
plist, strerror(errno));
free(plist);
return -1;
@@ -66,38 +69,75 @@ index_clean(struct xbps_handle *xhp, const char *repodir)
return 0;
}
}
idxfiles = prop_dictionary_internalize_from_zfile(plistf);
if (idxfiles == NULL) {
if (errno != ENOENT) {
fprintf(stderr, "index: cannot read `%s': %s\n",
plistf, strerror(errno));
rv = -1;
goto out;
} else {
goto out;
}
}
if (chdir(repodir) == -1) {
fprintf(stderr, "cannot chdir to %s: %s\n",
fprintf(stderr, "index: cannot chdir to %s: %s\n",
repodir, strerror(errno));
rv = errno;
rv = -1;
goto out;
}
printf("Cleaning `%s' index, please wait...\n", repodir);
again:
for (i = idx; i < prop_array_count(array); i++) {
pkgd = prop_array_get(array, i);
prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
array = prop_dictionary_all_keys(idx);
for (i = 0; i < prop_array_count(array); i++) {
ksym = prop_array_get(array, i);
pkgd = prop_dictionary_get_keysym(idx, ksym);
prop_dictionary_get_cstring_nocopy(pkgd, "filename", &filen);
prop_dictionary_get_cstring_nocopy(pkgd, "architecture", &arch);
if (access(filen, R_OK) == -1) {
prop_dictionary_get_cstring_nocopy(pkgd,
"pkgver", &pkgver);
prop_dictionary_get_cstring_nocopy(pkgd,
"architecture", &arch);
printf("index: removed obsolete entry `%s' (%s)\n",
pkgver, arch);
prop_array_remove(array, i);
if (result == NULL)
result = prop_array_create();
keyname = prop_dictionary_keysym_cstring_nocopy(ksym);
prop_array_add_cstring(result, keyname);
flush = true;
idx = i;
goto again;
}
}
if (flush && !prop_array_externalize_to_zfile(array, plist)) {
rv = errno;
goto out;
}
printf("index: %u packages registered.\n", prop_array_count(array));
out:
free(plist);
prop_object_release(array);
if (flush) {
for (i = 0; i < prop_array_count(result); i++) {
prop_array_get_cstring_nocopy(result, i, &keyname);
prop_dictionary_remove(idx, keyname);
prop_dictionary_remove(idxfiles, keyname);
}
prop_object_release(result);
if (!prop_dictionary_externalize_to_zfile(idx, plist) &&
!prop_dictionary_externalize_to_zfile(idxfiles, plistf)) {
fprintf(stderr, "index: failed to externalize %s: %s\n",
plist, strerror(errno));
goto out;
}
}
printf("index: %u packages registered.\n",
prop_dictionary_count(idx));
printf("index-files: %u packages registered.\n",
prop_dictionary_count(idxfiles));
out:
if (plist)
free(plist);
if (plistf)
free(plistf);
if (idx)
prop_object_release(idx);
if (idxfiles)
prop_object_release(idxfiles);
return rv;
}
@@ -108,15 +148,21 @@ out:
int
index_add(struct xbps_handle *xhp, int argc, char **argv)
{
prop_array_t idx = NULL;
prop_dictionary_t newpkgd = NULL, curpkgd;
prop_array_t filespkgar, pkg_files, pkg_links, pkg_cffiles;
prop_dictionary_t idx, idxfiles, newpkgd, newpkgfilesd, curpkgd;
prop_dictionary_t filespkgd;
prop_object_t obj, fileobj;
struct stat st;
const char *pkgname, *version, *regver, *oldfilen, *oldpkgver;
const char *arch, *oldarch;
const char *pkgver, *arch, *oldarch;
char *sha256, *filen, *repodir, *buf, *buf2;
char *tmpfilen = NULL, *tmprepodir = NULL, *plist = NULL;
char *tmpfilen, *tmprepodir, *plist, *plistf;
size_t x;
int i, ret = 0, rv = 0;
bool flush = false;
bool files_flush = false, found = false, flush = false;
idx = idxfiles = newpkgd = newpkgfilesd = curpkgd = NULL;
tmpfilen = tmprepodir = plist = plistf = NULL;
if ((tmprepodir = strdup(argv[0])) == NULL) {
rv = ENOMEM;
@@ -124,18 +170,33 @@ index_add(struct xbps_handle *xhp, int argc, char **argv)
}
repodir = dirname(tmprepodir);
/* Internalize plist file or create it if doesn't exist */
/* Internalize index or create it if doesn't exist */
if ((plist = xbps_pkg_index_plist(xhp, repodir)) == NULL)
return -1;
if ((idx = prop_array_internalize_from_zfile(plist)) == NULL) {
if ((idx = prop_dictionary_internalize_from_zfile(plist)) == NULL) {
if (errno != ENOENT) {
xbps_error_printf("xbps-repo: cannot read `%s': %s\n",
fprintf(stderr, "index: cannot read `%s': %s\n",
plist, strerror(errno));
rv = -1;
goto out;
} else {
idx = prop_array_create();
idx = prop_dictionary_create();
assert(idx);
}
}
/* Internalize index-files or create it if doesn't exist */
if ((plistf = xbps_pkg_index_files_plist(xhp, repodir)) == NULL)
return -1;
if ((idxfiles = prop_dictionary_internalize_from_zfile(plistf)) == NULL) {
if (errno != ENOENT) {
fprintf(stderr, "index: cannot read `%s': %s\n",
plistf, strerror(errno));
rv = -1;
goto out;
} else {
idxfiles = prop_dictionary_create();
assert(idx);
}
}
@@ -152,28 +213,34 @@ index_add(struct xbps_handle *xhp, int argc, char **argv)
/*
* Read metadata props plist dictionary from binary package.
*/
newpkgd = xbps_dictionary_metadata_plist_by_url(argv[i],
newpkgd = xbps_get_pkg_plist_from_binpkg(argv[i],
"./props.plist");
if (newpkgd == NULL) {
xbps_error_printf("failed to read %s metadata for `%s',"
fprintf(stderr, "failed to read %s metadata for `%s',"
" skipping!\n", XBPS_PKGPROPS, argv[i]);
free(tmpfilen);
continue;
}
prop_dictionary_get_cstring_nocopy(newpkgd, "architecture",
&arch);
prop_dictionary_get_cstring_nocopy(newpkgd, "pkgver", &pkgver);
if (!xbps_pkg_arch_match(xhp, arch, NULL)) {
fprintf(stderr, "index: ignoring %s, unmatched "
"arch (%s)\n", pkgver, arch);
prop_object_release(newpkgd);
continue;
}
prop_dictionary_get_cstring_nocopy(newpkgd, "pkgname",
&pkgname);
prop_dictionary_get_cstring_nocopy(newpkgd, "version",
&version);
prop_dictionary_get_cstring_nocopy(newpkgd, "architecture",
&arch);
/*
* Check if this package exists already in the index, but first
* checking the version. If current package version is greater
* than current registered package, update the index; otherwise
* pass to the next one.
*/
curpkgd =
xbps_find_pkg_in_array_by_name(xhp, idx, pkgname, NULL);
curpkgd = prop_dictionary_get(idx, pkgname);
if (curpkgd == NULL) {
if (errno && errno != ENOENT) {
prop_object_release(newpkgd);
@@ -235,18 +302,7 @@ index_add(struct xbps_handle *xhp, int argc, char **argv)
free(tmpfilen);
goto out;
}
if (!xbps_remove_pkg_from_array_by_pkgver(xhp, idx,
buf2, oldarch)) {
xbps_error_printf("failed to remove %s "
"from plist index: %s\n", buf,
strerror(errno));
rv = errno;
free(buf);
free(buf2);
prop_object_release(newpkgd);
free(tmpfilen);
goto out;
}
prop_dictionary_remove(idx, pkgname);
free(buf2);
printf("index: removed obsolete entry/binpkg %s.\n", buf);
free(buf);
@@ -292,7 +348,7 @@ index_add(struct xbps_handle *xhp, int argc, char **argv)
/*
* Add new pkg dictionary into the index.
*/
if (!prop_array_add(idx, newpkgd)) {
if (!prop_dictionary_set(idx, pkgname, newpkgd)) {
prop_object_release(newpkgd);
free(tmpfilen);
rv = EINVAL;
@@ -301,23 +357,121 @@ index_add(struct xbps_handle *xhp, int argc, char **argv)
flush = true;
printf("index: added `%s-%s' (%s).\n", pkgname, version, arch);
free(tmpfilen);
/*
* Add new pkg dictionary into the index-files.
*/
found = false;
newpkgfilesd = xbps_get_pkg_plist_from_binpkg(argv[i],
"./files.plist");
if (newpkgfilesd == NULL) {
rv = EINVAL;
goto out;
}
/* Find out if binary pkg stored in index contain any file */
pkg_cffiles = prop_dictionary_get(newpkgfilesd, "conf_files");
if (pkg_cffiles != NULL && prop_array_count(pkg_cffiles))
found = true;
else
pkg_cffiles = NULL;
pkg_files = prop_dictionary_get(newpkgfilesd, "files");
if (pkg_files != NULL && prop_array_count(pkg_files))
found = true;
else
pkg_files = NULL;
pkg_links = prop_dictionary_get(newpkgfilesd, "links");
if (pkg_links != NULL && prop_array_count(pkg_links))
found = true;
else
pkg_links = NULL;
/* If pkg does not contain any file, ignore it */
if (!found) {
prop_object_release(newpkgfilesd);
prop_object_release(newpkgd);
continue;
}
/* create pkg files array */
filespkgar = prop_array_create();
assert(filespkgar);
/* add conf_files in pkg files array */
if (pkg_cffiles != NULL) {
for (x = 0; x < prop_array_count(pkg_cffiles); x++) {
obj = prop_array_get(pkg_cffiles, x);
fileobj = prop_dictionary_get(obj, "file");
prop_array_add(filespkgar, fileobj);
}
}
/* add files array in pkg array */
if (pkg_files != NULL) {
for (x = 0; x < prop_array_count(pkg_files); x++) {
obj = prop_array_get(pkg_files, x);
fileobj = prop_dictionary_get(obj, "file");
prop_array_add(filespkgar, fileobj);
}
}
/* add links array in pkgd */
if (pkg_links != NULL) {
for (x = 0; x < prop_array_count(pkg_links); x++) {
obj = prop_array_get(pkg_links, x);
fileobj = prop_dictionary_get(obj, "file");
prop_array_add(filespkgar, fileobj);
}
}
prop_object_release(newpkgfilesd);
/* create pkg dictionary */
filespkgd = prop_dictionary_create();
assert(filespkgd);
/* add pkg files array into pkg dictionary */
prop_dictionary_set(filespkgd, "files", filespkgar);
prop_object_release(filespkgar);
/* set pkgver obj into pkg dictionary */
prop_dictionary_set_cstring(filespkgd, "pkgver", pkgver);
/* add pkg dictionary into index-files */
prop_dictionary_set(idxfiles, pkgname, filespkgd);
prop_object_release(filespkgd);
printf("index-files: added `%s' (%s)\n", pkgver, arch);
files_flush = true;
prop_object_release(newpkgd);
}
if (flush && !prop_array_externalize_to_zfile(idx, plist)) {
xbps_error_printf("failed to externalize plist: %s\n",
if (flush && !prop_dictionary_externalize_to_zfile(idx, plist)) {
fprintf(stderr, "index: failed to externalize plist: %s\n",
strerror(errno));
rv = errno;
rv = -1;
goto out;
}
printf("index: %u packages registered.\n", prop_array_count(idx));
if (files_flush &&
!prop_dictionary_externalize_to_zfile(idxfiles, plistf)) {
fprintf(stderr, "index-files: failed to externalize "
"plist: %s\n", strerror(errno));
rv = -1;
goto out;
}
printf("index: %u packages registered.\n",
prop_dictionary_count(idx));
printf("index-files: %u packages registered.\n",
prop_dictionary_count(idxfiles));
out:
if (tmprepodir)
free(tmprepodir);
if (plist)
free(plist);
if (plistf)
free(plistf);
if (idx)
prop_object_release(idx);
if (idxfiles)
prop_object_release(idxfiles);
return rv;
}

View File

@@ -99,15 +99,12 @@ main(int argc, char **argv)
exit(EXIT_FAILURE);
}
if (add_mode) {
if (index_add(&xh, argc - optind, argv + optind) == 0)
rv = index_files_add(&xh, argc - optind, argv + optind);
} else if (clean_mode) {
if (index_clean(&xh, argv[optind]) == 0)
rv = index_files_clean(&xh, argv[optind]);
} else if (rm_mode) {
if (add_mode)
rv = index_add(&xh, argc - optind, argv + optind);
else if (clean_mode)
rv = index_clean(&xh, argv[optind]);
else if (rm_mode)
rv = remove_obsoletes(&xh, argv[optind]);
}
xbps_end(&xh);
exit(rv ? EXIT_FAILURE : EXIT_SUCCESS);

View File

@@ -39,8 +39,8 @@
int
remove_obsoletes(struct xbps_handle *xhp, const char *repodir)
{
prop_dictionary_t pkgd;
prop_array_t idx;
prop_dictionary_t pkgd, idx;
struct xbps_rindex ri;
DIR *dirp;
struct dirent *dp;
const char *pkgver, *arch;
@@ -50,10 +50,10 @@ remove_obsoletes(struct xbps_handle *xhp, const char *repodir)
if ((plist = xbps_pkg_index_plist(xhp, repodir)) == NULL)
return -1;
idx = prop_array_internalize_from_zfile(plist);
idx = prop_dictionary_internalize_from_zfile(plist);
if (idx == NULL) {
if (errno != ENOENT) {
xbps_error_printf("xbps-repo: cannot read `%s': %s\n",
fprintf(stderr, "xbps-rindex: cannot read `%s': %s\n",
plist, strerror(errno));
free(plist);
return -1;
@@ -62,14 +62,19 @@ remove_obsoletes(struct xbps_handle *xhp, const char *repodir)
return 0;
}
}
/* initialize repository index */
ri.repod = idx;
ri.uri = repodir;
ri.xhp = xhp;
if (chdir(repodir) == -1) {
fprintf(stderr, "cannot chdir to %s: %s\n",
fprintf(stderr, "xbps-rindex: cannot chdir to %s: %s\n",
repodir, strerror(errno));
prop_object_release(idx);
return errno;
}
if ((dirp = opendir(repodir)) == NULL) {
fprintf(stderr, "failed to open %s: %s\n",
fprintf(stderr, "xbps-rindex: failed to open %s: %s\n",
repodir, strerror(errno));
prop_object_release(idx);
return errno;
@@ -82,12 +87,12 @@ remove_obsoletes(struct xbps_handle *xhp, const char *repodir)
if (strcmp(ext, ".xbps"))
continue;
pkgd = xbps_dictionary_metadata_plist_by_url(dp->d_name,
pkgd = xbps_get_pkg_plist_from_binpkg(dp->d_name,
"./props.plist");
if (pkgd == NULL) {
rv = remove_pkg(repodir, arch, dp->d_name);
if (rv != 0) {
fprintf(stderr, "index: failed to remove "
fprintf(stderr, "xbps-rindex: failed to remove "
"package `%s': %s\n", dp->d_name,
strerror(rv));
prop_object_release(pkgd);
@@ -100,10 +105,10 @@ remove_obsoletes(struct xbps_handle *xhp, const char *repodir)
/*
* If binpkg is not registered in index, remove binpkg.
*/
if (!xbps_find_pkg_in_array_by_pkgver(xhp, idx, pkgver, arch)) {
if (!xbps_rindex_get_pkg(&ri, pkgver)) {
rv = remove_pkg(repodir, arch, dp->d_name);
if (rv != 0) {
fprintf(stderr, "index: failed to remove "
fprintf(stderr, "xbps-rindex: failed to remove "
"package `%s': %s\n", dp->d_name,
strerror(rv));
prop_object_release(pkgd);