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);