/* Locate the repo by the identifying tag from pkg.conf(5) */ struct pkg_repo * pkg_repo_find_ident(const char *repoident) { struct pkg_repo *r; char *name; asprintf(&name, REPO_NAME_PREFIX"%s", repoident); if (name == NULL) return (NULL); /* Out of memory */ r = pkg_repo_find_name(name); free(name); return (r); }
/* * Finds the type of the given PackageKit repository name. * * This function checks remote repositories to ensure they match actually * configured repositories, and instead returns 'REPO_INVALID' when they * don't. A separate function 'repo_type_no_remote_check' does not do this * and can thus be unit tested. */ enum repo_type repo_type(const char *name) { enum repo_type type; /* 'name' may be NULL. This implies REPO_ANY. */ type = repo_type_no_remote_check(name); if (type == REPO_REMOTE) { struct pkg_repo *repo; repo = pkg_repo_find_name(name); if (repo == NULL) { type = REPO_INVALID; } else if (!pkg_repo_enabled(repo)) { type = REPO_DISABLED; } } return type; }
int pkg_repo_fetch(struct pkg *pkg) { char dest[MAXPATHLEN + 1]; char url[MAXPATHLEN + 1]; int fetched = 0; char cksum[SHA256_DIGEST_LENGTH * 2 +1]; char *path = NULL; const char *packagesite = NULL; const char *cachedir = NULL; int retcode = EPKG_OK; const char *sum, *name, *version, *reponame; struct pkg_repo *repo; assert((pkg->type & PKG_REMOTE) == PKG_REMOTE); if (pkg_config_string(PKG_CONFIG_CACHEDIR, &cachedir) != EPKG_OK) return (EPKG_FATAL); pkg_get(pkg, PKG_REPONAME, &reponame, PKG_CKSUM, &sum, PKG_NAME, &name, PKG_VERSION, &version); pkg_snprintf(dest, sizeof(dest), "%S/%R", cachedir, pkg); /* If it is already in the local cachedir, dont bother to * download it */ if (access(dest, F_OK) == 0) goto checksum; /* Create the dirs in cachedir */ if ((path = dirname(dest)) == NULL) { pkg_emit_errno("dirname", dest); retcode = EPKG_FATAL; goto cleanup; } if ((retcode = mkdirs(path)) != EPKG_OK) goto cleanup; /* * In multi-repos the remote URL is stored in pkg[PKG_REPOURL] * For a single attached database the repository URL should be * defined by PACKAGESITE. */ repo = pkg_repo_find_name(reponame); packagesite = pkg_repo_url(repo); if (packagesite == NULL || packagesite[0] == '\0') { pkg_emit_error("PACKAGESITE is not defined"); retcode = 1; goto cleanup; } if (packagesite[strlen(packagesite) - 1] == '/') pkg_snprintf(url, sizeof(url), "%S%R", packagesite, pkg); else pkg_snprintf(url, sizeof(url), "%S/%R", packagesite, pkg); retcode = pkg_fetch_file(repo, url, dest, 0); fetched = 1; if (retcode != EPKG_OK) goto cleanup; checksum: retcode = sha256_file(dest, cksum); if (retcode == EPKG_OK) if (strcmp(cksum, sum)) { if (fetched == 1) { pkg_emit_error("%s-%s failed checksum " "from repository", name, version); retcode = EPKG_FATAL; } else { pkg_emit_error("cached package %s-%s: " "checksum mismatch, fetching from remote", name, version); unlink(dest); return (pkg_repo_fetch(pkg)); } } cleanup: if (retcode != EPKG_OK) unlink(dest); return (retcode); }