diff --git a/contrib/mport/libexec/mport.check-fake/Makefile b/contrib/mport/libexec/mport.check-fake/Makefile index 2764ccd076..1ca26649d9 100644 --- a/contrib/mport/libexec/mport.check-fake/Makefile +++ b/contrib/mport/libexec/mport.check-fake/Makefile @@ -1,6 +1,6 @@ PROG= mport.check-fake -CFLAGS+= -I${.CURDIR}/../../libmport/ +CFLAGS+= -I${.CURDIR}/../../libmport/ -I/usr/include/private/ucl WARNS?= 6 MK_MAN= no diff --git a/contrib/mport/libexec/mport.check-fake/mport.check-fake.c b/contrib/mport/libexec/mport.check-fake/mport.check-fake.c index 951741d71d..859a20b104 100644 --- a/contrib/mport/libexec/mport.check-fake/mport.check-fake.c +++ b/contrib/mport/libexec/mport.check-fake/mport.check-fake.c @@ -89,11 +89,11 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; - DIAG("assetlist = %s; destdir = %s; prefix = %s; skip = %s", assetlistfile, destdir, prefix, skip) - if (!prefix || !destdir || !assetlistfile) usage(); + DIAG("assetlist = %s; destdir = %s; prefix = %s; skip = %s", assetlistfile, destdir, prefix, skip) + if (chroot_path != NULL) { if (chroot(chroot_path) == -1) { err(EXIT_FAILURE, "chroot failed"); diff --git a/contrib/mport/libexec/mport.check-for-older/Makefile b/contrib/mport/libexec/mport.check-for-older/Makefile index 73e25b6381..9daf6da900 100644 --- a/contrib/mport/libexec/mport.check-for-older/Makefile +++ b/contrib/mport/libexec/mport.check-for-older/Makefile @@ -1,6 +1,6 @@ PROG= mport.check-for-older -CFLAGS+= -I ../../libmport/ +CFLAGS+= -I ../../libmport/ -I/usr/include/private/ucl WARNS?= 4 MK_MAN= no diff --git a/contrib/mport/libexec/mport.create/Makefile b/contrib/mport/libexec/mport.create/Makefile index 0fa61cbf0a..80d690f7e9 100644 --- a/contrib/mport/libexec/mport.create/Makefile +++ b/contrib/mport/libexec/mport.create/Makefile @@ -1,6 +1,6 @@ PROG= mport.create -CFLAGS+= -I${.CURDIR}/../../libmport/ +CFLAGS+= -I${.CURDIR}/../../libmport/ -I/usr/include/private/ucl WARNS?= 6 MK_MAN= no diff --git a/contrib/mport/libexec/mport.delete/Makefile b/contrib/mport/libexec/mport.delete/Makefile index 1693018d05..54411c39a7 100644 --- a/contrib/mport/libexec/mport.delete/Makefile +++ b/contrib/mport/libexec/mport.delete/Makefile @@ -1,6 +1,6 @@ PROG= mport.delete -CFLAGS+= -I${.CURDIR}/../../libmport/ +CFLAGS+= -I${.CURDIR}/../../libmport/ -I/usr/include/private/ucl WARNS?= 4 MK_MAN= no diff --git a/contrib/mport/libexec/mport.delete/mport.delete.c b/contrib/mport/libexec/mport.delete/mport.delete.c index c621ba3041..d2aed2e520 100644 --- a/contrib/mport/libexec/mport.delete/mport.delete.c +++ b/contrib/mport/libexec/mport.delete/mport.delete.c @@ -108,6 +108,7 @@ int main(int argc, char *argv[]) { } while (*packs != NULL) { + (*packs)->action = MPORT_ACTION_DELETE; if (mport_delete_primative(mport, *packs, force) != MPORT_OK) { warnx("%s", mport_err_string()); mport_instance_free(mport); diff --git a/contrib/mport/libexec/mport.fetch/Makefile b/contrib/mport/libexec/mport.fetch/Makefile index 8f38b056ca..50d0dacd55 100644 --- a/contrib/mport/libexec/mport.fetch/Makefile +++ b/contrib/mport/libexec/mport.fetch/Makefile @@ -1,6 +1,6 @@ PROG= mport.fetch -CFLAGS= -I${.CURDIR}/../../libmport/ +CFLAGS= -I${.CURDIR}/../../libmport/ -I/usr/include/private/ucl WARNS?= 4 MK_MAN= no diff --git a/contrib/mport/libexec/mport.info/Makefile b/contrib/mport/libexec/mport.info/Makefile index 954aa19af6..cd98c3e652 100644 --- a/contrib/mport/libexec/mport.info/Makefile +++ b/contrib/mport/libexec/mport.info/Makefile @@ -1,6 +1,6 @@ PROG= mport.info -CFLAGS+=-I${.CURDIR}/../../libmport/ +CFLAGS+=-I${.CURDIR}/../../libmport/ -I/usr/include/private/ucl WARNS?= 4 MK_MAN= no diff --git a/contrib/mport/libexec/mport.init/Makefile b/contrib/mport/libexec/mport.init/Makefile index 0c7f86ec95..5ac71c7659 100644 --- a/contrib/mport/libexec/mport.init/Makefile +++ b/contrib/mport/libexec/mport.init/Makefile @@ -1,6 +1,6 @@ PROG= mport.init -CFLAGS+= -I${.CURDIR}/../../libmport/ +CFLAGS+= -I${.CURDIR}/../../libmport/ -I/usr/include/private/ucl WARNS?= 4 MK_MAN= no diff --git a/contrib/mport/libexec/mport.install/Makefile b/contrib/mport/libexec/mport.install/Makefile index 24056e1f22..4e2e965772 100644 --- a/contrib/mport/libexec/mport.install/Makefile +++ b/contrib/mport/libexec/mport.install/Makefile @@ -1,6 +1,6 @@ PROG= mport.install -CFLAGS+= -I${.CURDIR}/../../libmport/ +CFLAGS+= -I${.CURDIR}/../../libmport/ -I/usr/include/private/ucl WARNS?= 6 MK_MAN= no diff --git a/contrib/mport/libexec/mport.list/Makefile b/contrib/mport/libexec/mport.list/Makefile index 043ca2200e..0b660b48fa 100644 --- a/contrib/mport/libexec/mport.list/Makefile +++ b/contrib/mport/libexec/mport.list/Makefile @@ -1,6 +1,6 @@ PROG= mport.list -CFLAGS+= -I${.CURDIR}/../../libmport/ +CFLAGS+= -I${.CURDIR}/../../libmport/ -I/usr/include/private/ucl WARNS?= 4 MK_MAN= no diff --git a/contrib/mport/libexec/mport.list/mport.list.c b/contrib/mport/libexec/mport.list/mport.list.c index ae9fa00a31..a3a3a8ed5a 100644 --- a/contrib/mport/libexec/mport.list/mport.list.c +++ b/contrib/mport/libexec/mport.list/mport.list.c @@ -172,7 +172,7 @@ main(int argc, char *argv[]) } iestart = indexEntries; - while (*indexEntries != NULL) { + while (indexEntries != NULL && *indexEntries != NULL) { if (((*indexEntries)->version != NULL && mport_version_cmp((*packs)->version, (*indexEntries)->version) < 0) || ((*packs)->version != NULL && mport_version_cmp((*packs)->os_release, os_release) < 0)) { diff --git a/contrib/mport/libexec/mport.merge/Makefile b/contrib/mport/libexec/mport.merge/Makefile index 7ff538ba92..9d54171134 100644 --- a/contrib/mport/libexec/mport.merge/Makefile +++ b/contrib/mport/libexec/mport.merge/Makefile @@ -1,6 +1,6 @@ PROG= mport.merge -CFLAGS+= -I${.CURDIR}/../../libmport/ +CFLAGS+= -I${.CURDIR}/../../libmport/ -I/usr/include/private/ucl WARNS?= 4 MK_MAN= no diff --git a/contrib/mport/libexec/mport.query/Makefile b/contrib/mport/libexec/mport.query/Makefile index 74e3d74681..808769bb31 100644 --- a/contrib/mport/libexec/mport.query/Makefile +++ b/contrib/mport/libexec/mport.query/Makefile @@ -1,6 +1,6 @@ PROG= mport.query -CFLAGS+= -I${.CURDIR}/../../libmport/ +CFLAGS+= -I${.CURDIR}/../../libmport/ -I/usr/include/private/ucl WARNS?= 4 MK_MAN= no diff --git a/contrib/mport/libexec/mport.update/Makefile b/contrib/mport/libexec/mport.update/Makefile index c380d288ea..bdc4cf3d58 100644 --- a/contrib/mport/libexec/mport.update/Makefile +++ b/contrib/mport/libexec/mport.update/Makefile @@ -1,6 +1,6 @@ PROG= mport.update -CFLAGS+= -I${.CURDIR}/../../libmport/ -fblocks +CFLAGS+= -I${.CURDIR}/../../libmport/ -I/usr/include/private/ucl WARNS?= 4 MK_MAN= no diff --git a/contrib/mport/libexec/mport.updepends/Makefile b/contrib/mport/libexec/mport.updepends/Makefile index 157bcd4d2c..15e41a2fc0 100644 --- a/contrib/mport/libexec/mport.updepends/Makefile +++ b/contrib/mport/libexec/mport.updepends/Makefile @@ -1,6 +1,6 @@ PROG= mport.updepends -CFLAGS+= -I${.CURDIR}/../../libmport/ +CFLAGS+= -I${.CURDIR}/../../libmport/ -I/usr/include/private/ucl WARNS?= 4 MK_MAN= no diff --git a/contrib/mport/libexec/mport.version_cmp/Makefile b/contrib/mport/libexec/mport.version_cmp/Makefile index 7d9f04617c..d4ee717edb 100644 --- a/contrib/mport/libexec/mport.version_cmp/Makefile +++ b/contrib/mport/libexec/mport.version_cmp/Makefile @@ -1,6 +1,6 @@ PROG= mport.version_cmp -CFLAGS+= -I${.CURDIR}/../../libmport/ +CFLAGS+= -I${.CURDIR}/../../libmport/ -I/usr/include/private/ucl WARNS?= 4 MK_MAN= no diff --git a/contrib/mport/libmport/Makefile b/contrib/mport/libmport/Makefile index 20ebdbdb41..083fcdb048 100644 --- a/contrib/mport/libmport/Makefile +++ b/contrib/mport/libmport/Makefile @@ -9,7 +9,7 @@ SRCS= asset.c bundle_write.c bundle_read.c plist.c create_primative.c db.c \ update_primative.c bundle_read_update_pkg.c pkgmeta.c \ fetch.c index.c index_depends.c install.c clean.c setting.c \ stats.c update.c upgrade.c verify.c lock.c mkdir.c import_export.c \ - autoremove.c audit.c ping.c + autoremove.c audit.c ping.c message.c INCS= mport.h CFLAGS+= -I${.CURDIR} -I/usr/include/private/ucl diff --git a/contrib/mport/libmport/autoremove.c b/contrib/mport/libmport/autoremove.c index c30c0dac0c..93478bf31d 100644 --- a/contrib/mport/libmport/autoremove.c +++ b/contrib/mport/libmport/autoremove.c @@ -79,6 +79,7 @@ mport_autoremove(mportInstance *mport) { depends = depends_start; while ((*depends) != NULL) { mport_call_msg_cb(mport, "Auto-removing %s", (*depends)->name); + (*depends)->action = MPORT_ACTION_DELETE; if (mport_delete_primative(mport, *depends, true) != MPORT_OK) { mport_call_msg_cb(mport, "Unable to autoremove %s: %s", (*depends)->name, mport_err_string()); continue; diff --git a/contrib/mport/libmport/bundle_read_install_pkg.c b/contrib/mport/libmport/bundle_read_install_pkg.c index 9c630b4e97..a761682219 100644 --- a/contrib/mport/libmport/bundle_read_install_pkg.c +++ b/contrib/mport/libmport/bundle_read_install_pkg.c @@ -1,7 +1,7 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * - * Copyright (c) 2013-2015, 2021 Lucas Holt + * Copyright (c) 2013-2015, 2021, 2023 Lucas Holt * Copyright (c) 2007-2009 Chris Reinhardt * All rights reserved. * @@ -59,8 +59,6 @@ static int run_pkg_install(mportInstance *, mportBundleRead *, mportPackageMeta static int run_mtree(mportInstance *, mportBundleRead *, mportPackageMeta *); -static int display_pkg_msg(mportInstance *, mportBundleRead *, mportPackageMeta *); - static int get_file_count(mportInstance *, char *, int *); static int create_package_row(mportInstance *, mportPackageMeta *); @@ -77,10 +75,6 @@ static int mark_complete(mportInstance *, mportPackageMeta *); static int mport_bundle_read_get_assetlist(mportInstance *mport, mportPackageMeta *pkg, mportAssetList **alist_p, enum phase); -static int load_pkg_msg(mportInstance *mport, mportBundleRead *bundle, mportPackageMeta *pkg, mportPackageMessage *packageMessage); - -static mportPackageMessage * pkg_message_from_ucl(mportInstance *mport, const ucl_object_t *obj, mportPackageMessage *msg); - static int copy_metafile(mportInstance *, mportBundleRead *, mportPackageMeta *, char *); /** @@ -854,7 +848,7 @@ do_post_install(mportInstance *mport, mportBundleRead *bundle, mportPackageMeta if (run_postexec(mport, pkg) != MPORT_OK) RETURN_CURRENT_ERROR; - if (display_pkg_msg(mport, bundle, pkg) != MPORT_OK) + if (mport_pkg_message_display(mport, pkg) != MPORT_OK) RETURN_CURRENT_ERROR; if (run_pkg_install(mport, bundle, pkg, "POST-INSTALL") != MPORT_OK) @@ -996,148 +990,3 @@ run_pkg_install(mportInstance *mport, mportBundleRead *bundle, mportPackageMeta return MPORT_OK; } - - -static int -display_pkg_msg(mportInstance *mport, mportBundleRead *bundle, mportPackageMeta *pkg) -{ - mportPackageMessage packageMessage; - pkg_message_t expectedType; - - packageMessage.minimum_version = NULL; - packageMessage.maximum_version = NULL; - packageMessage.str = NULL; - packageMessage.prev = NULL; - packageMessage.next = NULL; - packageMessage.type = PKG_MESSAGE_ALWAYS; // default type - - if (load_pkg_msg(mport, bundle, pkg, &packageMessage) != MPORT_OK) { - RETURN_CURRENT_ERROR; - } - - switch (pkg->action) { - case MPORT_ACTION_INSTALL: - expectedType = PKG_MESSAGE_INSTALL; - break; - case MPORT_ACTION_UPDATE: - case MPORT_ACTION_UPGRADE: - expectedType = PKG_MESSAGE_UPGRADE; - break; - case MPORT_ACTION_DELETE: - expectedType = PKG_MESSAGE_REMOVE; - break; - default: - expectedType = PKG_MESSAGE_INSTALL; - } - - if (packageMessage.type == expectedType || packageMessage.type == PKG_MESSAGE_ALWAYS) { - if (packageMessage.str != NULL && packageMessage.str[0] != '\0') - mport_call_msg_cb(mport, "%s", packageMessage.str); - } - - free(packageMessage.str); - - return MPORT_OK; -} - - -static int -load_pkg_msg(mportInstance *mport, mportBundleRead *bundle, mportPackageMeta *pkg, mportPackageMessage *packageMessage) -{ - char filename[FILENAME_MAX]; - char *buf; - struct stat st; - FILE *file; - struct ucl_parser *parser; - ucl_object_t *obj; - - (void) snprintf(filename, FILENAME_MAX, "%s/%s/%s-%s/%s", bundle->tmpdir, MPORT_STUB_INFRA_DIR, pkg->name, - pkg->version, MPORT_MESSAGE_FILE); - - if (stat(filename, &st) == -1) { - /* if we couldn't stat the file, we assume there isn't a pkg-msg */ - return MPORT_OK; - } - - if ((file = fopen(filename, "re")) == NULL) - RETURN_ERRORX(MPORT_ERR_FATAL, "Couldn't open %s: %s", filename, strerror(errno)); - - if ((buf = (char *) calloc((size_t)(st.st_size + 1), sizeof(char))) == NULL) - RETURN_ERROR(MPORT_ERR_FATAL, "Out of memory."); - - if (fread(buf, sizeof(char), (size_t) st.st_size, file) != (size_t) st.st_size) { - free(buf); - RETURN_ERRORX(MPORT_ERR_FATAL, "Read error: %s", strerror(errno)); - } - - buf[st.st_size] = '\0'; - - if (buf[0] == '[') { - parser = ucl_parser_new(0); - // remove leading/trailing array entries - buf[0] = ' '; - buf[st.st_size-1] = '\0'; - - if (ucl_parser_add_chunk(parser, (const unsigned char*)buf, st.st_size)) { - obj = ucl_parser_get_object(parser); - ucl_parser_free(parser); - free(buf); - - packageMessage = pkg_message_from_ucl(mport, obj, packageMessage); - ucl_object_unref(obj); - - return packageMessage == NULL ? MPORT_ERR_FATAL : MPORT_OK; - } - - ucl_parser_free (parser); - } else { - /*obj = ucl_object_fromlstring(buf, st.st_size); - packageMessage = pkg_message_from_ucl(mport, obj, packageMessage); - ucl_object_unref(obj); */ - packageMessage->str = strdup(buf); - packageMessage->type = PKG_MESSAGE_ALWAYS; - free(buf); - } - - return MPORT_OK; -} - -static mportPackageMessage * -pkg_message_from_ucl(mportInstance *mport, const ucl_object_t *obj, mportPackageMessage *msg) -{ - const ucl_object_t *enhanced; - - if (ucl_object_type(obj) == UCL_STRING) { - msg->str = strdup(ucl_object_tostring(obj)); - } else if (ucl_object_type(obj) == UCL_OBJECT) { - /* New format of pkg message */ - enhanced = ucl_object_find_key(obj, "message"); - if (enhanced == NULL || ucl_object_type(enhanced) != UCL_STRING) { - return NULL; - } - msg->str = strdup(ucl_object_tostring(enhanced)); - - enhanced = ucl_object_find_key(obj, "minimum_version"); - if (enhanced != NULL && ucl_object_type(enhanced) == UCL_STRING) { - msg->minimum_version = strdup(ucl_object_tostring(enhanced)); - } - - enhanced = ucl_object_find_key(obj, "type"); - if (enhanced != NULL && ucl_object_type(enhanced) == UCL_STRING) { - const char *type = ucl_object_tostring(enhanced); - if (type != NULL) { - if (strcmp(type, "install") == 0) { - msg->type = PKG_MESSAGE_INSTALL; - } else if (strcmp(type, "upgrade") == 0) { - msg->type = PKG_MESSAGE_UPGRADE; - } else if (strcmp(type, "remove") == 0) { - msg->type = PKG_MESSAGE_REMOVE; - } else { - msg->type = PKG_MESSAGE_ALWAYS; - } - } - } - } - - return msg; -} diff --git a/contrib/mport/libmport/delete_primative.c b/contrib/mport/libmport/delete_primative.c index deeda3eb79..a635998939 100644 --- a/contrib/mport/libmport/delete_primative.c +++ b/contrib/mport/libmport/delete_primative.c @@ -335,6 +335,9 @@ mport_delete_primative(mportInstance *mport, mportPackageMeta *pack, int force) if (mport_db_do(mport->db, "DELETE FROM categories WHERE pkg=%Q", pack->name) != MPORT_OK) RETURN_CURRENT_ERROR; + if (mport_pkg_message_display(mport, pack) != MPORT_OK) + RETURN_CURRENT_ERROR; + if (delete_pkg_infra(mport, pack) != MPORT_OK) RETURN_CURRENT_ERROR; diff --git a/contrib/mport/libmport/info.c b/contrib/mport/libmport/info.c index b59466646b..4047ec7e5f 100644 --- a/contrib/mport/libmport/info.c +++ b/contrib/mport/libmport/info.c @@ -38,18 +38,18 @@ MPORT_PUBLIC_API char * mport_info(mportInstance *mport, const char *packageName) { - mportIndexEntry **indexEntry; - mportPackageMeta **packs; - mportIndexMovedEntry **movedEntries; + mportIndexEntry **indexEntry = NULL; + mportPackageMeta **packs = NULL; + mportIndexMovedEntry **movedEntries = NULL; char *status, *origin, *flavor, *deprecated; - char *os_release; - char *cpe; + char *os_release = NULL; + char *cpe = NULL; int locked = 0; int no_shlib_provided = 0; char *info_text = NULL; time_t expirationDate, installDate; - char *options; - char *desc; + char *options = NULL; + char *desc = NULL; mportAutomatic automatic; mportType type; char purl[256]; @@ -112,10 +112,11 @@ mport_info(mportInstance *mport, const char *packageName) { if (deprecated == NULL || deprecated[0] == '\0') { if (movedEntries != NULL && *movedEntries!= NULL && (*movedEntries)->date[0] != '\0') { deprecated = strdup("yes"); - } else { + } else { deprecated = strdup("no"); } } + expirationDate = (*packs)->expiration_date; if (expirationDate == 0 && movedEntries != NULL && *movedEntries!= NULL && (*movedEntries)->date[0] != '\0') { struct tm expDate; @@ -123,18 +124,24 @@ mport_info(mportInstance *mport, const char *packageName) { expirationDate = mktime(&expDate); } options = (*packs)->options; + if (options == NULL) { options = strdup(""); } + desc = (*packs)->desc; if (desc == NULL) { desc = strdup(""); } + automatic = (*packs)->automatic; installDate = (*packs)->install_date; type = (*packs)->type; flatsize = (*packs)->flatsize; - if (indexEntry != NULL) + + if (indexEntry == NULL || *indexEntry == NULL) + purl[0] = '\0'; + else if (packs != NULL && (*indexEntry)->pkgname != NULL && (*packs)->version != NULL) snprintf(purl, sizeof(purl), "pkg:mport/midnightbsd/%s@%s?arch=%s&osrel=%s", (*indexEntry)->pkgname, (*packs)->version, MPORT_ARCH, os_release); else purl[0] = '\0'; @@ -143,20 +150,38 @@ mport_info(mportInstance *mport, const char *packageName) { char flatsize_str[8]; humanize_number(flatsize_str, sizeof(flatsize_str), flatsize, "B", HN_AUTOSCALE, HN_DECIMAL | HN_IEC_PREFIXES); - if (packs != NULL) { - asprintf(&info_text, + if (indexEntry == NULL || *indexEntry == NULL) { + asprintf(&info_text, + "%s-%s\n" + "Name : %s\nVersion : %s\nLatest : %s\nLicenses : %s\nOrigin : %s\n" + "Flavor : %s\nOS : %s\n" + "CPE : %s\nPURL : %s\nLocked : %s\nPrime : %s\nShared library : %s\nDeprecated : %s\nExpiration Date : %s\nInstall Date : %s" + "Comment : %s\nOptions : %s\nType : %s\nFlat Size : %s\nDescription :\n%s\n", + (*packs)->name, (*packs)->version, + (*packs)->name, status, "", "", origin, + flavor, os_release, + cpe, purl, locked ? "yes" : "no", automatic == MPORT_EXPLICIT ? "yes" : "no", no_shlib_provided ? "yes" : "no", deprecated, + expirationDate == 0 ? "" : ctime(&expirationDate), + installDate == 0 ? "\n" : ctime(&installDate), + "", + options, + type == MPORT_TYPE_APP ? "Application" : "System", + flatsize_str, + desc); + } else if (packs != NULL) { + asprintf(&info_text, "%s-%s\n" "Name : %s\nVersion : %s\nLatest : %s\nLicenses : %s\nOrigin : %s\n" "Flavor : %s\nOS : %s\n" "CPE : %s\nPURL : %s\nLocked : %s\nPrime : %s\nShared library : %s\nDeprecated : %s\nExpiration Date : %s\nInstall Date : %s" "Comment : %s\nOptions : %s\nType : %s\nFlat Size : %s\nDescription :\n%s\n", (*packs)->name, (*packs)->version, - (*packs)->name, status, indexEntry != NULL ? (*indexEntry)->version : "", indexEntry != NULL ? (*indexEntry)->license : "", origin, + (*packs)->name, status, indexEntry == NULL ? "": (*indexEntry)->version, indexEntry == NULL ? "" : (*indexEntry)->license, origin, flavor, os_release, cpe, purl, locked ? "yes" : "no", automatic == MPORT_EXPLICIT ? "yes" : "no", no_shlib_provided ? "yes" : "no", deprecated, expirationDate == 0 ? "" : ctime(&expirationDate), installDate == 0 ? "\n" : ctime(&installDate), - indexEntry != NULL ? (*indexEntry)->comment : "", + indexEntry == NULL ? "" : (*indexEntry)->comment, options, type == MPORT_TYPE_APP ? "Application" : "System", flatsize_str, diff --git a/contrib/mport/libmport/install_primative.c b/contrib/mport/libmport/install_primative.c index 00565c18e8..fc663523a0 100644 --- a/contrib/mport/libmport/install_primative.c +++ b/contrib/mport/libmport/install_primative.c @@ -32,6 +32,78 @@ #include #include +static char ** get_dependencies(mportInstance *mport, mportPackageMeta *pack); + +static char ** +get_dependencies(mportInstance *mport, mportPackageMeta *pkg) +{ + sqlite3_stmt *stmt; + int ret, count = 0; + char **dependencies; + + if (mport_db_prepare(mport->db, &stmt, "SELECT COUNT(*) FROM stub.depends WHERE pkg=%Q", + pkg->name) != MPORT_OK) { + sqlite3_finalize(stmt); + return NULL; + } + + ret = sqlite3_step(stmt); + + switch (ret) { + case SQLITE_ROW: + count = sqlite3_column_int(stmt, 0); + sqlite3_finalize(stmt); + break; + case SQLITE_DONE: + sqlite3_finalize(stmt); + SET_ERROR(MPORT_ERR_FATAL, "SQLite returned no rows for a COUNT(*) select."); + return NULL; + default: + sqlite3_finalize(stmt); + SET_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(mport->db)); + return NULL; + } + + if ((dependencies = (char **)calloc(count + 1, sizeof(char *))) == NULL) + return NULL; + + if (mport_db_prepare(mport->db, &stmt, + "SELECT depend_pkgname, depend_pkgversion FROM stub.depends WHERE pkg=%Q", + pkg->name) != MPORT_OK) { + sqlite3_finalize(stmt); + return NULL; + } + + int i = 0; + while (1) { + const char *depend_pkg, *depend_version; + + ret = sqlite3_step(stmt); + + if (ret == SQLITE_ROW) { + depend_pkg = sqlite3_column_text(stmt, 0); + depend_version = sqlite3_column_text(stmt, 1); + asprintf(&dependencies[i], "%s-%s", depend_pkg, depend_version); + i++; + } else if (ret == SQLITE_DONE) { + /* No more dependencies to check. */ + sqlite3_finalize(stmt); + break; + } else { + SET_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(mport->db)); + sqlite3_finalize(stmt); + return NULL; + } + + if (i == count) + break; + } + + return dependencies; +} + + + MPORT_PUBLIC_API int mport_install_primative(mportInstance *mport, const char *filename, const char *prefix, mportAutomatic automatic) { @@ -39,6 +111,57 @@ mport_install_primative(mportInstance *mport, const char *filename, const char * mportPackageMeta **pkgs, *pkg; int i; bool error = false; + char **dependencies, **deps; + + /* There are two scenarios here. + 1. We are installing online with an index and have already fetched dependencies. + 2. We are installing from a local package file. Check if the dependencies are availaible in the + same directory that are missing. + */ + if (mport->offline) { + // temporarily open pkg file to get metadata. + if ((bundle = mport_bundle_read_new()) == NULL) + RETURN_ERROR(MPORT_ERR_FATAL, "Out of memory."); + + if (mport_bundle_read_init(bundle, filename) != MPORT_OK) + RETURN_CURRENT_ERROR; + + if (mport_bundle_read_prep_for_install(mport, bundle) != MPORT_OK) + RETURN_CURRENT_ERROR; + + if (mport_pkgmeta_read_stub(mport, &pkgs) != MPORT_OK) + RETURN_CURRENT_ERROR; + + if (mport_check_preconditions(mport, pkg, MPORT_PRECHECK_INSTALLED) != MPORT_OK) { + mport_call_msg_cb(mport, "%s-%s: already installed.", pkg->name, pkg->version); + return MPORT_OK; + } + if (mport_check_preconditions(mport, pkg, MPORT_PRECHECK_CONFLICTS) != MPORT_OK) { + mport_call_msg_cb(mport, "Unable to install %s-%s: %s", pkg->name, pkg->version, + mport_err_string()); + return MPORT_ERR_FATAL; + } + dependencies = get_dependencies(mport, pkg); + + // close so we can safely process depdendencies. + if (mport_bundle_read_finish(mport, bundle) != MPORT_OK) + return MPORT_ERR_FATAL; + + deps = dependencies; + char *dir = mport_directory(filename); + while (deps!= NULL) { + char *dep_filename; + asprintf(&dep_filename, "%s/%s.mport", dir, *deps); + if (dep_filename != NULL && mport_install_primative(mport, dep_filename, prefix, MPORT_AUTOMATIC)!= MPORT_OK) { + mport_call_msg_cb(mport, "Unable to install %s: %s", *deps, mport_err_string()); + return MPORT_ERR_FATAL; + } + free(dep_filename); + deps++; + } + free(dir); + free(dependencies); + } if ((bundle = mport_bundle_read_new()) == NULL) RETURN_ERROR(MPORT_ERR_FATAL, "Out of memory."); @@ -56,6 +179,7 @@ mport_install_primative(mportInstance *mport, const char *filename, const char * pkg = pkgs[i]; pkg->automatic = automatic; pkg->install_date = mport_get_time(); + pkg->action = MPORT_ACTION_INSTALL; if (prefix != NULL) { /* override the default prefix with the given prefix */ @@ -64,10 +188,8 @@ mport_install_primative(mportInstance *mport, const char *filename, const char * RETURN_ERROR(MPORT_ERR_FATAL, "Out of memory."); } - if ((mport_check_preconditions(mport, pkg, MPORT_PRECHECK_INSTALLED | MPORT_PRECHECK_DEPENDS | - MPORT_PRECHECK_CONFLICTS) != MPORT_OK) - || - (mport_bundle_read_install_pkg(mport, bundle, pkg) != MPORT_OK)) { + if ((mport_check_preconditions(mport, pkg, MPORT_PRECHECK_INSTALLED | MPORT_PRECHECK_DEPENDS | MPORT_PRECHECK_CONFLICTS) != MPORT_OK) + || (mport_bundle_read_install_pkg(mport, bundle, pkg) != MPORT_OK)) { mport_call_msg_cb(mport, "Unable to install %s-%s: %s", pkg->name, pkg->version, mport_err_string()); error = true; diff --git a/contrib/mport/libmport/instance.c b/contrib/mport/libmport/instance.c index 91688d5dae..c9e95b530d 100644 --- a/contrib/mport/libmport/instance.c +++ b/contrib/mport/libmport/instance.c @@ -56,6 +56,7 @@ mport_instance_init(mportInstance *mport, const char *root, const char *outputPa mport->noIndex = noIndex; mport->quiet = quiet; + mport->offline = false; if (root != NULL) { mport->root = strdup(root); diff --git a/contrib/mport/libmport/message.c b/contrib/mport/libmport/message.c new file mode 100644 index 0000000000..f46a720813 --- /dev/null +++ b/contrib/mport/libmport/message.c @@ -0,0 +1,208 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2013-2015, 2021, 2023 Lucas Holt + * Copyright (c) 2007-2009 Chris Reinhardt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "mport.h" +#include "mport_private.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int +mport_pkg_message_display(mportInstance *mport, mportPackageMeta *pkg) +{ + mportPackageMessage packageMessage; + pkg_message_t expectedType; + + packageMessage.minimum_version = NULL; + packageMessage.maximum_version = NULL; + packageMessage.str = NULL; + packageMessage.prev = NULL; + packageMessage.next = NULL; + packageMessage.type = PKG_MESSAGE_ALWAYS; // default type + + if (mport_pkg_message_load(mport, pkg, &packageMessage) != MPORT_OK) { + RETURN_CURRENT_ERROR; + } + + switch (pkg->action) { + case MPORT_ACTION_INSTALL: + expectedType = PKG_MESSAGE_INSTALL; + break; + case MPORT_ACTION_UPDATE: + case MPORT_ACTION_UPGRADE: + expectedType = PKG_MESSAGE_UPGRADE; + break; + case MPORT_ACTION_DELETE: + expectedType = PKG_MESSAGE_REMOVE; + break; + default: + expectedType = PKG_MESSAGE_INSTALL; + } + + /* Limit message display based on version if provided. */ + if (packageMessage.minimum_version != NULL && + mport_version_cmp(packageMessage.minimum_version, pkg->version) == 1) { + free(packageMessage.str); + return MPORT_OK; + } + + if (packageMessage.maximum_version != NULL && + mport_version_cmp(packageMessage.maximum_version, pkg->version) == -1) { + free(packageMessage.str); + return MPORT_OK; + } + + + if (packageMessage.type == expectedType || packageMessage.type == PKG_MESSAGE_ALWAYS) { + if (packageMessage.str != NULL && packageMessage.str[0] != '\0') + mport_call_msg_cb(mport, "%s", packageMessage.str); + } + + free(packageMessage.str); + + return MPORT_OK; +} + +int +mport_pkg_message_load( + mportInstance *mport, mportPackageMeta *pkg, mportPackageMessage *packageMessage) +{ + char filename[FILENAME_MAX]; + char *buf; + struct stat st; + FILE *file; + struct ucl_parser *parser; + ucl_object_t *obj; + + /* Assumes copy_metafile has run on install already */ + (void)snprintf(filename, FILENAME_MAX, "%s%s/%s-%s/%s", mport->root, MPORT_INST_INFRA_DIR, + pkg->name, pkg->version, MPORT_MESSAGE_FILE); + + if (stat(filename, &st) == -1) { + /* if we couldn't stat the file, we assume there isn't a pkg-msg */ + return MPORT_OK; + } + + if ((file = fopen(filename, "re")) == NULL) + RETURN_ERRORX(MPORT_ERR_FATAL, "Couldn't open %s: %s", filename, strerror(errno)); + + if ((buf = (char *)calloc((size_t)(st.st_size + 1), sizeof(char))) == NULL) + RETURN_ERROR(MPORT_ERR_FATAL, "Out of memory."); + + if (fread(buf, sizeof(char), (size_t)st.st_size, file) != (size_t)st.st_size) { + free(buf); + RETURN_ERRORX(MPORT_ERR_FATAL, "Read error: %s", strerror(errno)); + } + + buf[st.st_size] = '\0'; + + if (buf[0] == '[') { + parser = ucl_parser_new(0); + // remove leading/trailing array entries + buf[0] = ' '; + buf[st.st_size - 1] = '\0'; + + if (ucl_parser_add_chunk(parser, (const unsigned char *)buf, st.st_size)) { + obj = ucl_parser_get_object(parser); + ucl_parser_free(parser); + free(buf); + + packageMessage = mport_pkg_message_from_ucl(mport, obj, packageMessage); + ucl_object_unref(obj); + + return packageMessage == NULL ? MPORT_ERR_FATAL : MPORT_OK; + } + + ucl_parser_free(parser); + } else { + /*obj = ucl_object_fromlstring(buf, st.st_size); + packageMessage = mport_pkg_message_from_ucl(mport, obj, packageMessage); + ucl_object_unref(obj); */ + packageMessage->str = strdup(buf); + packageMessage->type = PKG_MESSAGE_ALWAYS; + free(buf); + } + + return MPORT_OK; +} + +mportPackageMessage * +mport_pkg_message_from_ucl(mportInstance *mport, const ucl_object_t *obj, mportPackageMessage *msg) +{ + const ucl_object_t *enhanced; + + if (ucl_object_type(obj) == UCL_STRING) { + msg->str = strdup(ucl_object_tostring(obj)); + } else if (ucl_object_type(obj) == UCL_OBJECT) { + /* New format of pkg message */ + enhanced = ucl_object_find_key(obj, "message"); + if (enhanced == NULL || ucl_object_type(enhanced) != UCL_STRING) { + return NULL; + } + msg->str = strdup(ucl_object_tostring(enhanced)); + + enhanced = ucl_object_find_key(obj, "minimum_version"); + if (enhanced != NULL && ucl_object_type(enhanced) == UCL_STRING) { + msg->minimum_version = strdup(ucl_object_tostring(enhanced)); + } + + enhanced = ucl_object_find_key(obj, "maximum_version"); + if (enhanced != NULL && ucl_object_type(enhanced) == UCL_STRING) { + msg->maximum_version = strdup(ucl_object_tostring(enhanced)); + } + + enhanced = ucl_object_find_key(obj, "type"); + if (enhanced != NULL && ucl_object_type(enhanced) == UCL_STRING) { + const char *type = ucl_object_tostring(enhanced); + if (type != NULL) { + if (strcmp(type, "install") == 0) { + msg->type = PKG_MESSAGE_INSTALL; + } else if (strcmp(type, "upgrade") == 0) { + msg->type = PKG_MESSAGE_UPGRADE; + } else if (strcmp(type, "remove") == 0) { + msg->type = PKG_MESSAGE_REMOVE; + } else { + msg->type = PKG_MESSAGE_ALWAYS; + } + } + } + } + + return msg; +} diff --git a/contrib/mport/libmport/mport.h b/contrib/mport/libmport/mport.h index bbe131eaff..55eb33f564 100644 --- a/contrib/mport/libmport/mport.h +++ b/contrib/mport/libmport/mport.h @@ -56,6 +56,7 @@ typedef struct { char *root; char *outputPath; /* Download directory */ bool noIndex; /* Do not fetch mport index */ + bool offline; /* Installing packages from local files, etc. */ bool quiet; mport_msg_cb msg_cb; mport_progress_init_cb progress_init_cb; diff --git a/contrib/mport/libmport/mport_private.h b/contrib/mport/libmport/mport_private.h index a02da5107f..50bf86ba6d 100644 --- a/contrib/mport/libmport/mport_private.h +++ b/contrib/mport/libmport/mport_private.h @@ -43,6 +43,7 @@ #endif #include #include +#include #include "bzlib.h" #define MPORT_PUBLIC_API @@ -50,7 +51,7 @@ #define MPORT_MASTER_VERSION 11 #define MPORT_BUNDLE_VERSION 6 #define MPORT_BUNDLE_VERSION_STR "6" -#define MPORT_VERSION "2.4.7" +#define MPORT_VERSION "2.4.8" #define MPORT_SETTING_MIRROR_REGION "mirror_region" #define MPORT_SETTING_TARGET_OS "target_os" @@ -95,6 +96,7 @@ char* mport_hash_file(const char *); int mport_copy_file(const char *, const char *); uid_t mport_get_uid(const char *); gid_t mport_get_gid(const char *); +char* mport_directory(const char *path); int mport_rmtree(const char *); int mport_mkdir(const char *); int mport_mkdirp(char *, mode_t); @@ -150,6 +152,10 @@ int mport_update_down(mportInstance *, mportPackageMeta *, struct ohash_info *, void mport_version_cmp_sqlite(sqlite3_context *, int, sqlite3_value **); int mport_version_require_check(const char *, const char *); +int mport_pkg_message_display(mportInstance *, mportPackageMeta *); +int mport_pkg_message_load(mportInstance *, mportPackageMeta *, mportPackageMessage *); +mportPackageMessage* mport_pkg_message_from_ucl(mportInstance *, const ucl_object_t *, mportPackageMessage *); + #define RETURN_CURRENT_ERROR return mport_err_code() #define RETURN_ERROR(code, msg) return mport_set_errx((code), "Error at %s:(%d): %s", __FILE__, __LINE__, (msg)) #define SET_ERROR(code, msg) mport_set_errx((code), "Error at %s:(%d): %s", __FILE__, __LINE__, (msg)) diff --git a/contrib/mport/libmport/pkgmeta.c b/contrib/mport/libmport/pkgmeta.c index 672c12bd4d..ade44df10f 100644 --- a/contrib/mport/libmport/pkgmeta.c +++ b/contrib/mport/libmport/pkgmeta.c @@ -1,7 +1,7 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * - * Copyright (c) 2010, 2021 Lucas Holt + * Copyright (c) 2010, 2021, 2023 Lucas Holt * Copyright (c) 2007-2009 Chris Reinhardt * All rights reserved. * @@ -36,20 +36,23 @@ #include "mport.h" #include "mport_private.h" +enum count_type { ALL, LOCKED, WHERE }; + static int populate_meta_from_stmt(mportPackageMeta *, sqlite3 *, sqlite3_stmt *); static int populate_vec_from_stmt(mportPackageMeta ***, int, sqlite3 *, sqlite3_stmt *); - +static int mport_pkgmeta_count(mportInstance *mport, enum count_type type, char *where); /* Package meta-data creation and destruction */ -MPORT_PUBLIC_API mportPackageMeta* -mport_pkgmeta_new(void) +MPORT_PUBLIC_API mportPackageMeta * +mport_pkgmeta_new(void) { - mportPackageMeta *pack = (mportPackageMeta *) calloc(1, sizeof(mportPackageMeta)); + mportPackageMeta *pack = (mportPackageMeta *)calloc(1, sizeof(mportPackageMeta)); if (pack == NULL) { return NULL; } - /* these items aren't always initialized from other sources and are needed to be an empty string for sqlite use. */ + /* these items aren't always initialized from other sources and are needed to be an empty + * string for sqlite use. */ pack->cpe = malloc(1 * sizeof(char)); pack->cpe[0] = '\0'; @@ -81,7 +84,7 @@ mport_pkgmeta_free(mportPackageMeta *pack) free(pack->comment); pack->comment = NULL; - + free(pack->desc); pack->desc = NULL; @@ -135,7 +138,6 @@ mport_pkgmeta_vec_free(mportPackageMeta **vec) pkgmetas = NULL; } - /* mport_pkgmeta_read_stub(mportInstance *mport, mportPackageMeta ***pack) * * Allocates and populates a vector of mportPackageMeta structs from the stub database @@ -145,58 +147,63 @@ mport_pkgmeta_vec_free(mportPackageMeta **vec) int mport_pkgmeta_read_stub(mportInstance *mport, mportPackageMeta ***ref) { - sqlite3_stmt *stmt; - sqlite3 *db = mport->db; - int len, ret; + sqlite3_stmt *stmt; + sqlite3 *db = mport->db; + int len; + int ret; - if (mport_db_prepare(db, &stmt, "SELECT COUNT(*) FROM stub.packages") != MPORT_OK) - RETURN_CURRENT_ERROR; + if (mport_db_prepare(db, &stmt, "SELECT COUNT(*) FROM stub.packages") != MPORT_OK) + RETURN_CURRENT_ERROR; - if (sqlite3_step(stmt) != SQLITE_ROW) { - sqlite3_finalize(stmt); - RETURN_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(db)); - } + if (sqlite3_step(stmt) != SQLITE_ROW) { + sqlite3_finalize(stmt); + RETURN_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(db)); + } - len = sqlite3_column_int(stmt, 0); - sqlite3_finalize(stmt); + len = sqlite3_column_int(stmt, 0); + sqlite3_finalize(stmt); - if (len == 0) { - /* a stub should have packages! */ - RETURN_ERROR(MPORT_ERR_FATAL, "stub database contains no packages."); - } + if (len == 0) { + /* a stub should have packages! */ + RETURN_ERROR(MPORT_ERR_FATAL, "stub database contains no packages."); + } - // this is nasty, but we want to maintain backward compatibility with older packages. - if (mport_db_prepare(db, &stmt, - "SELECT pkg, version, origin, lang, prefix, comment, os_release, cpe, 0 as locked, deprecated, expiration_date, no_provide_shlib, flavor, 0 as automatic, 0 as install_date, type, flatsize FROM stub.packages") != MPORT_OK) { - sqlite3_finalize(stmt); + // this is nasty, but we want to maintain backward compatibility with older packages. + if (mport_db_prepare(db, &stmt, + "SELECT pkg, version, origin, lang, prefix, comment, os_release, cpe, 0 as locked, deprecated, expiration_date, no_provide_shlib, flavor, 0 as automatic, 0 as install_date, type, flatsize FROM stub.packages") != + MPORT_OK) { + sqlite3_finalize(stmt); - if (mport_db_prepare(db, &stmt, - "SELECT pkg, version, origin, lang, prefix, comment, os_release, cpe, 0 as locked, deprecated, expiration_date, no_provide_shlib, flavor, 0 as automatic, 0 as install_date, type, 0 as flatsize FROM stub.packages") != MPORT_OK) { + if (mport_db_prepare(db, &stmt, + "SELECT pkg, version, origin, lang, prefix, comment, os_release, cpe, 0 as locked, deprecated, expiration_date, no_provide_shlib, flavor, 0 as automatic, 0 as install_date, type, 0 as flatsize FROM stub.packages") != + MPORT_OK) { sqlite3_finalize(stmt); if (mport_db_prepare(db, &stmt, - "SELECT pkg, version, origin, lang, prefix, comment, os_release, cpe, 0 as locked, deprecated, expiration_date, no_provide_shlib, flavor, 0 as automatic, 0 as install_date, 0 as type, 0 as flatsize FROM stub.packages") != MPORT_OK) { + "SELECT pkg, version, origin, lang, prefix, comment, os_release, cpe, 0 as locked, deprecated, expiration_date, no_provide_shlib, flavor, 0 as automatic, 0 as install_date, 0 as type, 0 as flatsize FROM stub.packages") != + MPORT_OK) { sqlite3_finalize(stmt); RETURN_CURRENT_ERROR; } - } - } + } + } - ret = populate_vec_from_stmt(ref, len, db, stmt); + ret = populate_vec_from_stmt(ref, len, db, stmt); - sqlite3_finalize(stmt); + sqlite3_finalize(stmt); - return ret; + return ret; } -/* mport_pkgmeta_search_master(mportInstance *mport, mportPacakgeMeta ***pack, const char *where, ...) +/* mport_pkgmeta_search_master(mportInstance *mport, mportPacakgeMeta ***pack, const char *where, + * ...) * * Allocate and populate the package meta for the given package from the * master database. - * + * * 'where' and the vargs are used to be build a where clause. For example to search by * name: - * + * * mport_pkgmeta_search_master(mport, &packvec, "pkg=%Q", name); * * or by origin @@ -208,251 +215,263 @@ mport_pkgmeta_read_stub(mportInstance *mport, mportPackageMeta ***ref) MPORT_PUBLIC_API int mport_pkgmeta_search_master(mportInstance *mport, mportPackageMeta ***ref, const char *fmt, ...) { - va_list args; - sqlite3_stmt *stmt; - int ret, len; - char *where; - sqlite3 *db = mport->db; - - va_start(args, fmt); - where = sqlite3_vmprintf(fmt, args); - va_end(args); - - if (where == NULL) - RETURN_ERROR(MPORT_ERR_FATAL, "Could not build where clause"); - - if (mport == NULL) - RETURN_ERROR(MPORT_ERR_FATAL, "mport not initialized"); - - if (mport_db_prepare(db, &stmt, "SELECT count(*) FROM packages WHERE %s", where) != MPORT_OK) { - sqlite3_finalize(stmt); - RETURN_CURRENT_ERROR; - } - - if (sqlite3_step(stmt) != SQLITE_ROW) { - sqlite3_finalize(stmt); - RETURN_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(db)); - } - - len = sqlite3_column_int(stmt, 0); - sqlite3_finalize(stmt); - - if (len == 0) { - sqlite3_free(where); - *ref = NULL; - return MPORT_OK; - } - - if (mport_db_prepare(db, &stmt, - "SELECT pkg, version, origin, lang, prefix, comment, os_release, cpe, locked, deprecated, expiration_date, no_provide_shlib, flavor, automatic, install_date, type, flatsize FROM packages WHERE %s", - where) != MPORT_OK) { - sqlite3_finalize(stmt); - RETURN_CURRENT_ERROR; - } - - ret = populate_vec_from_stmt(ref, len, db, stmt); - - sqlite3_free(where); - sqlite3_finalize(stmt); - - return ret; + va_list args; + sqlite3_stmt *stmt; + int ret; + int len; + char *where; + sqlite3 *db = mport->db; + + va_start(args, fmt); + where = sqlite3_vmprintf(fmt, args); + va_end(args); + + if (where == NULL) + RETURN_ERROR(MPORT_ERR_FATAL, "Could not build where clause"); + + if (mport == NULL) + RETURN_ERROR(MPORT_ERR_FATAL, "mport not initialized"); + + len = mport_pkgmeta_count(mport, WHERE, where); + + if (len == 0) { + sqlite3_free(where); + *ref = NULL; + return MPORT_OK; + } + + if (mport_db_prepare(db, &stmt, + "SELECT pkg, version, origin, lang, prefix, comment, os_release, cpe, locked, deprecated, expiration_date, no_provide_shlib, flavor, automatic, install_date, type, flatsize FROM packages WHERE %s", + where) != MPORT_OK) { + sqlite3_finalize(stmt); + RETURN_CURRENT_ERROR; + } + + ret = populate_vec_from_stmt(ref, len, db, stmt); + + sqlite3_free(where); + sqlite3_finalize(stmt); + + return ret; } +static int +mport_pkgmeta_count(mportInstance *mport, enum count_type type, char *where) +{ + sqlite3_stmt *stmt = NULL; + int len = 0; + char *sql = NULL; + + if (type == ALL) + sql = "SELECT count(*) FROM packages"; + else if (type == LOCKED) + sql = "SELECT count(*) FROM packages WHERE locked = 1"; + else if (type == WHERE) + sql = "SELECT count(*) FROM packages WHERE %s"; + + if (mport == NULL) return len; + + if (type == WHERE && where != NULL) { + if (mport_db_prepare(mport->db, &stmt, sql, where) != MPORT_OK) { + sqlite3_finalize(stmt); + return len; + } + } else { + if (mport_db_prepare(mport->db, &stmt, sql) != MPORT_OK) { + sqlite3_finalize(stmt); + return len; + } + } + + if (sqlite3_step(stmt) != SQLITE_ROW) { + sqlite3_finalize(stmt); + return len; + } + + len = sqlite3_column_int(stmt, 0); + sqlite3_finalize(stmt); + + return len; +} /* int mport_pkgmeta_list(mportInstance *mport, mportPackageMeta ***ref) * * List all packages currently installed - * + * * pack is set to NULL and MPORT_OK is returned if no packages where found. */ MPORT_PUBLIC_API int mport_pkgmeta_list(mportInstance *mport, mportPackageMeta ***ref) { - sqlite3_stmt *stmt; - int ret, len; - - if (mport == NULL) - RETURN_ERROR(MPORT_ERR_FATAL, "mport not initialized"); + sqlite3_stmt *stmt; + int ret; + int len; - sqlite3 *db = mport->db; + if (mport == NULL) + RETURN_ERROR(MPORT_ERR_FATAL, "mport not initialized"); - if (mport_db_prepare(db, &stmt, "SELECT count(*) FROM packages") != MPORT_OK) { - sqlite3_finalize(stmt); - RETURN_CURRENT_ERROR; - } + sqlite3 *db = mport->db; - if (sqlite3_step(stmt) != SQLITE_ROW) { - sqlite3_finalize(stmt); - RETURN_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(db)); - } + len = mport_pkgmeta_count(mport, ALL, NULL); - len = sqlite3_column_int(stmt, 0); - sqlite3_finalize(stmt); - - if (len == 0) { - *ref = NULL; - return MPORT_OK; - } + if (len == 0) { + *ref = NULL; + return MPORT_OK; + } - if (mport_db_prepare(db, &stmt, - "SELECT pkg, version, origin, lang, prefix, comment, os_release, cpe, locked, deprecated, expiration_date, no_provide_shlib, flavor, automatic, install_date, type, flatsize FROM packages ORDER BY pkg, version") != - MPORT_OK) { - sqlite3_finalize(stmt); - RETURN_CURRENT_ERROR; - } + if (mport_db_prepare(db, &stmt, + "SELECT pkg, version, origin, lang, prefix, comment, os_release, cpe, locked, deprecated, expiration_date, no_provide_shlib, flavor, automatic, install_date, type, flatsize FROM packages ORDER BY pkg, version") != + MPORT_OK) { + sqlite3_finalize(stmt); + RETURN_CURRENT_ERROR; + } - ret = populate_vec_from_stmt(ref, len, db, stmt); + ret = populate_vec_from_stmt(ref, len, db, stmt); - sqlite3_finalize(stmt); + sqlite3_finalize(stmt); - return ret; + return ret; } MPORT_PUBLIC_API int mport_pkgmeta_list_locked(mportInstance *mport, mportPackageMeta ***ref) { - sqlite3_stmt *stmt; - int ret, len; - - if (mport == NULL) - RETURN_ERROR(MPORT_ERR_FATAL, "mport not initialized"); - - sqlite3 *db = mport->db; + sqlite3_stmt *stmt; + int ret, len; - if (mport_db_prepare(db, &stmt, "SELECT count(*) FROM packages where locked=1") != MPORT_OK) { - sqlite3_finalize(stmt); - RETURN_CURRENT_ERROR; - } + if (mport == NULL) + RETURN_ERROR(MPORT_ERR_FATAL, "mport not initialized"); - if (sqlite3_step(stmt) != SQLITE_ROW) { - sqlite3_finalize(stmt); - RETURN_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(db)); - } + sqlite3 *db = mport->db; - len = sqlite3_column_int(stmt, 0); - sqlite3_finalize(stmt); + len = mport_pkgmeta_count(mport, LOCKED, NULL); - if (len == 0) { - *ref = NULL; - return MPORT_OK; - } + if (len == 0) { + *ref = NULL; + return MPORT_OK; + } - if (mport_db_prepare(db, &stmt, - "SELECT pkg, version, origin, lang, prefix, comment, os_release, cpe, locked, deprecated, expiration_date, no_provide_shlib, flavor, automatic, install_date, type, flatsize FROM packages where locked=1 ORDER BY pkg, version") != - MPORT_OK) { - sqlite3_finalize(stmt); - RETURN_CURRENT_ERROR; - } + if (mport_db_prepare(db, &stmt, + "SELECT pkg, version, origin, lang, prefix, comment, os_release, cpe, locked, deprecated, expiration_date, no_provide_shlib, flavor, automatic, install_date, type, flatsize FROM packages where locked=1 ORDER BY pkg, version") != + MPORT_OK) { + sqlite3_finalize(stmt); + RETURN_CURRENT_ERROR; + } - ret = populate_vec_from_stmt(ref, len, db, stmt); + ret = populate_vec_from_stmt(ref, len, db, stmt); - sqlite3_finalize(stmt); + sqlite3_finalize(stmt); - return ret; + return ret; } -/* mport_pkgmeta_get_downdepends(mportInstance *mport, mportPackageMeta *pkg, mportPackageMeta ***pkg_vec) - * - * Populate the depends of a pkg using the data in the master database. +/* mport_pkgmeta_get_downdepends(mportInstance *mport, mportPackageMeta *pkg, mportPackageMeta + * ***pkg_vec) + * + * Populate the depends of a pkg using the data in the master database. */ MPORT_PUBLIC_API int -mport_pkgmeta_get_downdepends(mportInstance *mport, mportPackageMeta *pkg, mportPackageMeta ***pkg_vec_p) +mport_pkgmeta_get_downdepends( + mportInstance *mport, mportPackageMeta *pkg, mportPackageMeta ***pkg_vec_p) { - int count = 0; - int ret; - sqlite3_stmt *stmt; - - if (mport == NULL) - RETURN_ERROR(MPORT_ERR_FATAL, "mport not initialized"); - - /* if the dependencies are set, there's nothing for us to do */ - if (mport_db_prepare(mport->db, &stmt, "SELECT COUNT(*) FROM depends WHERE pkg=%Q", pkg->name) != MPORT_OK) { - sqlite3_finalize(stmt); - RETURN_CURRENT_ERROR; - } - - if (sqlite3_step(stmt) != SQLITE_ROW) { - sqlite3_finalize(stmt); - RETURN_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(mport->db)); - } - - count = sqlite3_column_int(stmt, 0); - sqlite3_finalize(stmt); - - if (count == 0) { - *pkg_vec_p = NULL; - return MPORT_OK; - } - - if (mport_db_prepare(mport->db, &stmt, - "SELECT packages.pkg, packages.version, packages.origin, packages.lang, packages.prefix, packages.comment, packages.os_release, packages.cpe, packages.locked, packages.deprecated, packages.expiration_date, packages.no_provide_shlib, packages.flavor, packages.automatic, packages.install_date, packages.type, packages.flatsize FROM packages,depends WHERE packages.pkg=depends.depend_pkgname AND depends.pkg=%Q", - pkg->name) != MPORT_OK) { - sqlite3_finalize(stmt); - RETURN_CURRENT_ERROR; - } - - ret = populate_vec_from_stmt(pkg_vec_p, count, mport->db, stmt); - - sqlite3_finalize(stmt); - return ret; + int count = 0; + int ret; + sqlite3_stmt *stmt; + + if (mport == NULL) + RETURN_ERROR(MPORT_ERR_FATAL, "mport not initialized"); + + /* if the dependencies are set, there's nothing for us to do */ + if (mport_db_prepare(mport->db, &stmt, "SELECT COUNT(*) FROM depends WHERE pkg=%Q", + pkg->name) != MPORT_OK) { + sqlite3_finalize(stmt); + RETURN_CURRENT_ERROR; + } + + if (sqlite3_step(stmt) != SQLITE_ROW) { + sqlite3_finalize(stmt); + RETURN_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(mport->db)); + } + + count = sqlite3_column_int(stmt, 0); + sqlite3_finalize(stmt); + + if (count == 0) { + *pkg_vec_p = NULL; + return MPORT_OK; + } + + if (mport_db_prepare(mport->db, &stmt, + "SELECT packages.pkg, packages.version, packages.origin, packages.lang, packages.prefix, packages.comment, packages.os_release, packages.cpe, packages.locked, packages.deprecated, packages.expiration_date, packages.no_provide_shlib, packages.flavor, packages.automatic, packages.install_date, packages.type, packages.flatsize FROM packages,depends WHERE packages.pkg=depends.depend_pkgname AND depends.pkg=%Q", + pkg->name) != MPORT_OK) { + sqlite3_finalize(stmt); + RETURN_CURRENT_ERROR; + } + + ret = populate_vec_from_stmt(pkg_vec_p, count, mport->db, stmt); + + sqlite3_finalize(stmt); + return ret; } -/* mport_pkgmeta_get_updepends(mportInstance *mport, mportPackageMeta *pkg, mportPackageMeta ***pkg_vec) - * - * Populate the upwards depends of a pkg using the data in the master database. +/* mport_pkgmeta_get_updepends(mportInstance *mport, mportPackageMeta *pkg, mportPackageMeta + * ***pkg_vec) + * + * Populate the upwards depends of a pkg using the data in the master database. */ MPORT_PUBLIC_API int -mport_pkgmeta_get_updepends(mportInstance *mport, mportPackageMeta *pkg, mportPackageMeta ***pkg_vec_p) +mport_pkgmeta_get_updepends( + mportInstance *mport, mportPackageMeta *pkg, mportPackageMeta ***pkg_vec_p) { - int count = 0; - int ret; - sqlite3_stmt *stmt; - - if (mport == NULL) - RETURN_ERROR(MPORT_ERR_FATAL, "mport not initialized"); - - /* if the depends are set, there's nothing for us to do */ - if (mport_db_prepare(mport->db, &stmt, "SELECT COUNT(*) FROM depends WHERE depend_pkgname=%Q", pkg->name) != MPORT_OK) { - sqlite3_finalize(stmt); - RETURN_CURRENT_ERROR; - } - - if (sqlite3_step(stmt) != SQLITE_ROW) { - sqlite3_finalize(stmt); - RETURN_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(mport->db)); - } - - count = sqlite3_column_int(stmt, 0); - sqlite3_finalize(stmt); - - if (count == 0) { - *pkg_vec_p = NULL; - return MPORT_OK; - } - - if (mport_db_prepare(mport->db, &stmt, - "SELECT packages.pkg, packages.version, packages.origin, packages.lang, packages.prefix, packages.comment, packages.os_release, packages.cpe, packages.locked, packages.deprecated, packages.expiration_date, packages.no_provide_shlib, packages.flavor, packages.automatic, packages.install_date, packages.type, packages.flatsize FROM packages,depends WHERE packages.pkg=depends.pkg AND depends.depend_pkgname=%Q", - pkg->name) != MPORT_OK) { - sqlite3_finalize(stmt); - RETURN_CURRENT_ERROR; - } - - ret = populate_vec_from_stmt(pkg_vec_p, count, mport->db, stmt); - - sqlite3_finalize(stmt); - return ret; -} + int count = 0; + int ret; + sqlite3_stmt *stmt; + + if (mport == NULL) + RETURN_ERROR(MPORT_ERR_FATAL, "mport not initialized"); + + /* if the depends are set, there's nothing for us to do */ + if (mport_db_prepare(mport->db, &stmt, + "SELECT COUNT(*) FROM depends WHERE depend_pkgname=%Q", pkg->name) != MPORT_OK) { + sqlite3_finalize(stmt); + RETURN_CURRENT_ERROR; + } + + if (sqlite3_step(stmt) != SQLITE_ROW) { + sqlite3_finalize(stmt); + RETURN_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(mport->db)); + } + + count = sqlite3_column_int(stmt, 0); + sqlite3_finalize(stmt); + + if (count == 0) { + *pkg_vec_p = NULL; + return MPORT_OK; + } + + if (mport_db_prepare(mport->db, &stmt, + "SELECT packages.pkg, packages.version, packages.origin, packages.lang, packages.prefix, packages.comment, packages.os_release, packages.cpe, packages.locked, packages.deprecated, packages.expiration_date, packages.no_provide_shlib, packages.flavor, packages.automatic, packages.install_date, packages.type, packages.flatsize FROM packages,depends WHERE packages.pkg=depends.pkg AND depends.depend_pkgname=%Q", + pkg->name) != MPORT_OK) { + sqlite3_finalize(stmt); + RETURN_CURRENT_ERROR; + } + ret = populate_vec_from_stmt(pkg_vec_p, count, mport->db, stmt); + + sqlite3_finalize(stmt); + return ret; +} /* mport_pkgmeta_logevent(mport, pkg, "Hi there!"); * * Create an entry in the log table for this pkg (and version), using the given message. */ int -mport_pkgmeta_logevent(mportInstance *mport, mportPackageMeta *pkg, const char *msg) +mport_pkgmeta_logevent(mportInstance *mport, mportPackageMeta *pkg, const char *msg) { struct timespec now; - + if (clock_gettime(CLOCK_REALTIME, &now) != 0) { RETURN_ERROR(MPORT_ERR_FATAL, strerror(errno)); } @@ -465,10 +484,10 @@ mport_pkgmeta_logevent(mportInstance *mport, mportPackageMeta *pkg, const char * if (msg == NULL) RETURN_ERROR(MPORT_ERR_WARN, "null message to log"); - - return mport_db_do(mport->db, - "INSERT INTO log (pkg, version, date, msg) VALUES (%s,%s,%i,%s)", - pkg->name, pkg->version, now.tv_sec, msg); + + return mport_db_do(mport->db, + "INSERT INTO log (pkg, version, date, msg) VALUES (%s,%s,%i,%s)", pkg->name, + pkg->version, now.tv_sec, msg); } static int @@ -476,29 +495,29 @@ populate_vec_from_stmt(mportPackageMeta ***ref, int len, sqlite3 *db, sqlite3_st { mportPackageMeta **vec; int done = 0; - vec = (mportPackageMeta **) calloc((1 + len), sizeof(mportPackageMeta *)); + vec = (mportPackageMeta **)calloc((1 + len), sizeof(mportPackageMeta *)); *ref = vec; while (!done) { switch (sqlite3_step(stmt)) { - case SQLITE_ROW: - *vec = mport_pkgmeta_new(); - if (*vec == NULL) { - RETURN_ERROR(MPORT_ERR_FATAL, "Couldn't allocate meta."); - } - if (populate_meta_from_stmt(*vec, db, stmt) != MPORT_OK) { - RETURN_CURRENT_ERROR; - } - vec++; - break; - case SQLITE_DONE: - /* set the last cell in the array to null */ - *vec = NULL; - done++; - break; - default: - RETURN_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(db)); - break; /* not reached */ + case SQLITE_ROW: + *vec = mport_pkgmeta_new(); + if (*vec == NULL) { + RETURN_ERROR(MPORT_ERR_FATAL, "Couldn't allocate meta."); + } + if (populate_meta_from_stmt(*vec, db, stmt) != MPORT_OK) { + RETURN_CURRENT_ERROR; + } + vec++; + break; + case SQLITE_DONE: + /* set the last cell in the array to null */ + *vec = NULL; + done++; + break; + default: + RETURN_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(db)); + break; /* not reached */ } } @@ -506,13 +525,12 @@ populate_vec_from_stmt(mportPackageMeta ***ref, int len, sqlite3 *db, sqlite3_st return MPORT_OK; } - static int populate_meta_from_stmt(mportPackageMeta *pack, sqlite3 *db, sqlite3_stmt *stmt) { const char *tmp = 0; - /* Copy pkg to pack->name */ + /* Copy pkg to pack->name */ if ((tmp = sqlite3_column_text(stmt, 0)) == NULL) RETURN_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(db)); @@ -561,8 +579,8 @@ populate_meta_from_stmt(mportPackageMeta *pack, sqlite3 *db, sqlite3_stmt *stmt) if ((pack->os_release = strdup(MPORT_OSVERSION)) == NULL) RETURN_ERROR(MPORT_ERR_FATAL, "Out of memory."); } else { - if ((pack->os_release = strdup(tmp)) == NULL) - RETURN_ERROR(MPORT_ERR_FATAL, "Out of memory."); + if ((pack->os_release = strdup(tmp)) == NULL) + RETURN_ERROR(MPORT_ERR_FATAL, "Out of memory."); } pack->locked = sqlite3_column_int(stmt, 8); @@ -570,7 +588,7 @@ populate_meta_from_stmt(mportPackageMeta *pack, sqlite3 *db, sqlite3_stmt *stmt) /* CPE */ if ((tmp = sqlite3_column_text(stmt, 7)) == NULL) { if ((pack->cpe = strdup("")) == NULL) - RETURN_ERROR(MPORT_ERR_FATAL, "Out of memory."); + RETURN_ERROR(MPORT_ERR_FATAL, "Out of memory."); } else { if ((pack->cpe = strdup(tmp)) == NULL) RETURN_ERROR(MPORT_ERR_FATAL, "Out of memory."); @@ -579,7 +597,7 @@ populate_meta_from_stmt(mportPackageMeta *pack, sqlite3 *db, sqlite3_stmt *stmt) /* deprecated */ if ((tmp = sqlite3_column_text(stmt, 9)) == NULL) { if ((pack->deprecated = strdup("")) == NULL) - RETURN_ERROR(MPORT_ERR_FATAL, "Out of memory."); + RETURN_ERROR(MPORT_ERR_FATAL, "Out of memory."); } else { if ((pack->deprecated = strdup(tmp)) == NULL) RETURN_ERROR(MPORT_ERR_FATAL, "Out of memory."); diff --git a/contrib/mport/libmport/upgrade.c b/contrib/mport/libmport/upgrade.c index 589a1e50ce..77a55657c3 100755 --- a/contrib/mport/libmport/upgrade.c +++ b/contrib/mport/libmport/upgrade.c @@ -104,6 +104,7 @@ mport_upgrade(mportInstance *mport) { if ((*movedEntries)->date[0] != '\0') { asprintf(&msg, "Package %s is deprecated with expiration date %s. Do you want to remove it?", (*packs)->name, (*movedEntries)->date); if ((mport->confirm_cb)(msg, "Delete", "Don't delete", 1) == MPORT_OK) { + (*packs)->action = MPORT_ACTION_DELETE; mport_delete_primative(mport, (*packs), true); ohash_insert(&h, slot, (*packs)->name); } @@ -113,7 +114,9 @@ mport_upgrade(mportInstance *mport) { if ((*movedEntries)->moved_to_pkgname != NULL && (*movedEntries)->moved_to_pkgname[0]!= '\0') { mport_call_msg_cb(mport, "Package %s has moved to %s. Migrating %s\n", (*packs)->name, (*movedEntries)->moved_to_pkgname, (*movedEntries)->moved_to_pkgname); + (*packs)->action = MPORT_ACTION_UPGRADE; mport_delete_primative(mport, (*packs), true); + // TODO: how to mark this action as an update? mport_install(mport, (*movedEntries)->moved_to_pkgname, NULL, NULL, (*packs)->automatic); ohash_insert(&h, slot, (*packs)->name); ohash_insert(&h, slot, (*movedEntries)->moved_to_pkgname); @@ -128,6 +131,7 @@ mport_upgrade(mportInstance *mport) { key = ohash_find(&h, slot); if (key == NULL) { if (mport_index_check(mport, *packs)) { + (*packs)->action = MPORT_ACTION_UPGRADE; updated += mport_update_down(mport, *packs, &info, &h); } } @@ -158,6 +162,7 @@ mport_update_down(mportInstance *mport, mportPackageMeta *pack, struct ohash_inf if (key == NULL) { if (mport_index_check(mport, pack)) { mport_call_msg_cb(mport, "Updating %s\n", pack->name); + pack->action = MPORT_ACTION_UPGRADE; if (mport_update(mport, pack->name) !=0) { mport_call_msg_cb(mport, "Error updating %s\n", pack->name); ret = 0; @@ -179,6 +184,7 @@ mport_update_down(mportInstance *mport, mportPackageMeta *pack, struct ohash_inf ret += mport_update_down(mport, (*depends), info, h); if (mport_index_check(mport, *depends)) { mport_call_msg_cb(mport, "Updating depends %s\n", (*depends)->name); + (*depends)->action = MPORT_ACTION_UPGRADE; if (mport_update(mport, (*depends)->name) != 0) { mport_call_msg_cb(mport, "Error updating %s\n", (*depends)->name); } else { diff --git a/contrib/mport/libmport/util.c b/contrib/mport/libmport/util.c index a11b84e8fb..ce068a3487 100644 --- a/contrib/mport/libmport/util.c +++ b/contrib/mport/libmport/util.c @@ -350,6 +350,34 @@ mport_file_exists(const char *file) return (lstat(file, &st) == 0); } +char * +mport_directory(const char *path) +{ + + if (path[0] == '/') { + // 'path' is a full path, so we can extract the directory directly + char *dir = strdup(path); + char *lastSlash = strrchr(dir, '/'); + if (lastSlash != NULL) { + *lastSlash = '\0'; // Null-terminate at the last slash to get the directory + return dir; + } else { + free(dir); + } + } else { + // 'path' is just a filename, so get the current working directory + char currentDir[PATH_MAX]; + if (getcwd(currentDir, sizeof(currentDir)) != NULL) { + // Construct the full path by appending the filename + strcat(currentDir, "/"); + strcat(currentDir, path); + return strdup(currentDir); + } + } + + return NULL; +} + /* mport_xsystem(mportInstance *mport, char *fmt, ...) * * Our own version on system that takes a format string and a list @@ -433,7 +461,7 @@ mport_parselist(char *opt, char ***list, size_t *list_size) /* first we need to get the length of the dependency list */ for (*list_size = 0; (field = strsep(&opt, " \t\n")) != NULL;) { - if (*field != '\0') + if (field != NULL && *field != '\0') (*list_size)++; } diff --git a/contrib/mport/mport/Makefile b/contrib/mport/mport/Makefile index 7451bd0366..edd2dd7865 100644 --- a/contrib/mport/mport/Makefile +++ b/contrib/mport/mport/Makefile @@ -1,6 +1,6 @@ PROG= mport -CFLAGS= -I ../libmport/ -g -L../libmport -lmport -lutil +CFLAGS= -I ../libmport/ -I/usr/include/private/ucl -g -L../libmport -lmport -lutil CFLAGS+= -Werror -Wunused-variable -Wshadow -Wincompatible-pointer-types-discards-qualifiers LIBADD+= mport util diff --git a/contrib/mport/mport/mport.c b/contrib/mport/mport/mport.c index 1c8081e471..c733a10a76 100644 --- a/contrib/mport/mport/mport.c +++ b/contrib/mport/mport/mport.c @@ -51,6 +51,7 @@ static void loadIndex(mportInstance *); static mportIndexEntry **lookupIndex(mportInstance *, const char *); +static int add(mportInstance *mport, const char *filename, mportAutomatic automatic); static int install(mportInstance *, const char *); static int cpeList(mportInstance *); @@ -84,6 +85,8 @@ static int audit(mportInstance *, bool); static int selectMirror(mportInstance *mport); +static mportPackageMeta** lookup_for_lock(mportInstance *, const char *); + int main(int argc, char *argv[]) { @@ -162,7 +165,38 @@ main(int argc, char *argv[]) char *cmd = argv[0]; - if (!strcmp(cmd, "install")) { + if (!strcmp(cmd, "add")) { + if (argc == 1) { + mport_instance_free(mport); + usage(); + } + + int local_argc = argc; + char *const *local_argv = argv; + int aflag = 0; + + if (local_argc > 1) { + int ch2; + while ((ch2 = getopt(local_argc, local_argv, "A")) != -1) { + switch (ch2) { + case 'A': + aflag = 1; + break; + } + } + local_argc -= optind; + local_argv += optind; + } + + mport->noIndex = true; + mport->offline = true; + + for (i = 1; i < argc; i++) { + tempResultCode = add(mport, argv[i], aflag == 1 ? MPORT_AUTOMATIC : MPORT_EXPLICIT); + if (tempResultCode != 0) + resultCode = tempResultCode; + } + } else if (!strcmp(cmd, "install")) { if (argc == 1) { mport_instance_free(mport); usage(); @@ -517,7 +551,7 @@ selectMirror(mportInstance *mport) mport_index_mirror_list(mport, &mirrorEntry); - int fastest = 1000; + long fastest = 1000; const char *country = "us"; while(mirrorEntry != NULL && *mirrorEntry != NULL) { @@ -543,7 +577,7 @@ selectMirror(mportInstance *mport) mirrorEntry++; } - mport_call_msg_cb(mport, "Using mirror %s with rtt %d ms\n", country, fastest); + mport_call_msg_cb(mport, "Using mirror %s with rtt %ld ms\n", country, fastest); int result = mport_setting_set(mport, MPORT_SETTING_MIRROR_REGION, country); if (result != MPORT_OK) { @@ -586,54 +620,54 @@ search(mportInstance *mport, char **query) return (0); } -int -lock(mportInstance *mport, const char *packageName) +static mportPackageMeta** +lookup_for_lock(mportInstance *mport, const char *packageName) { mportPackageMeta **packs = NULL; if (packageName == NULL) { warnx("%s", "Specify package name"); - return (1); + return (NULL); } if (mport_pkgmeta_search_master(mport, &packs, "pkg=%Q", packageName) != MPORT_OK) { warnx("%s", mport_err_string()); - return (1); + return (NULL); } if (packs == NULL) { warnx("Package name not found, %s", packageName); - return (1); - } else { - mport_lock_lock(mport, (*packs)); } - return (0); + return (packs); } -int -unlock(mportInstance *mport, const char *packageName) +static int +lock(mportInstance *mport, const char *packageName) { - mportPackageMeta **packs = NULL; + mportPackageMeta **packs = lookup_for_lock(mport, packageName); - if (packageName == NULL) { - warnx("%s", "Specify package name"); - return (1); + if (packs != NULL) { + mport_lock_lock(mport, (*packs)); + mport_pkgmeta_free(*packs); + return (MPORT_OK); } - if (mport_pkgmeta_search_master(mport, &packs, "pkg=%Q", packageName) != MPORT_OK) { - warnx("%s", mport_err_string()); - return (1); - } + return (MPORT_ERR_FATAL); +} - if (packs == NULL) { - warnx("Package name not found, %s", packageName); - return (1); - } else { +static int +unlock(mportInstance *mport, const char *packageName) +{ + mportPackageMeta **packs = lookup_for_lock(mport, packageName); + + if (packs != NULL) { mport_lock_unlock(mport, (*packs)); + mport_pkgmeta_free(*packs); + return (MPORT_OK); } - return (0); + return (MPORT_ERR_FATAL); } static int @@ -710,17 +744,23 @@ which(mportInstance *mport, const char *filePath, bool quiet, bool origin) return (0); } +int +add(mportInstance *mport, const char *filename, mportAutomatic automatic) { + return mport_install_primative(mport, filename, NULL, automatic); +} + int install(mportInstance *mport, const char *packageName) { mportIndexEntry **indexEntry = NULL; + mportIndexEntry **ie = NULL; mportIndexEntry **i2 = NULL; int resultCode; int item; int choice; indexEntry = lookupIndex(mport, packageName); - if (*indexEntry == NULL) { + if (indexEntry == NULL || *indexEntry == NULL) { int loc = -1; size_t len = strlen(packageName); for (int i = len - 1; i >= 0; i--) { @@ -746,6 +786,7 @@ install(mportInstance *mport, const char *packageName) if (indexEntry == NULL || *indexEntry == NULL) errx(4, "Package %s not found in the index.", packageName); + ie = indexEntry; if (indexEntry[1] != NULL) { printf("Multiple packages found. Please select one:\n"); i2 = indexEntry; @@ -767,10 +808,12 @@ install(mportInstance *mport, const char *packageName) } } - resultCode = mport_install_depends( - mport, (*indexEntry)->pkgname, (*indexEntry)->version, MPORT_EXPLICIT); + if (indexEntry == NULL || *indexEntry == NULL) { + resultCode = mport_install_depends( + mport, (*indexEntry)->pkgname, (*indexEntry)->version, MPORT_EXPLICIT); + } - mport_index_entry_free_vec(indexEntry); + mport_index_entry_free_vec(ie); return (resultCode); } @@ -793,6 +836,7 @@ delete(mportInstance *mport, const char *packageName) } while (*packs != NULL) { + (*packs)->action = MPORT_ACTION_DELETE; if (mport_delete_primative(mport, *packs, force) != MPORT_OK) { warnx("%s", mport_err_string()); mport_pkgmeta_vec_free(packs);