diff --git a/NEWS b/NEWS index 6b6d7fca..67ab2c9a 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,35 @@ 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. * xbps-query(8): packages can be matched by using virtual package diff --git a/TODO b/TODO index 20276ef2..d08cd061 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,6 @@ libxbps: - transaction: avoid fetching the whole pkg when updating and only fetch modified files from target pkg. - - properties: (update-first) still unimplemented. - Add support to handle 'shlib-requires' and 'shlib-provides'. xbps-create: diff --git a/bin/xbps-install/state_cb.c b/bin/xbps-install/state_cb.c index dfe2e0c0..30ae1658 100644 --- a/bin/xbps-install/state_cb.c +++ b/bin/xbps-install/state_cb.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2011-2012 Juan Romero Pardines. + * Copyright (c) 2011-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "defs.h" @@ -34,7 +35,8 @@ void state_cb(struct xbps_state_cb_data *xscd, void *cbdata) { prop_dictionary_t pkgd; - const char *version; + const char *instver, *newver; + char *pkgname; bool syslog_enabled = false; (void)cbdata; @@ -59,36 +61,44 @@ state_cb(struct xbps_state_cb_data *xscd, void *cbdata) printf("\n[*] Configuring unpacked packages\n"); break; case XBPS_STATE_REPOSYNC: - printf("[*] Updating `%s' ...\n", xscd->arg0); + printf("[*] Updating `%s' ...\n", xscd->arg); break; 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; case XBPS_STATE_CONFIG_FILE: if (xscd->desc != NULL) printf("%s\n", xscd->desc); break; case XBPS_STATE_REMOVE: - printf("%s-%s: removing ...\n", xscd->arg0, xscd->arg1); + printf("%s: removing ...\n", xscd->arg); break; case XBPS_STATE_CONFIGURE: - printf("%s-%s: configuring ...\n", xscd->arg0, xscd->arg1); + printf("%s: configuring ...\n", xscd->arg); break; case XBPS_STATE_REGISTER: case XBPS_STATE_UNREGISTER: /* empty */ break; case XBPS_STATE_UNPACK: - printf("%s-%s: unpacking ...\n", xscd->arg0, xscd->arg1); + printf("%s: unpacking ...\n", xscd->arg); break; case XBPS_STATE_INSTALL: /* empty */ break; case XBPS_STATE_UPDATE: - pkgd = xbps_pkgdb_get_pkg(xscd->xhp, xscd->arg0); - prop_dictionary_get_cstring_nocopy(pkgd, "version", &version); - printf("%s-%s: updating to %s ...\n", xscd->arg0, - version, xscd->arg1); + pkgname = xbps_pkg_name(xscd->arg); + assert(pkgname); + newver = xbps_pkg_version(xscd->arg); + 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; /* success */ case XBPS_STATE_REMOVE_FILE: @@ -101,27 +111,24 @@ state_cb(struct xbps_state_cb_data *xscd, void *cbdata) } break; case XBPS_STATE_INSTALL_DONE: - printf("%s-%s: installed successfully.\n", - xscd->arg0, xscd->arg1); + printf("%s: installed successfully.\n", xscd->arg); if (syslog_enabled) - syslog(LOG_NOTICE, "Installed `%s-%s' successfully " - "(rootdir: %s).", xscd->arg0, xscd->arg1, + syslog(LOG_NOTICE, "Installed `%s' successfully " + "(rootdir: %s).", xscd->arg, xscd->xhp->rootdir); break; case XBPS_STATE_UPDATE_DONE: - printf("%s-%s: updated successfully.\n", - xscd->arg0, xscd->arg1); + printf("%s: updated successfully.\n", xscd->arg); if (syslog_enabled) - syslog(LOG_NOTICE, "Updated `%s' to `%s' successfully " - "(rootdir: %s).", xscd->arg0, xscd->arg1, + syslog(LOG_NOTICE, "Updated `%s' successfully " + "(rootdir: %s).", xscd->arg, xscd->xhp->rootdir); break; case XBPS_STATE_REMOVE_DONE: - printf("%s-%s: removed successfully.\n", - xscd->arg0, xscd->arg1); + printf("%s: removed successfully.\n", xscd->arg); if (syslog_enabled) - syslog(LOG_NOTICE, "Removed `%s-%s' successfully " - "(rootdir: %s).", xscd->arg0, xscd->arg1, + syslog(LOG_NOTICE, "Removed `%s' successfully " + "(rootdir: %s).", xscd->arg, xscd->xhp->rootdir); break; /* errors */ @@ -152,7 +159,7 @@ state_cb(struct xbps_state_cb_data *xscd, void *cbdata) break; default: xbps_dbg_printf(xscd->xhp, - "unknown state %d\n", xscd->state); + "%s: unknown state %d\n", xscd->arg, xscd->state); break; } } diff --git a/bin/xbps-install/transaction.c b/bin/xbps-install/transaction.c index 480faeb4..fe65a4ec 100644 --- a/bin/xbps-install/transaction.c +++ b/bin/xbps-install/transaction.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2012 Juan Romero Pardines. + * Copyright (c) 2009-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -75,20 +75,18 @@ static void show_actions(prop_object_iterator_t iter) { 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) { prop_dictionary_get_cstring_nocopy(obj, "transaction", &trans); - prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); - 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, "pkgver", &pkgver); prop_dictionary_get_cstring_nocopy(obj, "architecture", &arch); - if (repoloc && fname && arch) - printf(" %s %s %s", repoloc, fname, arch); + printf("%s %s %s", pkgver, arch, trans); + prop_dictionary_get_cstring_nocopy(obj, "repository", &repoloc); + if (repoloc) + printf(" %s", repoloc); printf("\n"); } diff --git a/bin/xbps-install/xbps-install.8 b/bin/xbps-install/xbps-install.8 index 36b5615b..a6724415 100644 --- a/bin/xbps-install/xbps-install.8 +++ b/bin/xbps-install/xbps-install.8 @@ -1,4 +1,4 @@ -.Dd February 20, 2013 +.Dd March 4, 2013 .Os Void Linux .Dt xbps-install 8 .Sh NAME @@ -95,13 +95,13 @@ architecture. .Sh FILES .Bl -tag -width /var/db/xbps/..plist .It Ar /etc/xbps/xbps.conf -Default XBPS configuration file. +Default configuration file. .It Ar /var/db/xbps/..plist Package metadata properties. -.It Ar /var/db/xbps/pkgdb.plist -XBPS package database. +.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 XBPS cache directory. +Default cache directory to store downloaded binary packages. .Sh SEE ALSO .Xr xbps-create 8 , .Xr xbps-dgraph 8 , diff --git a/bin/xbps-pkgdb/check.c b/bin/xbps-pkgdb/check.c index fc2591f5..86198e8f 100644 --- a/bin/xbps-pkgdb/check.c +++ b/bin/xbps-pkgdb/check.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2012 Juan Romero Pardines. + * Copyright (c) 2009-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,24 +48,34 @@ static void * pkgdb_thread_worker(void *arg) { prop_dictionary_t pkgd; + prop_array_t array; + prop_object_t obj; struct thread_data *thd = arg; - const char *pkgname, *pkgver; + const char *pkgver; + char *pkgname; unsigned int i; int rv; + array = prop_dictionary_all_keys(thd->xhp->pkgdb); + assert(array); + /* process pkgs from start until end */ for (i = thd->start; i < thd->end; i++) { - pkgd = prop_array_get(thd->xhp->pkgdb, i); - prop_dictionary_get_cstring_nocopy(pkgd, "pkgname", &pkgname); + obj = prop_array_get(array, i); + pkgd = prop_dictionary_get_keysym(thd->xhp->pkgdb, obj); prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver); if (thd->xhp->flags & XBPS_FLAG_VERBOSE) printf("Checking %s ...\n", pkgver); + pkgname = xbps_pkg_name(pkgver); + assert(pkgname); rv = check_pkg_integrity(thd->xhp, pkgd, pkgname); + free(pkgname); if (rv != 0) fprintf(stderr, "pkgdb[%d] failed for %s: %s\n", thd->thread_num, pkgver, strerror(rv)); } + prop_object_release(array); return NULL; } @@ -84,7 +94,7 @@ check_pkg_integrity_all(struct xbps_handle *xhp) thd = calloc(maxthreads, sizeof(*thd)); assert(thd); - slicecount = prop_array_count(xhp->pkgdb) / maxthreads; + slicecount = prop_dictionary_count(xhp->pkgdb) / maxthreads; pkgcount = 0; for (i = 0; i < maxthreads; i++) { @@ -92,7 +102,7 @@ check_pkg_integrity_all(struct xbps_handle *xhp) thd[i].xhp = xhp; thd[i].start = pkgcount; if (i + 1 >= maxthreads) - thd[i].end = prop_array_count(xhp->pkgdb); + thd[i].end = prop_dictionary_count(xhp->pkgdb); else thd[i].end = pkgcount + slicecount; pthread_create(&thd[i].thread, NULL, @@ -141,13 +151,8 @@ check_pkg_integrity(struct xbps_handle *xhp, propsd = prop_dictionary_internalize_from_file(buf); free(buf); if (propsd == NULL) { - printf("%s: unexistent metafile, converting to 0.18 " - "format...\n", pkgname); - if ((rv = convert_pkgd_metadir(xhp, opkgd)) != 0) - return rv; - - return 0; - + xbps_error_printf("%s: unexistent metafile!\n", pkgname); + return EINVAL; } else if (prop_dictionary_count(propsd) == 0) { xbps_error_printf("%s: incomplete metadata file.\n", pkgname); prop_object_release(propsd); diff --git a/bin/xbps-pkgdb/convert.c b/bin/xbps-pkgdb/convert.c index 9afbc304..8b01b104 100644 --- a/bin/xbps-pkgdb/convert.c +++ b/bin/xbps-pkgdb/convert.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2012 Juan Romero Pardines. + * Copyright (c) 2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,136 +38,81 @@ #include #include "defs.h" -static prop_data_t -create_script_blob(struct xbps_handle *xhp, - const char *file, - const char *pkgname) -{ - prop_data_t data; - struct stat st; - void *mf; - char *buf; - int fd; - - buf = xbps_xasprintf("%s/metadata/%s/%s", xhp->metadir, pkgname, file); - if ((fd = open(buf, O_RDONLY)) == -1) { - free(buf); - if (errno != ENOENT) - fprintf(stderr, "%s: can't read INSTALL script: %s\n", - pkgname, strerror(errno)); - - return NULL; - } - if (stat(buf, &st) == -1) { - free(buf); - fprintf(stderr, "%s: failed to stat %s script: %s\n", - pkgname, file, strerror(errno)); - return NULL; - } - free(buf); - - mf = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - if (mf == MAP_FAILED) { - close(fd); - fprintf(stderr, "%s: failed to map INSTALL script: %s\n", - pkgname, strerror(errno)); - return NULL; - } - data = prop_data_create_data(mf, st.st_size); - munmap(mf, st.st_size); - - return data; -} - /* - * Converts package metadata format to 0.18. + * Convert pkgdb format to 0.21. */ -int -convert_pkgd_metadir(struct xbps_handle *xhp, prop_dictionary_t pkgd) +static void +pkgdb_format_021(struct xbps_handle *xhp, const char *plist_new) { - prop_dictionary_t filesd, propsd; - prop_array_t array; - prop_data_t data; - const char *pkgname; - char *buf, *sha256, *propsf, *filesf; + prop_array_t array, rdeps; + prop_dictionary_t pkgdb, pkgd; + size_t i; + char *pkgname, *plist; - prop_dictionary_get_cstring_nocopy(pkgd, "pkgname", &pkgname); - - /* Merge XBPS_PKGFILES */ - propsf = xbps_xasprintf("%s/metadata/%s/%s", xhp->metadir, - pkgname, XBPS_PKGPROPS); - propsd = prop_dictionary_internalize_from_zfile(propsf); - assert(propsd); - - filesf = xbps_xasprintf("%s/metadata/%s/%s", xhp->metadir, - pkgname, XBPS_PKGFILES); - filesd = prop_dictionary_internalize_from_zfile(filesf); - assert(filesd); - - array = prop_dictionary_get(filesd, "files"); - if (array && prop_array_count(array)) - prop_dictionary_set(propsd, "files", array); - - array = prop_dictionary_get(filesd, "conf_files"); - if (array && prop_array_count(array)) - prop_dictionary_set(propsd, "conf_files", array); - - array = prop_dictionary_get(filesd, "dirs"); - if (array && prop_array_count(array)) - prop_dictionary_set(propsd, "dirs", array); - - array = prop_dictionary_get(filesd, "links"); - if (array && prop_array_count(array)) - prop_dictionary_set(propsd, "links", array); - - prop_object_release(filesd); - - /* Merge INSTALL script */ - if ((data = create_script_blob(xhp, "INSTALL", pkgname))) { - prop_dictionary_set(propsd, "install-script", data); - prop_object_release(data); + plist = xbps_xasprintf("%s/pkgdb.plist", xhp->metadir); + if (access(plist, R_OK) == -1) { + if (errno == ENOENT) { + /* missing file, no conversion needed */ + free(plist); + return; + } + xbps_error_printf("cannot read %s: %s\n", + plist, strerror(errno)); + exit(EXIT_FAILURE); } - /* Merge REMOVE script */ - if ((data = create_script_blob(xhp, "REMOVE", pkgname))) { - prop_dictionary_set(propsd, "remove-script", data); - prop_object_release(data); + + array = prop_array_internalize_from_zfile(plist); + if (prop_object_type(array) != PROP_TYPE_ARRAY) { + xbps_error_printf("unknown object type for %s\n", + plist, strerror(errno)); + exit(EXIT_FAILURE); } - /* Externalize pkg metaplist */ - buf = xbps_xasprintf("%s/.%s.plist", xhp->metadir, pkgname); - if (!prop_dictionary_externalize_to_file(propsd, buf)) { - fprintf(stderr, "%s: can't externalize plist: %s\n", - pkgname, strerror(errno)); - return -1; + + pkgdb = prop_dictionary_create(); + assert(pkgdb); + + for (i = 0; i < prop_array_count(array); i++) { + pkgd = prop_array_get(array, i); + prop_dictionary_get_cstring(pkgd, "pkgname", &pkgname); + rdeps = prop_dictionary_get(pkgd, "run_depends"); + /* remove unneeded objs */ + prop_dictionary_remove(pkgd, "pkgname"); + prop_dictionary_remove(pkgd, "version"); + if (prop_array_count(rdeps) == 0) + prop_dictionary_remove(pkgd, "run_depends"); + + prop_dictionary_set(pkgdb, pkgname, pkgd); + free(pkgname); } - /* create sha256 hash for pkg plist */ - sha256 = xbps_file_hash(buf); - free(buf); - assert(sha256); - prop_dictionary_set_cstring(pkgd, "metafile-sha256", sha256); - free(sha256); - /* Remove old files/dir */ - if ((remove(propsf) == -1) || (remove(filesf) == -1)) - fprintf(stderr, "%s: failed to remove %s: %s\n", - pkgname, propsf, strerror(errno)); + if (prop_array_count(array) != prop_dictionary_count(pkgdb)) { + xbps_error_printf("failed conversion! unmatched obj count " + "(got %zu, need %zu)\n", prop_dictionary_count(pkgdb), + prop_array_count(array)); + exit(EXIT_FAILURE); + } - buf = xbps_xasprintf("%s/metadata/%s/INSTALL", xhp->metadir, pkgname); - if (access(buf, R_OK) == 0) - remove(buf); - free(buf); + if (!prop_dictionary_externalize_to_file(pkgdb, plist_new)) { + xbps_error_printf("failed to write %s: %s\n", + plist_new, strerror(errno)); + exit(EXIT_FAILURE); + } - buf = xbps_xasprintf("%s/metadata/%s/REMOVE", xhp->metadir, pkgname); - if (access(buf, R_OK) == 0) - remove(buf); - free(buf); + prop_object_release(array); + prop_object_release(pkgdb); + free(plist); - buf = xbps_xasprintf("%s/metadata/%s", xhp->metadir, pkgname); - remove(buf); - free(buf); - - buf = xbps_xasprintf("%s/metadata", xhp->metadir); - remove(buf); - free(buf); - - return 0; + printf("Conversion to 0.21 pkgdb format successfully\n"); +} + +void +convert_pkgdb_format(struct xbps_handle *xhp) +{ + char *plist; + + plist = xbps_xasprintf("%s/%s", xhp->metadir, XBPS_PKGDB); + if ((access(plist, R_OK) == -1) && (errno == ENOENT)) + pkgdb_format_021(xhp, plist); + + free(plist); } diff --git a/bin/xbps-pkgdb/defs.h b/bin/xbps-pkgdb/defs.h index 24102650..5e4d37b7 100644 --- a/bin/xbps-pkgdb/defs.h +++ b/bin/xbps-pkgdb/defs.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2012 Juan Romero Pardines. + * Copyright (c) 2012-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,6 +42,6 @@ CHECK_PKG_DECL(rundeps); CHECK_PKG_DECL(symlinks); /* from convert.c */ -int convert_pkgd_metadir(struct xbps_handle *, prop_dictionary_t); +void convert_pkgdb_format(struct xbps_handle *); #endif /* !_XBPS_PKGDB_DEFS_H_ */ diff --git a/bin/xbps-pkgdb/main.c b/bin/xbps-pkgdb/main.c index 7a42b1ad..c09a9749 100644 --- a/bin/xbps-pkgdb/main.c +++ b/bin/xbps-pkgdb/main.c @@ -46,6 +46,7 @@ usage(bool fail) " -h --help Print usage help\n" " -m --mode Change PKGNAME to automatic or manual mode\n" " -r --rootdir Full path to rootdir\n" + " -u --update Update pkgdb to the latest format\n" " -v --verbose Verbose messages\n" " -V --version Show XBPS version\n"); exit(fail ? EXIT_FAILURE : EXIT_SUCCESS); @@ -73,7 +74,7 @@ change_pkg_instmode(struct xbps_handle *xhp, int main(int argc, char **argv) { - const char *shortopts = "aC:dhm:r:Vv"; + const char *shortopts = "aC:dhm:r:uVv"; const struct option longopts[] = { { "all", no_argument, NULL, 'a' }, { "config", required_argument, NULL, 'C' }, @@ -81,6 +82,7 @@ main(int argc, char **argv) { "help", no_argument, NULL, 'h' }, { "mode", required_argument, NULL, 'm' }, { "rootdir", required_argument, NULL, 'r' }, + { "update", no_argument, NULL, 'u' }, { "verbose", no_argument, NULL, 'v' }, { "version", no_argument, NULL, 'V' }, { NULL, 0, NULL, 0 } @@ -88,7 +90,7 @@ main(int argc, char **argv) struct xbps_handle xh; const char *conffile = NULL, *rootdir = NULL, *instmode = NULL; int c, i, rv, flags = 0; - bool all = false; + bool update_format = false, all = false; while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { switch (c) { @@ -110,6 +112,9 @@ main(int argc, char **argv) case 'r': rootdir = optarg; break; + case 'u': + update_format = true; + break; case 'v': flags |= XBPS_FLAG_VERBOSE; break; @@ -122,7 +127,7 @@ main(int argc, char **argv) /* NOTREACHED */ } } - if (!all && (argc == optind)) + if (!update_format && !all && (argc == optind)) usage(true); memset(&xh, 0, sizeof(xh)); @@ -136,7 +141,9 @@ main(int argc, char **argv) exit(EXIT_FAILURE); } - if (instmode) { + if (update_format) + convert_pkgdb_format(&xh); + else if (instmode) { if ((strcmp(instmode, "auto")) && (strcmp(instmode, "manual"))) usage(true); diff --git a/bin/xbps-pkgdb/xbps-pkgdb.8 b/bin/xbps-pkgdb/xbps-pkgdb.8 index ce89577d..23dcc938 100644 --- a/bin/xbps-pkgdb/xbps-pkgdb.8 +++ b/bin/xbps-pkgdb/xbps-pkgdb.8 @@ -1,4 +1,4 @@ -.Dd February 20, 2013 +.Dd March 4, 2013 .Os Void Linux .Dt xbps-pkgdb 8 .Sh NAME @@ -13,7 +13,8 @@ The .Nm utility can check/fix issues and modify the package database (pkgdb). It's able to check for missing dependencies, modified files and symlinks, -and more errors that have been fixed in newer versions of xbps. +and more errors that have been fixed in newer versions of xbps. A mode to update +the format to the latest version is also available. This is the list of things that .Nm currently does: @@ -29,6 +30,8 @@ Checks that all required dependencies for a package are resolved. .It Sy OBSOLETE METADATA CHECK Checks that the package database does not contain obsolete data from previous XBPS versions and removes them if found. +.It Sy FORMAT CONVERSION +Updates the pkgdb format to the latest version. .Sh OPTIONS .Bl -tag -width -x .It Fl a, Fl -all @@ -45,14 +48,23 @@ Switches to the specified installation mode: automatic or manual mode. .It Fl r, Fl -rootdir Ar dir Specifies a full path for the target root directory. +.It Fl u, Fl -update +Updates the pkgdb format to the latest version making the necessary conversions +automatically. Usually this is needed only in rare circumstances. .It Fl v, Fl -verbose Enables verbose messages. .It Fl V, Fl -version Shows the XBPS version. .Sh FILES -.Bl -tag -width xxxxxxxxxxxxxxxxxxxx +.Bl -tag -width /var/db/xbps/..plist .It Ar /etc/xbps/xbps.conf -Default XBPS configuration file. +Default configuration file. +.It Ar /var/db/xbps/..plist +Package metadata properties. +.It Ar /var/db/xbps/pkgdb-0.21.plist +Default package database (0.21 format). Keeps track of installed packages and properties. +.It Ar /var/cache/xbps +Default cache directory to store downloaded binary packages. .Sh SEE ALSO .Xr xbps-create 8 , .Xr xbps-dgraph 8 , diff --git a/bin/xbps-query/defs.h b/bin/xbps-query/defs.h index cd0cffea..a6fc41b8 100644 --- a/bin/xbps-query/defs.h +++ b/bin/xbps-query/defs.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2012 Juan Romero Pardines. + * Copyright (c) 2009-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,9 +33,9 @@ #endif /* 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 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 *); /* from show-info-files.c */ @@ -56,8 +56,6 @@ int repo_ownedby(struct xbps_handle *, int, char **); /* From list.c */ 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); int list_pkgs_in_dict(struct xbps_handle *, prop_object_t, void *, bool *); diff --git a/bin/xbps-query/list.c b/bin/xbps-query/list.c index b11a25dd..f92a06be 100644 --- a/bin/xbps-query/list.c +++ b/bin/xbps-query/list.c @@ -241,19 +241,3 @@ find_longest_pkgver(struct xbps_handle *xhp, prop_object_t o) 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; -} diff --git a/bin/xbps-query/main.c b/bin/xbps-query/main.c index d84af8e8..dd29d324 100644 --- a/bin/xbps-query/main.c +++ b/bin/xbps-query/main.c @@ -56,7 +56,7 @@ usage(bool fail) " -s --search PATTERN(s) Search for packages matching PATTERN(s)\n" " -f --files Show files 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"); exit(fail ? EXIT_FAILURE : EXIT_SUCCESS); @@ -90,16 +90,16 @@ main(int argc, char **argv) }; struct xbps_handle xh; 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_manual, show_prop, show_files, show_deps, show_rdeps; - bool show, search, repo_mode, opmode; + bool list_manual, show_prop, show_files, show_rdeps; + bool show, search, repo_mode, opmode, fulldeptree; rootdir = cachedir = conffile = defrepo = props = NULL; flags = rv = c = 0; list_pkgs = list_repos = orphans = search = own = false; list_manual = show_prop = show_files = false; - show = show_deps = show_rdeps = false; + show = show_rdeps = fulldeptree = false; repo_mode = opmode = false; while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { @@ -157,7 +157,8 @@ main(int argc, char **argv) printf("%s\n", XBPS_RELVER); exit(EXIT_SUCCESS); case 'x': - show_deps = opmode = true; + show_deps++; + opmode = true; break; case 'X': show_rdeps = opmode = true; @@ -234,10 +235,13 @@ main(int argc, char **argv) } else if (show_deps) { /* show-deps mode */ + if (show_deps > 1) + fulldeptree = true; + if (repo_mode) - rv = repo_show_pkg_deps(&xh, argv[optind]); + rv = repo_show_pkg_deps(&xh, argv[optind], fulldeptree); else - rv = show_pkg_deps(&xh, argv[optind]); + rv = show_pkg_deps(&xh, argv[optind], fulldeptree); } else if (show_rdeps) { /* show-rdeps mode */ diff --git a/bin/xbps-query/show-deps.c b/bin/xbps-query/show-deps.c index 896dc42a..7603179c 100644 --- a/bin/xbps-query/show-deps.c +++ b/bin/xbps-query/show-deps.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2012 Juan Romero Pardines. + * Copyright (c) 2009-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,22 +33,64 @@ #include #include "defs.h" -int -show_pkg_deps(struct xbps_handle *xhp, const char *pkgname) +static void +print_rdeps(struct xbps_handle *xhp, prop_array_t rdeps, + bool full, bool repo, bool origin, int *indent) { - prop_dictionary_t propsd; - int rv = 0; + prop_array_t currdeps; + 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); - if (propsd == NULL) + for (i = 0; i < prop_array_count(rdeps); i++) { + 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; - rv = xbps_callback_array_iter_in_dict(xhp, propsd, "run_depends", - list_strings_sep_in_array, NULL); + rdeps = prop_dictionary_get(pkgd, "run_depends"); + if (rdeps != NULL) + print_rdeps(xhp, rdeps, full, false, true, &indent); - return rv; + return 0; } int @@ -58,8 +100,7 @@ show_pkg_revdeps(struct xbps_handle *xhp, const char *pkg) const char *pkgdep; size_t i; - reqby = xbps_pkgdb_get_pkg_revdeps(xhp, pkg); - if (reqby) { + if ((reqby = xbps_pkgdb_get_pkg_revdeps(xhp, pkg)) != NULL) { for (i = 0; i < prop_array_count(reqby); i++) { prop_array_get_cstring_nocopy(reqby, i, &pkgdep); printf("%s\n", pkgdep); @@ -69,16 +110,19 @@ show_pkg_revdeps(struct xbps_handle *xhp, const char *pkg) } 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; + int indent = 0; if (((pkgd = xbps_rpool_get_pkg(xhp, pattern)) == NULL) && ((pkgd = xbps_rpool_get_virtualpkg(xhp, pattern)) == NULL)) return errno; - (void)xbps_callback_array_iter_in_dict(xhp, pkgd, - "run_depends", list_strings_sep_in_array, NULL); + rdeps = prop_dictionary_get(pkgd, "run_depends"); + if (rdeps != NULL) + print_rdeps(xhp, rdeps, full, true, true, &indent); return 0; } diff --git a/bin/xbps-query/show-info-files.c b/bin/xbps-query/show-info-files.c index a0f3bfe0..34048d0b 100644 --- a/bin/xbps-query/show-info-files.c +++ b/bin/xbps-query/show-info-files.c @@ -295,8 +295,7 @@ repo_show_pkg_info(struct xbps_handle *xhp, { prop_dictionary_t pkgd; - if (((pkgd = xbps_rpool_get_pkg(xhp, pattern)) == NULL) && - ((pkgd = xbps_rpool_get_virtualpkg(xhp, pattern)) == NULL)) + if ((pkgd = xbps_rpool_get_pkg_plist(xhp, pattern, "./props.plist")) == NULL) return errno; if (option) diff --git a/bin/xbps-query/xbps-query.8 b/bin/xbps-query/xbps-query.8 index 306dcbf8..66df8775 100644 --- a/bin/xbps-query/xbps-query.8 +++ b/bin/xbps-query/xbps-query.8 @@ -1,4 +1,4 @@ -.Dd February 20, 2013 +.Dd March 4, 2013 .Os Void Linux .Dt xbps-query 8 .Sh NAME @@ -139,6 +139,7 @@ Multiple properties can be specified by delimiting them with commas. .It Fl x, Fl -deps Ar PKG Show the required dependencies for .Ar PKG . +Only direct dependencies are shown. To see a full dependency tree set it twice. .It Fl X, Fl -revdeps Ar PKG Show the reverse dependencies for .Ar PKG . @@ -152,13 +153,13 @@ architecture. .Sh FILES .Bl -tag -width /var/db/xbps/..plist .It Ar /etc/xbps/xbps.conf -Default XBPS configuration file. +Default configuration file. .It Ar /var/db/xbps/..plist Package metadata properties. -.It Ar /var/db/xbps/pkgdb.plist -XBPS package database. +.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 XBPS cache directory. +Default cache directory to store downloaded binary packages. .Sh SEE ALSO .Xr xbps-create 8 , .Xr xbps-dgraph 8 , diff --git a/bin/xbps-reconfigure/main.c b/bin/xbps-reconfigure/main.c index 2019f372..ba20a29a 100644 --- a/bin/xbps-reconfigure/main.c +++ b/bin/xbps-reconfigure/main.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2012 Juan Romero Pardines. + * Copyright (c) 2012-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -65,7 +65,7 @@ state_cb(struct xbps_state_cb_data *xscd, void *cbd) switch (xscd->state) { /* notifications */ case XBPS_STATE_CONFIGURE: - printf("%s-%s: configuring ...\n", xscd->arg0, xscd->arg1); + printf("%s: configuring ...\n", xscd->arg); break; /* errors */ case XBPS_STATE_CONFIGURE_FAIL: @@ -75,7 +75,7 @@ state_cb(struct xbps_state_cb_data *xscd, void *cbd) break; default: xbps_dbg_printf(xscd->xhp, - "unknown state %d\n", xscd->state); + "%s: unknown state %d\n", xscd->arg, xscd->state); break; } } diff --git a/bin/xbps-reconfigure/xbps-reconfigure.8 b/bin/xbps-reconfigure/xbps-reconfigure.8 index 9c464102..09d629da 100644 --- a/bin/xbps-reconfigure/xbps-reconfigure.8 +++ b/bin/xbps-reconfigure/xbps-reconfigure.8 @@ -1,4 +1,4 @@ -.Dd November 6, 2012 +.Dd March 4, 2013 .Os Void Linux .Dt xbps-reconfigure 8 .Sh NAME @@ -48,6 +48,16 @@ Specifies a full path for the target root directory. Enables verbose messages. .It Fl V, Fl -version Shows the XBPS version. +.Sh FILES +.Bl -tag -width /var/db/xbps/..plist +.It Ar /etc/xbps/xbps.conf +Default configuration file. +.It Ar /var/db/xbps/..plist +Package metadata properties. +.It Ar /var/db/xbps/pkgdb-0.21.plist +Default package database (0.21 format). Keeps track of installed packages and properties. +.It Ar /var/cache/xbps +Default cache directory to store downloaded binary packages. .Sh SEE ALSO .Xr xbps-create 8 , .Xr xbps-dgraph 8 , diff --git a/bin/xbps-remove/main.c b/bin/xbps-remove/main.c index c6e6744d..603fefe7 100644 --- a/bin/xbps-remove/main.c +++ b/bin/xbps-remove/main.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2008-2012 Juan Romero Pardines. + * Copyright (c) 2008-2013 Juan Romero Pardines. * All rights reserved. * * 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: break; case XBPS_STATE_REMOVE: - printf("Removing `%s-%s' ...\n", xscd->arg0, xscd->arg1); + printf("Removing `%s' ...\n", xscd->arg); break; /* success */ case XBPS_STATE_REMOVE_FILE: @@ -92,11 +92,10 @@ state_cb_rm(struct xbps_state_cb_data *xscd, void *cbdata) } break; case XBPS_STATE_REMOVE_DONE: - printf("Removed `%s-%s' successfully.\n", - xscd->arg0, xscd->arg1); + printf("Removed `%s' successfully.\n", xscd->arg); if (syslog_enabled) - syslog(LOG_NOTICE, "Removed `%s-%s' successfully " - "(rootdir: %s).", xscd->arg0, xscd->arg1, + syslog(LOG_NOTICE, "Removed `%s' successfully " + "(rootdir: %s).", xscd->arg, xscd->xhp->rootdir); break; /* errors */ @@ -119,8 +118,7 @@ state_cb_rm(struct xbps_state_cb_data *xscd, void *cbdata) break; default: xbps_dbg_printf(xscd->xhp, - "%s-%s: unknown state %d\n", - xscd->arg0, xscd->arg1, xscd->state); + "%s: unknown state %d\n", xscd->arg, xscd->state); break; } } diff --git a/bin/xbps-remove/xbps-remove.8 b/bin/xbps-remove/xbps-remove.8 index 0c0c919d..5889b042 100644 --- a/bin/xbps-remove/xbps-remove.8 +++ b/bin/xbps-remove/xbps-remove.8 @@ -1,4 +1,4 @@ -.Dd November 21, 2012 +.Dd March 4, 2013 .Os Void Linux .Dt xbps-remove 8 .Sh NAME @@ -87,13 +87,13 @@ Shows the XBPS version. .Sh FILES .Bl -tag -width /var/db/xbps/..plist .It Ar /etc/xbps/xbps.conf -Default XBPS configuration file. +Default configuration file. .It Ar /var/db/xbps/..plist Package metadata properties. -.It Ar /var/db/xbps/pkgdb.plist -XBPS package database. +.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 XBPS cache directory. +Default cache directory to store downloaded binary packages. .Sh SEE ALSO .Xr xbps-create 8 , .Xr xbps-dgraph 8 , diff --git a/bin/xbps-rindex/index-add.c b/bin/xbps-rindex/index-add.c index ac1aa6c2..f5d3a502 100644 --- a/bin/xbps-rindex/index-add.c +++ b/bin/xbps-rindex/index-add.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2012 Juan Romero Pardines. + * Copyright (c) 2012-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,9 +48,8 @@ index_add(struct xbps_handle *xhp, int argc, char **argv) prop_dictionary_t filespkgd; prop_object_t obj, fileobj; struct stat st; - const char *pkgname, *version, *regver, *oldfilen, *oldpkgver; - const char *pkgver, *arch, *oldarch; - char *sha256, *filen, *repodir, *buf; + const char *oldpkgver, *arch, *oldarch; + char *pkgver, *pkgname, *sha256, *repodir, *buf; char *tmpfilen, *tmprepodir, *plist, *plistf; size_t x; int i, ret = 0; @@ -100,7 +99,6 @@ index_add(struct xbps_handle *xhp, int argc, char **argv) if ((tmpfilen = strdup(argv[i])) == NULL) return ENOMEM; - filen = basename(tmpfilen); /* * 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", &arch); - prop_dictionary_get_cstring_nocopy(newpkgd, "pkgver", &pkgver); + prop_dictionary_get_cstring(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); + pkgname = xbps_pkg_name(pkgver); + assert(pkgname); /* * Check if this package exists already in the index, but first * 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); if (curpkgd == NULL) { - if (errno && errno != ENOENT) + if (errno && errno != ENOENT) { + free(pkgver); + free(pkgname); return errno; + } } else { - prop_dictionary_get_cstring_nocopy(curpkgd, - "filename", &oldfilen); prop_dictionary_get_cstring_nocopy(curpkgd, "pkgver", &oldpkgver); prop_dictionary_get_cstring_nocopy(curpkgd, "architecture", &oldarch); - prop_dictionary_get_cstring_nocopy(curpkgd, - "version", ®ver); - ret = xbps_cmpver(version, regver); + ret = xbps_cmpver(pkgver, oldpkgver); if (ret <= 0) { /* Same version or index version greater */ - fprintf(stderr, "index: skipping `%s-%s' " + fprintf(stderr, "index: skipping `%s' " "(%s), already registered.\n", - pkgname, version, arch); + pkgver, arch); prop_object_release(newpkgd); free(tmpfilen); + free(pkgver); + free(pkgname); continue; } /* @@ -167,32 +164,57 @@ index_add(struct xbps_handle *xhp, int argc, char **argv) * We have the dictionary now, add the required * 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; - - if ((sha256 = xbps_file_hash(argv[i])) == NULL) - return errno; - + } if (!prop_dictionary_set_cstring(newpkgd, "filename-sha256", - sha256)) + sha256)) { + free(pkgver); + free(pkgname); return errno; + } free(sha256); - if (stat(argv[i], &st) == -1) + if (stat(argv[i], &st) == -1) { + free(pkgver); + free(pkgname); return errno; + } if (!prop_dictionary_set_uint64(newpkgd, "filename-size", (uint64_t)st.st_size)) { + free(pkgver); + free(pkgname); 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. */ - if (!prop_dictionary_set(idx, pkgname, newpkgd)) + if (!prop_dictionary_set(idx, pkgname, newpkgd)) { + free(pkgname); return EINVAL; + } flush = true; - printf("index: added `%s-%s' (%s).\n", pkgname, version, arch); + printf("index: added `%s' (%s).\n", pkgver, arch); free(tmpfilen); /* * Add new pkg dictionary into the index-files. @@ -200,8 +222,11 @@ index_add(struct xbps_handle *xhp, int argc, char **argv) found = false; newpkgfilesd = xbps_get_pkg_plist_from_binpkg(argv[i], "./files.plist"); - if (newpkgfilesd == NULL) + if (newpkgfilesd == NULL) { + free(pkgver); + free(pkgname); return EINVAL; + } /* Find out if binary pkg stored in index contain any file */ pkg_cffiles = prop_dictionary_get(newpkgfilesd, "conf_files"); @@ -226,6 +251,8 @@ index_add(struct xbps_handle *xhp, int argc, char **argv) if (!found) { prop_object_release(newpkgfilesd); prop_object_release(newpkgd); + free(pkgver); + free(pkgname); continue; } /* 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); files_flush = true; prop_object_release(newpkgd); + free(pkgver); + free(pkgname); } if (flush && !prop_dictionary_externalize_to_zfile(idx, plist)) { diff --git a/bin/xbps-rindex/index-clean.c b/bin/xbps-rindex/index-clean.c index eeaba819..d471fe4c 100644 --- a/bin/xbps-rindex/index-clean.c +++ b/bin/xbps-rindex/index-clean.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2012 Juan Romero Pardines. + * Copyright (c) 2012-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -54,7 +54,8 @@ cleaner_thread(void *arg) prop_dictionary_t pkgd; prop_array_t array; struct thread_data *thd = arg; - const char *pkgver, *filen, *sha256; + char *filen; + const char *pkgver, *arch, *sha256; unsigned int i; /* process pkgs from start until end */ @@ -63,8 +64,9 @@ cleaner_thread(void *arg) for (i = thd->start; i < thd->end; i++) { obj = prop_array_get(array, i); 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); + filen = xbps_xasprintf("%s.%s.xbps"); xbps_dbg_printf(thd->xhp, "thread[%d] checking %s\n", thd->thread_num, pkgver); if (access(filen, R_OK) == -1) { @@ -73,6 +75,7 @@ cleaner_thread(void *arg) * broken or simply unexistent; either way, remove it. */ prop_array_add_cstring_nocopy(thd->result, pkgver); + free(filen); continue; } /* @@ -82,6 +85,7 @@ cleaner_thread(void *arg) "filename-sha256", &sha256); if (xbps_file_hash_check(filen, sha256) != 0) prop_array_add_cstring_nocopy(thd->result, pkgver); + free(filen); } prop_object_release(array); diff --git a/bin/xbps-rindex/remove-obsoletes.c b/bin/xbps-rindex/remove-obsoletes.c index 426340f3..5796872a 100644 --- a/bin/xbps-rindex/remove-obsoletes.c +++ b/bin/xbps-rindex/remove-obsoletes.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2012 Juan Romero Pardines. + * Copyright (c) 2012-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/include/xbps_api.h.in b/include/xbps_api.h.in index 6ab37547..27fecb3b 100644 --- a/include/xbps_api.h.in +++ b/include/xbps_api.h.in @@ -46,9 +46,9 @@ * @def XBPS_PKGINDEX_VERSION * 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 #define XBPS_VERSION "UNSET" @@ -81,7 +81,7 @@ * @def XBPS_PKGDB * Filename for the package database. */ -#define XBPS_PKGDB "pkgdb.plist" +#define XBPS_PKGDB "pkgdb-0.21.plist" /** * @def XBPS_PKGPROPS @@ -217,6 +217,7 @@ extern "C" { * install, update, remove and replace. * - XBPS_STATE_TRANS_CONFIGURE: transaction is configuring all * 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_VERIFY: a binary package is being verified. * - XBPS_STATE_REMOVE: a package is being removed. @@ -290,7 +291,8 @@ typedef enum xbps_state { XBPS_STATE_UNPACK_FAIL, XBPS_STATE_REGISTER_FAIL, XBPS_STATE_UNREGISTER_FAIL, - XBPS_STATE_REPOSYNC_FAIL + XBPS_STATE_REPOSYNC_FAIL, + XBPS_STATE_XBPS_UPDATE } xbps_state_t; /** @@ -318,19 +320,12 @@ struct xbps_state_cb_data { */ 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. */ - const char *arg0; - /** - * @var arg1 - * - * State string argument 1. String set on this - * variable may change depending on \a state. - */ - const char *arg1; + const char *arg; /** * @var err * @@ -480,10 +475,10 @@ struct xbps_handle { /** * @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. */ - prop_array_t pkgdb; + prop_dictionary_t pkgdb; /** * @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, 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 * 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] blob The buffer pointer where the data is stored. * @param[in] blobsiz The size of the buffer data. - * @param[in] pkgname The package name associated. - * @param[in] version The package version associated. + * @param[in] pkgver The package name/version associated. * @param[in] action The action to execute on the temporary file. * @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, const void *blob, const size_t blobsiz, - const char *pkgname, - const char *version, + const char *pkgver, const char *action, 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 - * XBPS_PKGFILES 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: - * files, dirs, links and conf_files. - * @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 */ /*@{*/ @@ -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. * * @param[in] xhp The pointer to an xbps_handle struct. - * @param[in] pkgname Package name. - * @param[in] version Package version. + * @param[in] pkgver Package name/version to match. * @param[in] state Package state to be set. * * @return 0 on success, otherwise an errno value. */ int xbps_set_pkg_state_installed(struct xbps_handle *xhp, - const char *pkgname, - const char *version, + const char *pkgver, pkg_state_t state); /** diff --git a/include/xbps_api_impl.h b/include/xbps_api_impl.h index 08987d16..0203cf4d 100644 --- a/include/xbps_api_impl.h +++ b/include/xbps_api_impl.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2010-2012 Juan Romero Pardines. + * Copyright (c) 2010-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -70,6 +70,9 @@ #define archive_read_finish(x) \ archive_read_free(x) +#define archive_write_finish(x) \ + archive_write_free(x) + #define archive_compression_name(x) \ archive_filter_name(x, 0) @@ -144,7 +147,6 @@ int HIDDEN xbps_entry_install_conf_file(struct xbps_handle *, prop_dictionary_t, struct archive_entry *, const char *, - const char *, const char *); /** * @private @@ -156,7 +158,7 @@ prop_dictionary_t HIDDEN /** * @private - * From lib/rpool_pkgdeps.c + * From lib/rindex_pkgdeps.c */ int HIDDEN xbps_repository_find_deps(struct xbps_handle *, 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 xbps_find_virtualpkg_in_array(struct xbps_handle *, prop_array_t, 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 * 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, const char *, bool, bool, bool); void HIDDEN xbps_set_cb_state(struct xbps_handle *, xbps_state_t, int, - const char *, const char *, const char *, ...); + const char *, const char *, ...); /** * @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 *); +/** + * @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 * From lib/package_conflicts.c @@ -231,7 +251,7 @@ void HIDDEN xbps_pkg_find_conflicts(struct xbps_handle *, prop_dictionary_t); /** * @private - * From lib/rindex_get.c + * From lib/plist_find.c */ const char HIDDEN *vpkg_user_conf(struct xbps_handle *, const char *, bool); diff --git a/lib/cb_util.c b/lib/cb_util.c index cff1cdac..a42f0f36 100644 --- a/lib/cb_util.c +++ b/lib/cb_util.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2011-2012 Juan Romero Pardines. + * Copyright (c) 2011-2013 Juan Romero Pardines. * All rights reserved. * * 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_state_t state, int err, - const char *arg0, - const char *arg1, + const char *arg, const char *fmt, ...) { @@ -90,8 +89,7 @@ xbps_set_cb_state(struct xbps_handle *xhp, xscd.xhp = xhp; xscd.state = state; xscd.err = err; - xscd.arg0 = arg0; - xscd.arg1 = arg1; + xscd.arg = arg; if (fmt != NULL) { va_start(va, fmt); retval = vasprintf(&buf, fmt, va); diff --git a/lib/package_config_files.c b/lib/package_config_files.c index 57089d15..7434935b 100644 --- a/lib/package_config_files.c +++ b/lib/package_config_files.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2012 Juan Romero Pardines. + * Copyright (c) 2009-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -64,8 +64,7 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp, prop_dictionary_t filesd, struct archive_entry *entry, const char *entry_pname, - const char *pkgname, - const char *version) + const char *pkgver) { prop_dictionary_t forigd; 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(entry != NULL); assert(entry_pname != NULL); - assert(pkgname != NULL); - assert(version != NULL); + assert(pkgver != NULL); iter = xbps_array_iter_from_dict(filesd, "conf_files"); if (iter == NULL) @@ -88,13 +86,13 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp, * Get original hash for the file from current * installed package. */ - xbps_dbg_printf(xhp, "%s-%s: processing conf_file %s\n", - pkgname, version, entry_pname); + xbps_dbg_printf(xhp, "%s: processing conf_file %s\n", + pkgver, entry_pname); - forigd = xbps_pkgdb_get_pkg_metadata(xhp, pkgname); + forigd = xbps_pkgdb_get_pkg_metadata(xhp, pkgver); if (forigd == NULL) { - xbps_dbg_printf(xhp, "%s-%s: conf_file %s not currently " - "installed\n", pkgname, version, entry_pname); + xbps_dbg_printf(xhp, "%s: conf_file %s not currently " + "installed\n", pkgver, entry_pname); rv = 1; goto out; } @@ -120,8 +118,8 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp, * First case: original hash not found, install new file. */ if (sha256_orig == NULL) { - xbps_dbg_printf(xhp, "%s-%s: conf_file %s not installed\n", - pkgname, version, entry_pname); + xbps_dbg_printf(xhp, "%s: conf_file %s not installed\n", + pkgver, entry_pname); rv = 1; goto out; } @@ -145,9 +143,8 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp, /* * File not installed, install new one. */ - xbps_dbg_printf(xhp, "%s-%s: conf_file %s not " - "installed\n", pkgname, version, - entry_pname); + xbps_dbg_printf(xhp, "%s: conf_file %s not " + "installed\n", pkgver, entry_pname); rv = 1; break; } else { @@ -163,9 +160,8 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp, if ((strcmp(sha256_orig, sha256_cur) == 0) && (strcmp(sha256_orig, sha256_new) == 0) && (strcmp(sha256_cur, sha256_new) == 0)) { - xbps_dbg_printf(xhp, "%s-%s: conf_file %s orig = X, " - "cur = X, new = X\n", pkgname, version, - entry_pname); + xbps_dbg_printf(xhp, "%s: conf_file %s orig = X, " + "cur = X, new = X\n", pkgver, entry_pname); rv = 0; break; /* @@ -177,9 +173,9 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp, (strcmp(sha256_orig, sha256_new)) && (strcmp(sha256_cur, sha256_new))) { xbps_set_cb_state(xhp, XBPS_STATE_CONFIG_FILE, - 0, pkgname, version, + 0, pkgver, "Updating configuration file `%s' provided " - "by version `%s'.", cffile, version); + "by `%s'.", cffile, pkgver); rv = 1; break; /* @@ -193,7 +189,7 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp, (strcmp(sha256_cur, sha256_new)) && (strcmp(sha256_orig, sha256_cur))) { xbps_set_cb_state(xhp, XBPS_STATE_CONFIG_FILE, - 0, pkgname, version, + 0, pkgver, "Keeping modified configuration file `%s'.", cffile); rv = 0; @@ -207,9 +203,8 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp, } else if ((strcmp(sha256_cur, sha256_new) == 0) && (strcmp(sha256_orig, sha256_new)) && (strcmp(sha256_orig, sha256_cur))) { - xbps_dbg_printf(xhp, "%s-%s: conf_file %s orig = X, " - "cur = Y, new = Y\n", pkgname, version, - entry_pname); + xbps_dbg_printf(xhp, "%s: conf_file %s orig = X, " + "cur = Y, new = Y\n", pkgver, entry_pname); rv = 0; break; /* @@ -220,10 +215,14 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp, } else if ((strcmp(sha256_orig, sha256_cur)) && (strcmp(sha256_cur, sha256_new)) && (strcmp(sha256_orig, sha256_new))) { + const char *version; + + version = xbps_pkg_version(pkgver); + assert(version); buf = xbps_xasprintf(".%s.new-%s", cffile, version); xbps_set_cb_state(xhp, XBPS_STATE_CONFIG_FILE, - 0, pkgname, version, + 0, pkgver, version, "Installing new configuration file to " "`%s.new-%s'.", cffile, version); archive_entry_set_pathname(entry, buf); @@ -241,8 +240,8 @@ out: prop_object_iterator_release(iter); - xbps_dbg_printf(xhp, "%s-%s: conf_file %s returned %d\n", - pkgname, version, entry_pname, rv); + xbps_dbg_printf(xhp, "%s: conf_file %s returned %d\n", + pkgver, entry_pname, rv); return rv; } diff --git a/lib/package_configure.c b/lib/package_configure.c index 08683e90..21040595 100644 --- a/lib/package_configure.c +++ b/lib/package_configure.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2012 Juan Romero Pardines. + * Copyright (c) 2009-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -43,28 +43,30 @@ * * @note * 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. */ int xbps_configure_packages(struct xbps_handle *xhp, bool flush) { + prop_dictionary_t pkgd; prop_object_t obj; prop_object_iterator_t iter; - const char *pkgname; + const char *pkgver; int rv; if ((rv = xbps_pkgdb_init(xhp)) != 0) return rv; - iter = prop_array_iterator(xhp->pkgdb); + iter = prop_dictionary_iterator(xhp->pkgdb); assert(iter); while ((obj = prop_object_iterator_next(iter))) { - prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); - rv = xbps_configure_pkg(xhp, pkgname, true, false, false); + pkgd = prop_dictionary_get_keysym(xhp->pkgdb, obj); + prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver); + rv = xbps_configure_pkg(xhp, pkgver, true, false, false); if (rv != 0) { xbps_dbg_printf(xhp, "%s: failed to configure %s: %s\n", - __func__, pkgname, strerror(rv)); + __func__, pkgver, strerror(rv)); break; } } @@ -78,32 +80,27 @@ xbps_configure_packages(struct xbps_handle *xhp, bool flush) int xbps_configure_pkg(struct xbps_handle *xhp, - const char *pkgname, + const char *pkgver, bool check_state, bool update, bool flush) { prop_dictionary_t pkgd, pkgmetad; - const char *version, *pkgver; - char *plist; + char *pkgname, *plist; int rv = 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) 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); - 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) { xbps_dbg_printf(xhp, "%s: [configure] failed to get " - "pkg state: %s\n", pkgname, strerror(rv)); - prop_object_release(pkgd); + "pkg state: %s\n", pkgver, strerror(rv)); return EINVAL; } @@ -115,10 +112,13 @@ xbps_configure_pkg(struct xbps_handle *xhp, 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 */ + pkgname = xbps_pkg_name(pkgver); + assert(pkgname); plist = xbps_xasprintf("%s/.%s.plist", xhp->metadir, pkgname); + free(pkgname); pkgmetad = prop_dictionary_internalize_from_file(plist); free(plist); assert(pkgmetad); @@ -126,7 +126,7 @@ xbps_configure_pkg(struct xbps_handle *xhp, rv = xbps_pkg_exec_script(xhp, pkgmetad, "install-script", "post", update); if (rv != 0) { xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE_FAIL, - errno, pkgname, version, + errno, pkgver, "%s: [configure] INSTALL script failed to execute " "the post ACTION: %s", pkgver, strerror(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); if (rv != 0) { xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE_FAIL, rv, - pkgname, version, - "%s: [configure] failed to set state to installed: %s", + pkgver, "%s: [configure] failed to set state to installed: %s", pkgver, strerror(rv)); } if (flush) { if ((rv = xbps_pkgdb_update(xhp, true)) != 0) { xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE_FAIL, rv, - pkgname, version, - "%s: [configure] failed to update pkgdb: %s\n", + pkgver, "%s: [configure] failed to update pkgdb: %s\n", pkgver, strerror(rv)); } } diff --git a/lib/package_register.c b/lib/package_register.c index 3ab6dd97..b0c2a36b 100644 --- a/lib/package_register.c +++ b/lib/package_register.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2008-2012 Juan Romero Pardines. + * Copyright (c) 2008-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,68 +31,48 @@ #include "xbps_api_impl.h" -/** - * @file lib/package_register.c - * @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) +int HIDDEN +xbps_register_pkg(struct xbps_handle *xhp, prop_dictionary_t pkgrd) { prop_dictionary_t pkgd; prop_array_t provides, rundeps; char outstr[64]; time_t t; struct tm *tmp; - const char *pkgname, *version, *desc, *pkgver; - char *buf, *sha256; + const char *desc, *pkgver; + char *pkgname = NULL, *buf, *sha256; int rv = 0; bool autoinst = false; 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, "short_desc", &desc); prop_dictionary_get_bool(pkgrd, "automatic-install", &autoinst); provides = prop_dictionary_get(pkgrd, "provides"); 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(desc != NULL); - pkgd = xbps_pkgdb_get_pkg(xhp, pkgname); + pkgd = xbps_pkgdb_get_pkg(xhp, pkgver); if (pkgd == NULL) { rv = ENOENT; 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, "pkgver", pkgver)) { xbps_dbg_printf(xhp, "%s: invalid pkgver for %s\n", - __func__, pkgname); + __func__, pkgver); rv = EINVAL; goto out; } if (!prop_dictionary_set_cstring_nocopy(pkgd, "short_desc", desc)) { xbps_dbg_printf(xhp, "%s: invalid short_desc for %s\n", - __func__, pkgname); + __func__, pkgver); rv = EINVAL; 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, "automatic-install", autoinst)) { xbps_dbg_printf(xhp, "%s: invalid autoinst for %s\n", - __func__, pkgname); + __func__, pkgver); rv = EINVAL; goto out; } @@ -115,34 +95,31 @@ xbps_register_pkg(struct xbps_handle *xhp, prop_dictionary_t pkgrd, bool flush) t = time(NULL); if ((tmp = localtime(&t)) == NULL) { xbps_dbg_printf(xhp, "%s: localtime failed: %s\n", - pkgname, strerror(errno)); + pkgver, strerror(errno)); rv = EINVAL; goto out; } if (strftime(outstr, sizeof(outstr)-1, "%F %R %Z", tmp) == 0) { xbps_dbg_printf(xhp, "%s: strftime failed: %s\n", - pkgname, strerror(errno)); + pkgver, strerror(errno)); rv = EINVAL; goto out; } 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; goto out; } if (provides && !prop_dictionary_set(pkgd, "provides", provides)) { xbps_dbg_printf(xhp, "%s: failed to set provides for %s\n", - __func__, pkgname); + __func__, pkgver); rv = EINVAL; goto out; } - if (rundeps == NULL) - rundeps = prop_array_create(); - - if (!prop_dictionary_set(pkgd, "run_depends", rundeps)) { + if (rundeps && !prop_dictionary_set(pkgd, "run_depends", rundeps)) { xbps_dbg_printf(xhp, "%s: failed to set rundeps for %s\n", - __func__, pkgname); + __func__, pkgver); rv = EINVAL; 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. */ + pkgname = xbps_pkg_name(pkgver); + assert(pkgname); buf = xbps_xasprintf("%s/.%s.plist", xhp->metadir, pkgname); sha256 = xbps_file_hash(buf); 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, "skip-obsoletes"); - if (!xbps_pkgdb_replace_pkg(xhp, pkgd, pkgname, flush)) { + if (!prop_dictionary_set(xhp->pkgdb, pkgname, pkgd)) { xbps_dbg_printf(xhp, - "%s: failed to replace pkgd dict for %s\n", - __func__, pkgname); + "%s: failed to set pkgd for %s\n", __func__, pkgver); goto out; } + (void)xbps_pkgdb_update(xhp, true); + out: + if (pkgname) + free(pkgname); + if (rv != 0) { xbps_set_cb_state(xhp, XBPS_STATE_REGISTER_FAIL, - rv, pkgname, version, - "%s: failed to register package: %s", + rv, pkgver, "%s: failed to register package: %s", pkgver, strerror(rv)); } return rv; } -int -xbps_unregister_pkg(struct xbps_handle *xhp, const char *pkgver, bool flush) +int HIDDEN +xbps_unregister_pkg(struct xbps_handle *xhp, const char *pkgver) { + char *pkgname; + assert(xhp); assert(pkgver); xbps_set_cb_state(xhp, XBPS_STATE_UNREGISTER, 0, pkgver, NULL, NULL); - if (!xbps_pkgdb_remove_pkg(xhp, pkgver, flush)) { - xbps_set_cb_state(xhp, XBPS_STATE_UNREGISTER_FAIL, - errno, pkgver, NULL, - "%s: failed to unregister package: %s", - pkgver, strerror(errno)); - return errno; - } + pkgname = xbps_pkg_name(pkgver); + assert(pkgname); + prop_dictionary_remove(xhp->pkgdb, pkgname); + free(pkgname); + + (void)xbps_pkgdb_update(xhp, true); + return 0; } diff --git a/lib/package_remove.c b/lib/package_remove.c index 9d039c5a..4b776f31 100644 --- a/lib/package_remove.c +++ b/lib/package_remove.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2012 Juan Romero Pardines. + * Copyright (c) 2009-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,45 +33,7 @@ #include "xbps_api_impl.h" -/** - * @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 pre-remove 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 post-remove target specified in the REMOVE script - * will be executed. - * -# Its state will be changed to XBPS_PKG_STATE_HALF_REMOVED. - * -# Its purge-remove 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 1 and 4 - * 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: - * - Salmon bg box: XBPS_PKGFILES plist file. - * - White bg box: mandatory objects. - * - Grey bg box: 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 +int HIDDEN xbps_remove_pkg_files(struct xbps_handle *xhp, prop_dictionary_t dict, const char *key, @@ -81,7 +43,7 @@ xbps_remove_pkg_files(struct xbps_handle *xhp, prop_array_t array; prop_object_iterator_t iter; prop_object_t obj; - const char *file, *sha256, *version, *curobj = NULL; + const char *file, *sha256, *curobj = NULL; char *path = NULL, *pkgname = NULL; char buf[PATH_MAX]; int rv = 0; @@ -109,7 +71,6 @@ xbps_remove_pkg_files(struct xbps_handle *xhp, pkgname = xbps_pkg_name(pkgver); assert(pkgname); - version = xbps_pkg_version(pkgver); while ((obj = prop_object_iterator_next(iter))) { prop_dictionary_get_cstring_nocopy(obj, "file", &file); @@ -128,7 +89,7 @@ xbps_remove_pkg_files(struct xbps_handle *xhp, /* missing file, ignore it */ xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE_HASH_FAIL, - rv, pkgname, version, + rv, pkgver, "%s: failed to check hash for %s `%s': %s", pkgver, curobj, file, strerror(rv)); free(path); @@ -140,7 +101,7 @@ xbps_remove_pkg_files(struct xbps_handle *xhp, XBPS_FLAG_FORCE_REMOVE_FILES) == 0) { xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE_HASH_FAIL, - 0, pkgname, version, + 0, pkgver, "%s: %s `%s' SHA256 mismatch, " "preserving file", pkgver, curobj, file); @@ -149,7 +110,7 @@ xbps_remove_pkg_files(struct xbps_handle *xhp, } else { xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE_HASH_FAIL, - 0, pkgname, version, + 0, pkgver, "%s: %s `%s' SHA256 mismatch, " "forcing removal", pkgver, curobj, file); @@ -157,7 +118,7 @@ xbps_remove_pkg_files(struct xbps_handle *xhp, } else if (rv != 0 && rv != ERANGE) { xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE_HASH_FAIL, - rv, pkgname, version, + rv, pkgver, "%s: [remove] failed to check hash for " "%s `%s': %s", pkgver, curobj, file, strerror(rv)); @@ -186,15 +147,14 @@ xbps_remove_pkg_files(struct xbps_handle *xhp, */ if (remove(path) == -1) { xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE_FAIL, - errno, pkgname, version, + errno, pkgver, "%s: failed to remove %s `%s': %s", pkgver, curobj, file, strerror(errno)); errno = 0; } else { /* success */ xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE, - 0, pkgname, version, - "Removed %s `%s'", curobj, file); + 0, pkgver, "Removed %s `%s'", curobj, file); } free(path); } @@ -204,7 +164,7 @@ xbps_remove_pkg_files(struct xbps_handle *xhp, return rv; } -int +int HIDDEN xbps_remove_pkg(struct xbps_handle *xhp, const char *pkgver, bool update, @@ -231,12 +191,12 @@ xbps_remove_pkg(struct xbps_handle *xhp, pkgver, state); 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) { rv = errno; xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL, - rv, pkgname, version, + rv, pkgver, "%s: [remove] failed to chdir to rootdir `%s': %s", pkgver, xhp->rootdir, strerror(rv)); goto out; @@ -248,7 +208,7 @@ xbps_remove_pkg(struct xbps_handle *xhp, free(buf); if (pkgd == NULL) 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 (state == XBPS_PKG_STATE_HALF_REMOVED) @@ -261,7 +221,7 @@ xbps_remove_pkg(struct xbps_handle *xhp, "pre", update); if (rv != 0) { xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL, - errno, pkgname, version, + errno, pkgver, "%s: [remove] REMOVE script failed to " "execute pre ACTION: %s", 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); if (rv != 0) { xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL, - rv, pkgname, version, + rv, pkgver, "%s: [remove] REMOVE script failed to execute " "post ACTION: %s", pkgver, strerror(rv)); goto out; @@ -318,11 +278,11 @@ softreplace: /* * 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); if (rv != 0) { xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL, - rv, pkgname, version, + rv, pkgver, "%s: [remove] failed to set state to half-removed: %s", pkgver, strerror(rv)); goto out; @@ -336,7 +296,7 @@ purge: rv = xbps_pkg_exec_script(xhp, pkgd, "remove-script", "purge", false); if (rv != 0) { xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL, - rv, pkgname, version, + rv, pkgver, "%s: REMOVE script failed to execute " "purge ACTION: %s", pkgver, strerror(rv)); goto out; @@ -350,7 +310,7 @@ purge: if (remove(buf) == -1) { if (errno != ENOENT) { xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL, - rv, pkgname, version, + rv, pkgver, "%s: failed to remove metadata file: %s", pkgver, strerror(errno)); } @@ -359,13 +319,12 @@ purge: /* * Unregister package from pkgdb. */ - if ((rv = xbps_unregister_pkg(xhp, pkgver, true)) != 0) + if ((rv = xbps_unregister_pkg(xhp, pkgver)) != 0) goto out; xbps_dbg_printf(xhp, "[remove] unregister %s returned %d\n", pkgver, rv); - xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_DONE, - 0, pkgname, version, NULL); + xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_DONE, 0, pkgver, NULL); out: if (pkgname != NULL) free(pkgname); diff --git a/lib/package_script.c b/lib/package_script.c index 738cc99a..97ead0b3 100644 --- a/lib/package_script.c +++ b/lib/package_script.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2012 Juan Romero Pardines. + * Copyright (c) 2012-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,8 +35,7 @@ int xbps_pkg_exec_buffer(struct xbps_handle *xhp, const void *blob, const size_t blobsiz, - const char *pkgname, - const char *version, + const char *pkgver, const char *action, bool update) { @@ -46,8 +45,7 @@ xbps_pkg_exec_buffer(struct xbps_handle *xhp, int fd, rv; assert(blob); - assert(pkgname); - assert(version); + assert(pkgver); assert(action); if (strcmp(xhp->rootdir, "/") == 0) { @@ -87,7 +85,7 @@ xbps_pkg_exec_buffer(struct xbps_handle *xhp, close(fd); /* exec script */ - rv = xbps_file_exec(xhp, fpath, action, pkgname, version, + rv = xbps_file_exec(xhp, fpath, action, pkgver, update ? "yes" : "no", xhp->conffile, NULL); @@ -105,7 +103,7 @@ xbps_pkg_exec_script(struct xbps_handle *xhp, bool update) { prop_data_t data; - const char *pkgname, *version; + const char *pkgver; assert(xhp); assert(d); @@ -116,10 +114,8 @@ xbps_pkg_exec_script(struct xbps_handle *xhp, if (data == NULL) return 0; - prop_dictionary_get_cstring_nocopy(d, "pkgname", &pkgname); - prop_dictionary_get_cstring_nocopy(d, "version", &version); + prop_dictionary_get_cstring_nocopy(d, "pkgver", &pkgver); return xbps_pkg_exec_buffer(xhp, prop_data_data(data), - prop_data_size(data), pkgname, version, - action, update); + prop_data_size(data), pkgver, action, update); } diff --git a/lib/package_state.c b/lib/package_state.c index e56b32a2..12922bad 100644 --- a/lib/package_state.c +++ b/lib/package_state.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2012 Juan Romero Pardines. + * Copyright (c) 2009-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -93,15 +93,15 @@ get_state(prop_dictionary_t dict) int xbps_pkg_state_installed(struct xbps_handle *xhp, - const char *pkgname, + const char *pkgver, pkg_state_t *state) { prop_dictionary_t pkgd; - assert(pkgname != NULL); + assert(pkgver != NULL); assert(state != NULL); - pkgd = xbps_pkgdb_get_pkg(xhp, pkgname); + pkgd = xbps_pkgdb_get_pkg(xhp, pkgver); if (pkgd == NULL) return ENOENT; @@ -133,46 +133,32 @@ xbps_set_pkg_state_dictionary(prop_dictionary_t dict, pkg_state_t state) } 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, "pkgname", name)) + if (!prop_dictionary_set_cstring_nocopy(pkgd, "pkgver", pkgver)) 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; } int xbps_set_pkg_state_installed(struct xbps_handle *xhp, - const char *pkgname, - const char *version, + const char *pkgver, pkg_state_t state) { prop_dictionary_t pkgd; + char *pkgname; 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) { pkgd = prop_dictionary_create(); if (pkgd == NULL) return ENOMEM; - if ((rv = set_pkg_objs(pkgd, pkgname, version)) != 0) { + if ((rv = set_pkg_objs(pkgd, pkgver)) != 0) { prop_object_release(pkgd); return rv; } @@ -180,17 +166,25 @@ xbps_set_pkg_state_installed(struct xbps_handle *xhp, prop_object_release(pkgd); 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); + free(pkgname); return EINVAL; } + free(pkgname); } else { if ((rv = set_new_state(pkgd, state)) != 0) return rv; - if ((rv = xbps_array_replace_dict_by_name(xhp->pkgdb, - pkgd, pkgname)) != 0) - return rv; + pkgname = xbps_pkg_name(pkgver); + assert(pkgname); + if (!prop_dictionary_set(xhp->pkgdb, pkgname, pkgd)) { + free(pkgname); + return EINVAL; + } + free(pkgname); } return rv; diff --git a/lib/package_unpack.c b/lib/package_unpack.c index 28db843d..eb930058 100644 --- a/lib/package_unpack.c +++ b/lib/package_unpack.c @@ -82,9 +82,11 @@ find_pkg_symlink_target(prop_dictionary_t d, const char *file) static int unpack_archive(struct xbps_handle *xhp, prop_dictionary_t pkg_repod, + const char *pkgver, + const char *fname, 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_object_t obj; prop_data_t data; @@ -93,12 +95,10 @@ unpack_archive(struct xbps_handle *xhp, struct stat st; struct xbps_unpack_cb_data xucd; struct archive_entry *entry; - size_t i, entry_idx = 0; - size_t instbufsiz, rembufsiz; + size_t i, entry_idx = 0, instbufsiz, rembufsiz; ssize_t entry_size; - const char *file, *entry_pname, *transact, *pkgname; - const char *version, *pkgver, *fname, *tgtlnk; - char *dname, *buf, *buf2, *p, *p2; + const char *file, *entry_pname, *transact, *tgtlnk; + char *pkgname, *dname, *buf, *buf2, *p, *p2; int ar_rv, rv, rv_stat, flags; bool preserve, update, conf_file, file_exists, skip_obsoletes; 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(ar != NULL); + pkg_metad = propsd = filesd = old_filesd = NULL; force = preserve = update = conf_file = file_exists = 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_cstring_nocopy(pkg_repod, "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(); @@ -141,7 +138,7 @@ unpack_archive(struct xbps_handle *xhp, } if (chdir(xhp->rootdir) == -1) { xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL, - errno, pkgname, version, + errno, pkgver, "%s: [unpack] failed to chdir to rootdir `%s': %s", pkgver, xhp->rootdir, strerror(errno)); rv = errno; @@ -197,11 +194,11 @@ unpack_archive(struct xbps_handle *xhp, } rv = xbps_pkg_exec_buffer(xhp, instbuf, instbufsiz, - pkgname, version, "pre", update); + pkgver, "pre", update); if (rv != 0) { xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL, - rv, pkgname, version, + rv, pkgver, "%s: [unpack] INSTALL script failed " "to execute pre ACTION: %s", pkgver, strerror(rv)); @@ -236,15 +233,18 @@ unpack_archive(struct xbps_handle *xhp, } continue; } else if (strcmp("./props.plist", entry_pname) == 0) { - /* ignore this one; we use pkg data from repo index */ - archive_read_data_skip(ar); + propsd = xbps_dictionary_from_archive_entry(ar, entry); + if (propsd == NULL) { + rv = errno; + goto out; + } continue; } /* * If XBPS_PKGFILES or XBPS_PKGPROPS weren't found * in the archive at this phase, skip all data. */ - if (filesd == NULL) { + if (propsd == NULL || filesd == NULL) { archive_read_data_skip(ar); /* * If we have processed 4 entries and the two @@ -254,7 +254,7 @@ unpack_archive(struct xbps_handle *xhp, if (entry_idx >= 3) { xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL, - ENODEV, pkgname, version, + ENODEV, pkgver, "%s: [unpack] invalid binary package `%s'.", pkgver, fname); rv = ENODEV; @@ -301,14 +301,13 @@ unpack_archive(struct xbps_handle *xhp, * "conf_files" array on its XBPS_PKGPROPS * dictionary. */ - if (xbps_entry_is_a_conf_file(pkg_repod, buf)) { + if (xbps_entry_is_a_conf_file(propsd, buf)) { conf_file = true; if (xhp->unpack_cb != NULL) xucd.entry_is_conf = true; rv = xbps_entry_install_conf_file(xhp, - filesd, entry, entry_pname, - pkgname, version); + filesd, entry, entry_pname, pkgver); if (rv == -1) { /* error */ goto out; @@ -324,10 +323,9 @@ unpack_archive(struct xbps_handle *xhp, if (rv == -1) { /* error */ xbps_dbg_printf(xhp, - "%s-%s: failed to check" + "%s: failed to check" " hash for `%s': %s\n", - pkgname, version, - entry_pname, + pkgver, entry_pname, strerror(errno)); goto out; } else if (rv == 0) { @@ -335,10 +333,10 @@ unpack_archive(struct xbps_handle *xhp, * hash match, skip extraction. */ xbps_dbg_printf(xhp, - "%s-%s: file %s " + "%s: file %s " "matches existing SHA256, " - "skipping...\n", pkgname, - version, entry_pname); + "skipping...\n", + pkgver, entry_pname); skip_extract = true; } } @@ -372,9 +370,9 @@ unpack_archive(struct xbps_handle *xhp, "new: %s\n", pkgver, entry_pname, p, p2); if (strcmp(p, p2) == 0) { - xbps_dbg_printf(xhp, "%s-%s: symlink " + xbps_dbg_printf(xhp, "%s: symlink " "%s matched, skipping...\n", - pkgname, version, entry_pname); + pkgver, entry_pname); skip_extract = true; } free(buf); @@ -389,17 +387,16 @@ unpack_archive(struct xbps_handle *xhp, if (chmod(entry_pname, entry_statp->st_mode) != 0) { xbps_dbg_printf(xhp, - "%s-%s: failed " + "%s: failed " "to set perms %s to %s: %s\n", - pkgname, version, - archive_entry_strmode(entry), + pkgver, archive_entry_strmode(entry), entry_pname, strerror(errno)); rv = EINVAL; goto out; } - xbps_dbg_printf(xhp, "%s-%s: entry %s changed file " - "mode to %s.\n", pkgname, version, entry_pname, + xbps_dbg_printf(xhp, "%s: entry %s changed file " + "mode to %s.\n", pkgver, entry_pname, archive_entry_strmode(entry)); } /* @@ -412,15 +409,13 @@ unpack_archive(struct xbps_handle *xhp, if (chown(entry_pname, entry_statp->st_uid, entry_statp->st_gid) != 0) { xbps_dbg_printf(xhp, - "%s-%s: failed " + "%s: failed " "to set uid/gid to %u:%u (%s)\n", - pkgname, version, - entry_statp->st_uid, entry_statp->st_gid, + pkgver, entry_statp->st_uid, entry_statp->st_gid, strerror(errno)); } else { - xbps_dbg_printf(xhp, "%s-%s: entry %s changed " - "uid/gid to %u:%u.\n", pkgname, version, - entry_pname, + xbps_dbg_printf(xhp, "%s: entry %s changed " + "uid/gid to %u:%u.\n", pkgver, entry_pname, entry_statp->st_uid, entry_statp->st_gid); } } @@ -435,8 +430,7 @@ unpack_archive(struct xbps_handle *xhp, free(buf); buf = NULL; xbps_set_cb_state(xhp, - XBPS_STATE_CONFIG_FILE, 0, - pkgname, version, + XBPS_STATE_CONFIG_FILE, 0, pkgver, "Renamed old configuration file " "`%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) { rv = archive_errno(ar); xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL, - rv, pkgname, version, + rv, pkgver, NULL, "%s: [unpack] failed to extract file `%s': %s", pkgver, entry_pname, strerror(rv)); } else { @@ -471,7 +465,7 @@ unpack_archive(struct xbps_handle *xhp, */ if ((rv = archive_errno(ar)) != 0) { xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL, - rv, pkgname, version, + rv, pkgver, NULL, "%s: [unpack] failed to extract files: %s", pkgver, fname, archive_error_string(ar)); goto out; @@ -490,7 +484,7 @@ unpack_archive(struct xbps_handle *xhp, * - Package upgrade. * - 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) goto out1; @@ -501,21 +495,21 @@ unpack_archive(struct xbps_handle *xhp, if (remove(file) == -1) { xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE_OBSOLETE_FAIL, - errno, pkgname, version, + errno, pkgver, NULL, "%s: failed to remove obsolete entry `%s': %s", pkgver, file, strerror(errno)); continue; } xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE_OBSOLETE, - 0, pkgname, version, + 0, pkgver, NULL, "%s: removed obsolete entry: %s", pkgver, file); prop_object_release(obj); } out1: - prop_dictionary_make_immutable(pkg_repod); - pkg_metad = prop_dictionary_copy_mutable(pkg_repod); + prop_dictionary_make_immutable(propsd); + pkg_metad = prop_dictionary_copy_mutable(propsd); /* Add objects from XBPS_PKGFILES */ array = prop_dictionary_get(filesd, "files"); @@ -550,6 +544,8 @@ out1: prop_dictionary_remove(pkg_metad, "remove-and-update"); prop_dictionary_remove(pkg_metad, "transaction"); prop_dictionary_remove(pkg_metad, "state"); + prop_dictionary_remove(pkg_metad, "pkgname"); + prop_dictionary_remove(pkg_metad, "version"); /* * Externalize pkg dictionary to metadir. @@ -562,22 +558,29 @@ out1: goto out; } } + pkgname = xbps_pkg_name(pkgver); + assert(pkgname); + buf = xbps_xasprintf("%s/.%s.plist", XBPS_META_PATH, pkgname); if (!prop_dictionary_externalize_to_file(pkg_metad, buf)) { rv = errno; xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL, - errno, pkgname, version, + errno, pkgver, "%s: [unpack] failed to extract metadata file `%s': %s", pkgver, buf, strerror(errno)); free(buf); + free(pkgname); goto out; } free(buf); + free(pkgname); out: if (prop_object_type(pkg_metad) == PROP_TYPE_DICTIONARY) prop_object_release(pkg_metad); if (prop_object_type(filesd) == PROP_TYPE_DICTIONARY) prop_object_release(filesd); + if (prop_object_type(propsd) == PROP_TYPE_DICTIONARY) + prop_object_release(propsd); return rv; } @@ -586,22 +589,19 @@ int HIDDEN xbps_unpack_binary_pkg(struct xbps_handle *xhp, prop_dictionary_t pkg_repod) { struct archive *ar = NULL; - const char *pkgname, *version, *pkgver; + const char *pkgver; char *bpkg; int pkg_fd, rv = 0; 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); - - xbps_set_cb_state(xhp, XBPS_STATE_UNPACK, 0, pkgname, version, NULL); + xbps_set_cb_state(xhp, XBPS_STATE_UNPACK, 0, pkgver, NULL, NULL); bpkg = xbps_repository_pkg_path(xhp, pkg_repod); if (bpkg == NULL) { xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL, - errno, pkgname, version, + errno, pkgver, "%s: [unpack] cannot determine binary package " "file for `%s': %s", pkgver, bpkg, strerror(errno)); return errno; @@ -623,7 +623,7 @@ xbps_unpack_binary_pkg(struct xbps_handle *xhp, prop_dictionary_t pkg_repod) if (pkg_fd == -1) { rv = archive_errno(ar); xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL, - rv, pkgname, version, + rv, pkgver, "%s: [unpack] failed to open binary package `%s': %s", pkgver, bpkg, strerror(rv)); free(bpkg); @@ -631,14 +631,13 @@ xbps_unpack_binary_pkg(struct xbps_handle *xhp, prop_dictionary_t pkg_repod) return rv; } archive_read_open_fd(ar, pkg_fd, ARCHIVE_READ_BLOCKSIZE); - free(bpkg); /* * 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, - rv, pkgname, version, + rv, pkgver, "%s: [unpack] failed to unpack files from archive: %s", pkgver, strerror(rv)); goto out; @@ -646,10 +645,10 @@ xbps_unpack_binary_pkg(struct xbps_handle *xhp, prop_dictionary_t pkg_repod) /* * 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_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL, - rv, pkgname, version, + rv, pkgver, "%s: [unpack] failed to set state to unpacked: %s", pkgver, strerror(rv)); } @@ -657,6 +656,8 @@ out: close(pkg_fd); if (ar) archive_read_free(ar); + if (bpkg) + free(bpkg); return rv; } diff --git a/lib/pkgdb.c b/lib/pkgdb.c index da89a2c9..3f49b41e 100644 --- a/lib/pkgdb.c +++ b/lib/pkgdb.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2012 Juan Romero Pardines. + * Copyright (c) 2012-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -79,7 +79,7 @@ xbps_pkgdb_init(struct xbps_handle *xhp) int xbps_pkgdb_update(struct xbps_handle *xhp, bool flush) { - prop_array_t pkgdb_storage; + prop_dictionary_t pkgdb_storage; char *plist; static int cached_rv; 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); if (xhp->pkgdb && flush) { - pkgdb_storage = prop_array_internalize_from_zfile(plist); + pkgdb_storage = prop_dictionary_internalize_from_file(plist); if (pkgdb_storage == NULL || - !prop_array_equals(xhp->pkgdb, pkgdb_storage)) { + !prop_dictionary_equals(xhp->pkgdb, pkgdb_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); return errno; } @@ -106,9 +106,9 @@ xbps_pkgdb_update(struct xbps_handle *xhp, bool flush) cached_rv = 0; } /* 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) - xhp->pkgdb = prop_array_create(); + xhp->pkgdb = prop_dictionary_create(); else 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"); } -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 xbps_pkgdb_foreach_reverse_cb(struct xbps_handle *xhp, int (*fn)(struct xbps_handle *, prop_object_t, void *, bool *), 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 @@ -167,7 +169,25 @@ xbps_pkgdb_foreach_cb(struct xbps_handle *xhp, int (*fn)(struct xbps_handle *, prop_object_t, void *, bool *), 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 @@ -176,7 +196,7 @@ xbps_pkgdb_get_pkg(struct xbps_handle *xhp, const char *pkg) if (xbps_pkgdb_init(xhp) != 0) return NULL; - return xbps_find_pkg_in_array(xhp->pkgdb, pkg); + return xbps_find_pkg_in_dict(xhp->pkgdb, pkg); } prop_dictionary_t @@ -185,28 +205,32 @@ xbps_pkgdb_get_virtualpkg(struct xbps_handle *xhp, const char *vpkg) if (xbps_pkgdb_init(xhp) != 0) 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 get_pkg_metadata(struct xbps_handle *xhp, prop_dictionary_t pkgd) { prop_dictionary_t pkg_metad; - const char *pkgname; - char *plist; + const char *pkgver; + 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; - + } 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); if (pkg_metad == NULL) { xbps_dbg_printf(xhp, "[pkgdb] cannot read %s metadata: %s\n", - pkgname, strerror(errno)); + pkgver, strerror(errno)); + free(pkgname); 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_object_release(pkg_metad); + free(pkgname); return pkg_metad; } @@ -223,7 +248,7 @@ static void generate_full_revdeps_tree(struct xbps_handle *xhp) { prop_array_t rundeps, pkg; - prop_dictionary_t pkgmetad; + prop_dictionary_t pkgmetad, pkgd; prop_object_t obj; prop_object_iterator_t iter; const char *pkgver, *pkgdep, *vpkgname; @@ -236,17 +261,18 @@ generate_full_revdeps_tree(struct xbps_handle *xhp) xhp->pkgdb_revdeps = prop_dictionary_create(); - iter = prop_array_iterator(xhp->pkgdb); + iter = prop_dictionary_iterator(xhp->pkgdb); assert(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 * the slower pkg metadata method. */ - rundeps = prop_dictionary_get(obj, "run_depends"); + rundeps = prop_dictionary_get(pkgd, "run_depends"); if (rundeps == NULL) { - pkgmetad = get_pkg_metadata(xhp, obj); + pkgmetad = get_pkg_metadata(xhp, pkgd); assert(pkgmetad); rundeps = prop_dictionary_get(pkgmetad, "run_depends"); } @@ -269,7 +295,7 @@ generate_full_revdeps_tree(struct xbps_handle *xhp) alloc = true; 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_dictionary_set(xhp->pkgdb_revdeps, vpkgname, pkg); free(curpkgname); @@ -283,16 +309,21 @@ generate_full_revdeps_tree(struct xbps_handle *xhp) prop_array_t xbps_pkgdb_get_pkg_revdeps(struct xbps_handle *xhp, const char *pkg) { + prop_array_t res; prop_dictionary_t pkgd; - const char *pkgname; + const char *pkgver; + char *pkgname; if ((pkgd = xbps_pkgdb_get_pkg(xhp, pkg)) == NULL) return NULL; 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 @@ -306,52 +337,3 @@ xbps_pkgdb_get_pkg_metadata(struct xbps_handle *xhp, const char *pkg) 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; -} diff --git a/lib/plist.c b/lib/plist.c index 7efe0bf5..b7535112 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2008-2012 Juan Romero Pardines. + * Copyright (c) 2008-2013 Juan Romero Pardines. * All rights reserved. * * 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); if (prop_object_type(array) != PROP_TYPE_ARRAY) - return EINVAL; + return ENOENT; for (i = 0; i < prop_array_count(array); i++) { obj = prop_array_get(array, i); @@ -213,7 +213,8 @@ array_replace_dict(prop_array_t array, { prop_object_t obj; size_t i; - const char *curpkgname; + const char *curpkgver; + char *curpkgname; assert(prop_object_type(array) == PROP_TYPE_ARRAY); assert(prop_object_type(dict) == PROP_TYPE_DICTIONARY); @@ -226,8 +227,8 @@ array_replace_dict(prop_array_t array, if (bypattern) { /* pkgpattern match */ prop_dictionary_get_cstring_nocopy(obj, - "pkgver", &curpkgname); - if (xbps_pkgpattern_match(curpkgname, str)) { + "pkgver", &curpkgver); + if (xbps_pkgpattern_match(curpkgver, str)) { if (!prop_array_set(array, i, dict)) return EINVAL; @@ -236,13 +237,18 @@ array_replace_dict(prop_array_t array, } else { /* pkgname match */ prop_dictionary_get_cstring_nocopy(obj, - "pkgname", &curpkgname); + "pkgver", &curpkgver); + curpkgname = xbps_pkg_name(curpkgver); + assert(curpkgname); if (strcmp(curpkgname, str) == 0) { - if (!prop_array_set(array, i, dict)) + if (!prop_array_set(array, i, dict)) { + free(curpkgname); return EINVAL; - + } + free(curpkgname); return 0; } + free(curpkgname); } } /* no match */ @@ -252,9 +258,9 @@ array_replace_dict(prop_array_t array, int HIDDEN xbps_array_replace_dict_by_name(prop_array_t array, 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 diff --git a/lib/plist_fetch.c b/lib/plist_fetch.c index 6bd5763b..402e7e4f 100644 --- a/lib/plist_fetch.c +++ b/lib/plist_fetch.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2012 Juan Romero Pardines. + * Copyright (c) 2009-2013 Juan Romero Pardines. * Copyright (c) 2008, 2009 Joerg Sonnenberger * All rights reserved. * @@ -190,7 +190,6 @@ xbps_get_pkg_plist_from_binpkg(const char *fname, const char *plistf) break; } - archive_read_close(a); archive_read_free(a); return plistd; diff --git a/lib/plist_find.c b/lib/plist_find.c index 13896ba6..0581be9c 100644 --- a/lib/plist_find.c +++ b/lib/plist_find.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2008-2012 Juan Romero Pardines. + * Copyright (c) 2008-2013 Juan Romero Pardines. * All rights reserved. * * 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_iterator_t iter; - const char *pkgver, *dpkgn; + const char *pkgver; + char *dpkgn; bool found = false; iter = prop_array_iterator(array); @@ -76,12 +77,16 @@ get_pkg_in_array(prop_array_t array, const char *str, bool virtual) } else { /* match by pkgname */ if (!prop_dictionary_get_cstring_nocopy(obj, - "pkgname", &dpkgn)) + "pkgver", &pkgver)) continue; + dpkgn = xbps_pkg_name(pkgver); + assert(dpkgn); if (strcmp(dpkgn, str) == 0) { + free(dpkgn); found = true; break; } + free(dpkgn); } } 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); } + +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; +} diff --git a/lib/rindex_get.c b/lib/rindex_get.c index a4c800c2..53381364 100644 --- a/lib/rindex_get.c +++ b/lib/rindex_get.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2012 Juan Romero Pardines. + * Copyright (c) 2012-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,152 +36,13 @@ * @brief 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 xbps_rindex_get_virtualpkg(struct xbps_rindex *rpi, 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; + prop_dictionary_t pkgd; - if (xbps_pkgpattern_version(pkg)) - bypattern = true; - - /* 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) { + pkgd = xbps_find_virtualpkg_in_dict(rpi->xhp, rpi->repod, pkg); + if (pkgd) { prop_dictionary_set_cstring_nocopy(pkgd, "repository", rpi->uri); return pkgd; @@ -192,15 +53,9 @@ out: prop_dictionary_t xbps_rindex_get_pkg(struct xbps_rindex *rpi, const char *pkg) { - prop_dictionary_t pkgd = NULL; - - 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); + prop_dictionary_t pkgd; + pkgd = xbps_find_pkg_in_dict(rpi->repod, pkg); if (pkgd) { prop_dictionary_set_cstring_nocopy(pkgd, "repository", rpi->uri); diff --git a/lib/rindex_pkgdeps.c b/lib/rindex_pkgdeps.c index efa19c48..5e8d5318 100644 --- a/lib/rindex_pkgdeps.c +++ b/lib/rindex_pkgdeps.c @@ -158,8 +158,8 @@ find_repo_deps(struct xbps_handle *xhp, prop_array_t curpkgrdeps; pkg_state_t state; size_t x; - const char *reqpkg, *reqpkgname, *pkgver_q, *reason = NULL; - char *pkgname; + const char *reqpkg, *pkgver_q, *reason = NULL; + char *pkgname, *reqpkgname; int rv = 0; if (*depth >= MAX_DEPTH) @@ -317,8 +317,8 @@ find_repo_deps(struct xbps_handle *xhp, } prop_dictionary_get_cstring_nocopy(curpkgd, "pkgver", &pkgver_q); - prop_dictionary_get_cstring_nocopy(curpkgd, - "pkgname", &reqpkgname); + reqpkgname = xbps_pkg_name(pkgver_q); + assert(reqpkgname); /* * Check dependency validity. */ @@ -329,9 +329,11 @@ find_repo_deps(struct xbps_handle *xhp, "%s (depends on itself)]\n", reqpkg); free(pkgname); + free(reqpkgname); continue; } free(pkgname); + free(reqpkgname); /* * Check if package has matched conflicts. diff --git a/lib/rpool.c b/lib/rpool.c index 0024f2ae..4bbdecb4 100644 --- a/lib/rpool.c +++ b/lib/rpool.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2012 Juan Romero Pardines. + * Copyright (c) 2009-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/lib/rpool_get.c b/lib/rpool_get.c index 9aad1c8e..755ba216 100644 --- a/lib/rpool_get.c +++ b/lib/rpool_get.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2012 Juan Romero Pardines. + * Copyright (c) 2009-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -193,6 +193,7 @@ xbps_rpool_get_pkg_plist(struct xbps_handle *xhp, const char *plistf) { prop_dictionary_t pkgd = NULL, plistd = NULL; + const char *repo; char *url; 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 * libfetch! */ - pkgd = xbps_rpool_get_pkg(xhp, pkg); - if (pkgd == NULL) + if (((pkgd = xbps_rpool_get_pkg(xhp, pkg)) == NULL) && + ((pkgd = xbps_rpool_get_virtualpkg(xhp, pkg)) == NULL)) goto out; url = xbps_repository_pkg_path(xhp, pkgd); @@ -216,6 +217,10 @@ xbps_rpool_get_pkg_plist(struct xbps_handle *xhp, goto out; } 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); out: diff --git a/lib/transaction_commit.c b/lib/transaction_commit.c index 84c079a7..712e31d8 100644 --- a/lib/transaction_commit.c +++ b/lib/transaction_commit.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2012 Juan Romero Pardines. + * Copyright (c) 2009-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -60,9 +60,8 @@ static int check_binpkgs_hash(struct xbps_handle *xhp, prop_object_iterator_t iter) { prop_object_t obj; - const char *pkgver, *repoloc, *filen, *sha256, *trans; - const char *pkgname, *version; - char *binfile; + const char *pkgver, *arch, *repoloc, *sha256, *trans; + char *binfile, *filen; int rv = 0; 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)) continue; - prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); - prop_dictionary_get_cstring_nocopy(obj, "version", &version); + prop_dictionary_get_cstring_nocopy(obj, "architecture", &arch); prop_dictionary_get_cstring_nocopy(obj, "repository", &repoloc); prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver); - prop_dictionary_get_cstring_nocopy(obj, "filename", &filen); prop_dictionary_get_cstring_nocopy(obj, "filename-sha256", &sha256); @@ -84,18 +81,22 @@ check_binpkgs_hash(struct xbps_handle *xhp, prop_object_iterator_t iter) rv = EINVAL; 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); rv = xbps_file_hash_check(binfile, sha256); if (rv != 0) { free(binfile); + free(filen); xbps_set_cb_state(xhp, XBPS_STATE_VERIFY_FAIL, - rv, pkgname, version, + rv, pkgver, "Failed to verify `%s' package integrity: %s", filen, strerror(rv)); break; } free(binfile); + free(filen); } prop_object_iterator_reset(iter); @@ -106,9 +107,8 @@ static int download_binpkgs(struct xbps_handle *xhp, prop_object_iterator_t iter) { prop_object_t obj; - const char *pkgver, *repoloc, *filen, *trans; - const char *pkgname, *version, *fetchstr; - char *binfile; + const char *pkgver, *arch, *fetchstr, *repoloc, *trans; + char *binfile, *filen; int rv = 0; bool state_dload = false; @@ -118,11 +118,9 @@ download_binpkgs(struct xbps_handle *xhp, prop_object_iterator_t iter) (strcmp(trans, "configure") == 0)) continue; - prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); - prop_dictionary_get_cstring_nocopy(obj, "version", &version); + prop_dictionary_get_cstring_nocopy(obj, "architecture", &arch); prop_dictionary_get_cstring_nocopy(obj, "repository", &repoloc); prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver); - prop_dictionary_get_cstring_nocopy(obj, "filename", &filen); binfile = xbps_repository_pkg_path(xhp, obj); 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 (xbps_mkpath(xhp->cachedir, 0755) == -1) { xbps_set_cb_state(xhp, XBPS_STATE_DOWNLOAD_FAIL, - errno, pkgname, version, + errno, pkgver, "%s: [trans] cannot create cachedir `%s':" "%s", pkgver, xhp->cachedir, strerror(errno)); @@ -153,24 +151,25 @@ download_binpkgs(struct xbps_handle *xhp, prop_object_iterator_t iter) } if (state_dload == false) { xbps_set_cb_state(xhp, XBPS_STATE_TRANS_DOWNLOAD, - 0, NULL, NULL, NULL); + 0, NULL, NULL); state_dload = true; } + filen = xbps_xasprintf("%s.%s.xbps", pkgver, arch); xbps_set_cb_state(xhp, XBPS_STATE_DOWNLOAD, - 0, pkgname, version, - "Downloading binary package `%s' (from `%s')...", + 0, pkgver, "Downloading binary package `%s' (from `%s')...", filen, repoloc); /* * Fetch binary package. */ if (chdir(xhp->cachedir) == -1) { xbps_set_cb_state(xhp, XBPS_STATE_DOWNLOAD_FAIL, - errno, pkgname, version, + errno, pkgver, "%s: [trans] failed to change dir to cachedir" "`%s': %s", pkgver, xhp->cachedir, strerror(errno)); rv = errno; free(binfile); + free(filen); break; } @@ -179,15 +178,16 @@ download_binpkgs(struct xbps_handle *xhp, prop_object_iterator_t iter) fetchstr = xbps_fetch_error_string(); xbps_set_cb_state(xhp, XBPS_STATE_DOWNLOAD_FAIL, fetchLastErrCode != 0 ? fetchLastErrCode : errno, - pkgname, version, - "%s: [trans] failed to download binary package " + pkgver, "%s: [trans] failed to download binary package " "`%s' from `%s': %s", pkgver, filen, repoloc, fetchstr ? fetchstr : strerror(errno)); free(binfile); + free(filen); break; } rv = 0; free(binfile); + free(filen); } prop_object_iterator_reset(iter); @@ -199,7 +199,7 @@ xbps_transaction_commit(struct xbps_handle *xhp) { prop_object_t obj; prop_object_iterator_t iter; - const char *pkgname, *version, *pkgver, *tract; + const char *pkgver, *tract; int rv = 0; bool update, install, sr; @@ -217,20 +217,18 @@ xbps_transaction_commit(struct xbps_handle *xhp) /* * 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) goto out; /* * Install, update, configure or remove packages as specified * 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) { update = false; 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); if (strcmp(tract, "remove") == 0) { @@ -245,14 +243,14 @@ xbps_transaction_commit(struct xbps_handle *xhp) rv = xbps_remove_pkg(xhp, pkgver, update, sr); if (rv != 0) { xbps_dbg_printf(xhp, "[trans] failed to " - "remove %s-%s\n", pkgname, version); + "remove %s\n", pkgver); goto out; } } else if (strcmp(tract, "configure") == 0) { /* * Reconfigure pending package. */ - rv = xbps_configure_pkg(xhp, pkgname, false, false, false); + rv = xbps_configure_pkg(xhp, pkgver, false, false, false); if (rv != 0) goto out; } else { @@ -264,27 +262,27 @@ xbps_transaction_commit(struct xbps_handle *xhp) else install = true; - if (update && xbps_pkgdb_get_pkg(xhp, pkgname)) { + if (update && xbps_pkgdb_get_pkg(xhp, pkgver)) { /* * Update a package: execute pre-remove * action if found before unpacking. */ xbps_set_cb_state(xhp, XBPS_STATE_UPDATE, 0, - pkgname, version, NULL); + pkgver, NULL); rv = xbps_remove_pkg(xhp, pkgver, true, false); if (rv != 0) { xbps_set_cb_state(xhp, XBPS_STATE_UPDATE_FAIL, - rv, pkgname, version, + rv, pkgver, "%s: [trans] failed to update " - "package to `%s': %s", pkgver, - version, strerror(rv)); + "package `%s'", pkgver, + strerror(rv)); goto out; } } else { /* Install a package */ xbps_set_cb_state(xhp, XBPS_STATE_INSTALL, - 0, pkgname, version, NULL); + 0, pkgver, NULL); } /* * Unpack binary package. @@ -294,7 +292,7 @@ xbps_transaction_commit(struct xbps_handle *xhp) /* * Register package. */ - if ((rv = xbps_register_pkg(xhp, obj, true)) != 0) + if ((rv = xbps_register_pkg(xhp, obj)) != 0) goto out; } } @@ -307,7 +305,7 @@ xbps_transaction_commit(struct xbps_handle *xhp) /* * 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) { prop_dictionary_get_cstring_nocopy(obj, "transaction", &tract); @@ -315,16 +313,15 @@ xbps_transaction_commit(struct xbps_handle *xhp) (strcmp(tract, "configure") == 0)) continue; - prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); - prop_dictionary_get_cstring_nocopy(obj, "version", &version); + prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver); update = false; if (strcmp(tract, "update") == 0) update = true; - rv = xbps_configure_pkg(xhp, pkgname, false, update, true); + rv = xbps_configure_pkg(xhp, pkgver, false, update, true); if (rv != 0) { xbps_dbg_printf(xhp, "%s: configure failed for " - "%s-%s: %s\n", pkgname, version, strerror(rv)); + "%s: %s\n", pkgver, strerror(rv)); goto out; } /* @@ -333,10 +330,10 @@ xbps_transaction_commit(struct xbps_handle *xhp) */ if (update) { xbps_set_cb_state(xhp, XBPS_STATE_UPDATE_DONE, 0, - pkgname, version, NULL); + pkgver, NULL); } else { xbps_set_cb_state(xhp, XBPS_STATE_INSTALL_DONE, 0, - pkgname, version, NULL); + pkgver, NULL); } } diff --git a/lib/transaction_dictionary.c b/lib/transaction_dictionary.c index 130eeb34..6897c57c 100644 --- a/lib/transaction_dictionary.c +++ b/lib/transaction_dictionary.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2012 Juan Romero Pardines. + * Copyright (c) 2009-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -61,7 +61,7 @@ compute_transaction_stats(struct xbps_handle *xhp) uint64_t tsize, dlsize, instsize, rmsize; uint32_t inst_pkgcnt, up_pkgcnt, cf_pkgcnt, rm_pkgcnt; int rv = 0; - const char *tract, *pkgname, *repo; + const char *tract, *pkgver, *repo; inst_pkgcnt = up_pkgcnt = cf_pkgcnt = rm_pkgcnt = 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, * 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, "repository", &repo); @@ -97,7 +97,7 @@ compute_transaction_stats(struct xbps_handle *xhp) */ if ((strcmp(tract, "remove") == 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) continue; prop_dictionary_get_uint64(pkg_metad, diff --git a/lib/transaction_ops.c b/lib/transaction_ops.c index 89233f05..a9f16cd1 100644 --- a/lib/transaction_ops.c +++ b/lib/transaction_ops.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2012 Juan Romero Pardines. + * Copyright (c) 2009-2013 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -60,9 +60,10 @@ enum { static int 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; - const char *pkgname, *repoloc, *repover, *repopkgver, *instver, *reason; + const char *repoloc, *repover, *repopkgver, *instpkgver, *reason; + char *pkgname; int rv = 0; pkg_state_t state = 0; @@ -88,29 +89,35 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, int action) 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, "repository", &repoloc); + pkgname = xbps_pkg_name(repopkgver); + assert(pkgname); + repover = xbps_pkg_version(repopkgver); + assert(repover); + if (action == TRANS_UPDATE) { /* * Compare installed version vs best pkg available in repos. */ prop_dictionary_get_cstring_nocopy(pkg_pkgdb, - "version", &instver); - if (xbps_cmpver(repover, instver) <= 0) { - xbps_dbg_printf(xhp, "[rpool] Skipping `%s-%s' " - "(installed: %s-%s) from repository `%s'\n", - pkgname, repover, pkgname, instver, repoloc); + "pkgver", &instpkgver); + if (xbps_cmpver(repopkgver, instpkgver) <= 0) { + xbps_dbg_printf(xhp, "[rpool] Skipping `%s' " + "(installed: %s) from repository `%s'\n", + repopkgver, instpkgver, repoloc); + free(pkgname); return EEXIST; } } /* * Prepare transaction dictionary. */ - if ((rv = xbps_transaction_init(xhp)) != 0) + if ((rv = xbps_transaction_init(xhp)) != 0) { + free(pkgname); return rv; + } 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)) { xbps_dbg_printf(xhp, "[update] `%s' already queued in " "transaction.\n", repopkgver); + free(pkgname); 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; + } /* * Set package state in dictionary with same state than the * package currently uses, otherwise not-installed. */ if ((rv = xbps_pkg_state_installed(xhp, pkgname, &state)) != 0) { - if (rv != ENOENT) + if (rv != ENOENT) { + free(pkgname); return rv; + } /* Package not installed, don't error out */ 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; + } if ((action == TRANS_INSTALL) && (state == XBPS_PKG_STATE_UNPACKED)) 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)) return EINVAL; - xbps_dbg_printf(xhp, "%s-%s: added into the transaction (%s).\n", - pkgname, repover, repoloc); + xbps_dbg_printf(xhp, "%s: added into the transaction (%s).\n", + repopkgver, repoloc); return 0; } @@ -174,9 +190,11 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, int action) int xbps_transaction_update_packages(struct xbps_handle *xhp) { + prop_dictionary_t pkgd; prop_object_t obj; prop_object_iterator_t iter; - const char *pkgname, *holdpkg; + const char *pkgver, *holdpkg; + char *pkgname; bool foundhold = false, newpkg_found = false; int rv = 0; size_t x; @@ -184,11 +202,31 @@ xbps_transaction_update_packages(struct xbps_handle *xhp) if ((rv = xbps_pkgdb_init(xhp)) != 0) return rv; - iter = prop_array_iterator(xhp->pkgdb); + iter = prop_dictionary_iterator(xhp->pkgdb); 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))) { - 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++) { holdpkg = cfg_getnstr(xhp->cfg, "PackagesOnHold", x); @@ -214,6 +252,7 @@ xbps_transaction_update_packages(struct xbps_handle *xhp) */ rv = 0; } + free(pkgname); } prop_object_iterator_release(iter); diff --git a/lib/transaction_package_replace.c b/lib/transaction_package_replace.c index 052eff3d..c4afe618 100644 --- a/lib/transaction_package_replace.c +++ b/lib/transaction_package_replace.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2011-2012 Juan Romero Pardines. + * Copyright (c) 2011-2013 Juan Romero Pardines. * All rights reserved. * * 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_object_t obj, obj2; prop_object_iterator_t iter; - const char *pattern, *pkgname, *curpkgname, *pkgver, *curpkgver; - char *buf; + const char *pattern, *pkgver, *curpkgver; + char *buf, *pkgname, *curpkgname; bool instd_auto, sr; size_t i; @@ -66,20 +66,23 @@ xbps_transaction_package_replace(struct xbps_handle *xhp) ((instd = xbps_pkgdb_get_virtualpkg(xhp, pattern)) == NULL)) continue; - prop_dictionary_get_cstring_nocopy(obj, - "pkgname", &pkgname); prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver); - prop_dictionary_get_cstring_nocopy(instd, - "pkgname", &curpkgname); prop_dictionary_get_cstring_nocopy(instd, "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, * due to virtual packages. */ - if (strcmp(pkgname, curpkgname) == 0) + if (strcmp(pkgname, curpkgname) == 0) { + free(pkgname); + free(curpkgname); continue; + } xbps_dbg_printf(xhp, "Package `%s' will be replaced by `%s', " @@ -126,15 +129,17 @@ xbps_transaction_package_replace(struct xbps_handle *xhp) "softreplace", true); buf = xbps_xasprintf("%s/.%s.plist", xhp->metadir, curpkgname); - filesd = prop_dictionary_internalize_from_zfile(buf); + filesd = prop_dictionary_internalize_from_file(buf); free(buf); assert(filesd != NULL); buf = xbps_xasprintf("%s/.%s.plist", xhp->metadir, pkgname); - if (!prop_dictionary_externalize_to_zfile(filesd, buf)) { + if (!prop_dictionary_externalize_to_file(filesd, buf)) { free(buf); prop_object_release(filesd); prop_object_iterator_release(iter); + free(pkgname); + free(curpkgname); return errno; } prop_object_release(filesd); @@ -147,6 +152,8 @@ xbps_transaction_package_replace(struct xbps_handle *xhp) prop_dictionary_set_cstring_nocopy(instd, "transaction", "remove"); prop_array_add(unsorted, instd); + free(pkgname); + free(curpkgname); } prop_object_iterator_release(iter); } diff --git a/lib/util.c b/lib/util.c index 6c125bbc..f9c7c34e 100644 --- a/lib/util.c +++ b/lib/util.c @@ -217,14 +217,17 @@ xbps_pkg_index_files_plist(struct xbps_handle *xhp, const char *uri) char HIDDEN * 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; assert(xhp); assert(prop_object_type(pkg_repod) == PROP_TYPE_DICTIONARY); 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; if (!prop_dictionary_get_cstring_nocopy(pkg_repod, "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. */ - 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) 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. */ - return xbps_xasprintf("%s/%s", repoloc, filen); + return xbps_xasprintf("%s/%s.%s.xbps", repoloc, pkgver, arch); } bool