]> git.ipfire.org Git - pakfire.git/commitdiff
package: Build a unified way to check if a package exists
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 30 Jan 2025 17:00:04 +0000 (17:00 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 30 Jan 2025 17:00:04 +0000 (17:00 +0000)
This performs a quick stat() as well.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/pakfire/package.c
src/pakfire/package.h

index 04f771dbcb77c9a39740cbe4bd504d53f03c7bd5..c048cec5aa806a879f5110214b624ab9fbc2931c 100644 (file)
@@ -1304,6 +1304,111 @@ ERROR:
        return r;
 }
 
+static int pakfire_package_is_available_exists(struct pakfire_package* self, const char* path) {
+       struct stat st = {};
+       int r;
+
+       // Stat the path
+       r = stat(path, &st);
+       if (r < 0) {
+               switch (errno) {
+                       // If path does not exist, the package is not available
+                       case ENOENT:
+                               return 0;
+
+                       // Fail on any other errors
+                       default:
+                               return -errno;
+               }
+       }
+
+       // Check if this is a regular file
+       switch (st.st_mode & S_IFMT) {
+               case S_IFREG:
+                       break;
+
+               // If path is of some unknown file type we rather assume it does not exist
+               default:
+                       return 0;
+       }
+
+       // Fetch the download size
+       ssize_t size = pakfire_package_get_num(self, PAKFIRE_PKG_DOWNLOADSIZE, 0);
+
+       // Check if the size matches - this is quite a good test to see if we have the right file
+       if ((size > 0) &&  (st.st_size != size))
+               return 0;
+
+       // Yes, this seems to be available
+       return 1;
+}
+
+static int pakfire_package_is_available_local(
+               struct pakfire_package* self, struct pakfire_repo* repo) {
+       char path[PATH_MAX];
+       int r;
+
+       const char* pkg_path = pakfire_package_get_string(self, PAKFIRE_PKG_PATH);
+
+       // Compose path
+       r = pakfire_repo_path(repo, path, "%s", pkg_path);
+       if (r < 0) {
+               ERROR(self->ctx, "Could not compose package path: %s\n", strerror(-r));
+               return r;
+       }
+
+       // Check if the package actually exists
+       return pakfire_package_is_available_exists(self, path);
+}
+
+static int pakfire_package_is_available_cache(struct pakfire_package* self) {
+       // Fetch the path the package should be in the cache
+       const char* path = pakfire_package_get_string(self, PAKFIRE_PKG_CACHE_PATH);
+
+       // Check if the package actually exists
+       return pakfire_package_is_available_exists(self, path);
+}
+
+/*
+       This function checks if the archive is available.
+
+       For local repositories, the path is checked, otherwise we will check the cache.
+*/
+int pakfire_package_is_available(struct pakfire_package* self) {
+       struct pakfire_repo* repo = NULL;
+       int r;
+
+       // Fetch NEVRA
+       const char* nevra = pakfire_package_get_string(self, PAKFIRE_PKG_NEVRA);
+
+       // Fetch the repository
+       repo = pakfire_package_get_repo(self);
+       if (!repo) {
+               ERROR(self->ctx, "Could not find repository for %s\n", nevra);
+               r = -ENOTSUP;
+               goto ERROR;
+       }
+
+       // Check local repositories
+       if (pakfire_repo_is_local(repo)) {
+               r = pakfire_package_is_available_local(self, repo);
+               if (r < 0)
+                       goto ERROR;
+
+       // Check remote repositories
+       } else {
+               r = pakfire_package_is_available_cache(self);
+               if (r < 0)
+                       goto ERROR;
+       }
+
+ERROR:
+       if (repo)
+               pakfire_repo_unref(repo);
+
+       return r;
+}
+
 int pakfire_package_is_installed(struct pakfire_package* pkg) {
        Pool* pool = pakfire_get_solv_pool(pkg->pakfire);
        Solvable* s = get_solvable(pkg);
index d13b0979492eb752ae66b06513bdfad34c0b169a..96c499eb8040219da45ed7eea597418b2e036608 100644 (file)
@@ -170,6 +170,7 @@ int pakfire_package_supports_build_arch(struct pakfire_package* pkg, const char*
 
 char* pakfire_package_join_evr(const char* e, const char* v, const char* r);
 
+int pakfire_package_is_available(struct pakfire_package* self);
 int pakfire_package_is_installed(struct pakfire_package* pkg);
 
 // Filelist