static int pkg_repo_binary_add_from_manifest(char *buf, const char *origin, const char *digest, long offset, sqlite3 *sqlite, struct pkg_manifest_key **keys, struct pkg **p, bool is_legacy, struct pkg_repo *repo) { int rc = EPKG_OK; struct pkg *pkg; const char *local_origin, *pkg_arch; if (*p == NULL) { rc = pkg_new(p, PKG_REMOTE); if (rc != EPKG_OK) return (EPKG_FATAL); } else { pkg_reset(*p, PKG_REMOTE); } pkg = *p; pkg_manifest_keys_new(keys); rc = pkg_parse_manifest(pkg, buf, offset, *keys); if (rc != EPKG_OK) { goto cleanup; } rc = pkg_is_valid(pkg); if (rc != EPKG_OK) { goto cleanup; } /* Ensure that we have a proper origin and arch*/ pkg_get(pkg, PKG_ORIGIN, &local_origin, PKG_ARCH, &pkg_arch); if (local_origin == NULL || strcmp(local_origin, origin) != 0) { pkg_emit_error("manifest contains origin %s while we wanted to add origin %s", local_origin ? local_origin : "NULL", origin); rc = EPKG_FATAL; goto cleanup; } if (pkg_arch == NULL || !is_valid_abi(pkg_arch, true)) { rc = EPKG_FATAL; pkg_emit_error("repository %s contains packages with wrong ABI: %s", repo->name, pkg_arch); goto cleanup; } pkg_set(pkg, PKG_REPONAME, repo->name); if (is_legacy) { pkg_set(pkg, PKG_OLD_DIGEST, digest); pkg_checksum_calculate(pkg, NULL); } else { pkg_set(pkg, PKG_DIGEST, digest); } rc = pkg_repo_binary_add_pkg(pkg, NULL, sqlite, true); cleanup: return (rc); }
static int pkg_read_manifest_v2(FILE *fs, struct pkg **pkg_p, struct pkg_manifest_key *keys) { struct pkg_section_hdr sec; struct pkg *pkg; void *payload; size_t paylen; int retcode = EPKG_OK; if (pkg_skip_to_section(fs, PKG_FORMAT_SECTION_MANIFEST, &sec) != EPKG_OK) { return (EPKG_FATAL); } if (pkg_section_maybe_uncompress(fs, &sec, &payload, &paylen) != EPKG_OK) { return (EPKG_FATAL); } retcode = pkg_new(pkg_p, PKG_FILE); if (retcode != EPKG_OK) { goto cleanup; } pkg = *pkg_p; retcode = pkg_parse_manifest(pkg, payload, paylen, keys); cleanup: free(payload); return (retcode); }
int pkg_load_manifest_file(struct pkg *pkg, const char *fpath) { char *manifest = NULL; off_t sz; int ret = EPKG_OK; if ((ret = file_to_buffer(fpath, &manifest, &sz)) != EPKG_OK) return (ret); ret = pkg_parse_manifest(pkg, manifest); free(manifest); return (ret); }
static int pkg_repo_add_from_manifest(char *buf, const char *origin, long offset, const char *manifest_digest, sqlite3 *sqlite, struct pkg_manifest_key **keys, struct pkg **p) { int rc = EPKG_OK; struct pkg *pkg; const char *local_origin, *pkg_arch; if (*p == NULL) { rc = pkg_new(p, PKG_REMOTE); if (rc != EPKG_OK) return (EPKG_FATAL); } else { pkg_reset(*p, PKG_REMOTE); } pkg = *p; pkg_manifest_keys_new(keys); rc = pkg_parse_manifest(pkg, buf, offset, *keys); if (rc != EPKG_OK) { goto cleanup; } rc = pkg_is_valid(pkg); if (rc != EPKG_OK) { goto cleanup; } /* Ensure that we have a proper origin and arch*/ pkg_get(pkg, PKG_ORIGIN, &local_origin, PKG_ARCH, &pkg_arch); if (local_origin == NULL || strcmp(local_origin, origin) != 0) { pkg_emit_error("manifest contains origin %s while we wanted to add origin %s", local_origin ? local_origin : "NULL", origin); rc = EPKG_FATAL; goto cleanup; } if (pkg_arch == NULL || !is_valid_abi(pkg_arch, true)) { rc = EPKG_FATAL; goto cleanup; } rc = pkgdb_repo_add_package(pkg, NULL, sqlite, manifest_digest, true); cleanup: return (rc); }
static int pkg_read_files_v2(FILE *fs, struct pkg *pkg, struct pkg_manifest_key *keys) { struct pkg_section_hdr sec; void *payload; size_t paylen; int retcode = EPKG_OK; if (pkg_skip_to_section(fs, PKG_FORMAT_SECTION_FILELIST, &sec) != EPKG_OK) { return (EPKG_END); } if (pkg_section_maybe_uncompress(fs, &sec, &payload, &paylen) != EPKG_OK) { return (EPKG_FATAL); } retcode = pkg_parse_manifest(pkg, payload, paylen, keys); free(payload); return (retcode); }
void test_manifest(void) { struct pkg *p = NULL; struct pkg_dep *dep = NULL; struct pkg_conflict *conflict = NULL; struct pkg_option *option = NULL; struct pkg_category *category = NULL; struct pkg_file *file = NULL; struct pkg_manifest_key *keys = NULL; const char *pkg_str; int64_t pkg_int; int i; pkg_manifest_keys_new(&keys); ATF_REQUIRE(keys != NULL); ATF_REQUIRE_EQ(EPKG_OK, pkg_new(&p, PKG_FILE)); ATF_REQUIRE(p != NULL); ATF_REQUIRE_EQ(EPKG_OK, pkg_parse_manifest(p, manifest, strlen(manifest), keys)); pkg_manifest_keys_free(keys); ATF_REQUIRE(pkg_get(p, PKG_NAME, &pkg_str) == EPKG_OK); ATF_REQUIRE(strcmp(pkg_str, "foobar") == 0); ATF_REQUIRE(pkg_get(p, PKG_VERSION, &pkg_str) == EPKG_OK); ATF_REQUIRE(strcmp(pkg_str, "0.3") == 0); ATF_REQUIRE(pkg_get(p, PKG_ORIGIN, &pkg_str) == EPKG_OK); ATF_REQUIRE(strcmp(pkg_str, "foo/bar") == 0); ATF_REQUIRE(pkg_get(p, PKG_COMMENT, &pkg_str) == EPKG_OK); ATF_REQUIRE(strcmp(pkg_str, "A dummy manifest") == 0); ATF_REQUIRE(pkg_get(p, PKG_ARCH, &pkg_str) == EPKG_OK); ATF_REQUIRE(strcmp(pkg_str, "amd64") == 0); ATF_REQUIRE(pkg_get(p, PKG_WWW, &pkg_str) == EPKG_OK); ATF_REQUIRE(strcmp(pkg_str, "http://www.foobar.com") == 0); ATF_REQUIRE(pkg_get(p, PKG_MAINTAINER, &pkg_str) == EPKG_OK); ATF_REQUIRE(strcmp(pkg_str, "*****@*****.**") == 0); ATF_REQUIRE(pkg_get(p, PKG_PREFIX, &pkg_str) == EPKG_OK); ATF_REQUIRE(strcmp(pkg_str, "/opt/prefix") == 0); ATF_REQUIRE(pkg_get(p, PKG_DESC, &pkg_str) == EPKG_OK); ATF_REQUIRE(strcmp(pkg_str, "port description") == 0); ATF_REQUIRE(pkg_get(p, PKG_MESSAGE, &pkg_str) == EPKG_OK); ATF_REQUIRE(strcmp(pkg_str, "pkg message") == 0); ATF_REQUIRE(pkg_get(p, PKG_FLATSIZE, &pkg_int) == EPKG_OK); ATF_REQUIRE(pkg_int == 10000); i = 0; while (pkg_deps(p, &dep) == EPKG_OK) { if (i == 0) { ATF_REQUIRE(strcmp(pkg_dep_name(dep), "depfoo") == 0); ATF_REQUIRE(strcmp(pkg_dep_origin(dep), "dep/foo") == 0); ATF_REQUIRE(strcmp(pkg_dep_version(dep), "1.2") == 0); } else if (i == 1) { ATF_REQUIRE(strcmp(pkg_dep_name(dep), "depbar") == 0); ATF_REQUIRE(strcmp(pkg_dep_origin(dep), "dep/bar") == 0); ATF_REQUIRE(strcmp(pkg_dep_version(dep), "3.4") == 0); } i++; } ATF_REQUIRE(i == 2); i = 0; #if 0 while (pkg_conflicts(p, &conflict) == EPKG_OK) { if (i == 0) { ATF_REQUIRE(strcmp(pkg_conflict_glob(conflict), "foo-*") == 0); } else if (i == 1) { ATF_REQUIRE(strcmp(pkg_conflict_glob(conflict), "bar-*") == 0); } i++; } ATF_REQUIRE(i == 2); #endif i = 0; while (pkg_options(p, &option) == EPKG_OK) { if (i == 0) { ATF_REQUIRE(strcmp(pkg_option_opt(option), "foo") == 0); ATF_REQUIRE(strcmp(pkg_option_value(option), "true") == 0); } else if (i == 1) { ATF_REQUIRE(strcmp(pkg_option_opt(option), "bar") == 0); ATF_REQUIRE(strcmp(pkg_option_value(option), "false") == 0); } i++; } ATF_REQUIRE(i == 2); i = 0; while (pkg_categories(p, &category) == EPKG_OK) { if (i == 0) { ATF_REQUIRE(strcmp(pkg_category_name(category), "foo") == 0); } else if (i == 1) { ATF_REQUIRE(strcmp(pkg_category_name(category), "bar") == 0); } i++; } ATF_REQUIRE(i == 2); ATF_REQUIRE(pkg_files(p, &file) == EPKG_OK); ATF_REQUIRE(strcmp(pkg_file_path(file), "/usr/local/bin/foo") == 0); #if 0 ATF_REQUIRE(strcmp(pkg_file_sha256(file), "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b") == 0); #endif pkg_free(p); /* p = NULL; ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK); ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest1) == EPKG_FATAL); pkg_free(p); p = NULL; ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK); ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest2) == EPKG_FATAL); pkg_free(p); p = NULL; ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK); ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest3) == EPKG_FATAL); pkg_free(p); p = NULL; ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK); ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest4) == EPKG_FATAL); pkg_free(p); */ }
void test_manifest(void) { struct pkg *p = NULL; struct pkg_dep *dep = NULL; struct pkg_conflict *conflict = NULL; struct pkg_option *option = NULL; struct pkg_file *file = NULL; int i; ATF_REQUIRE_EQ(EPKG_OK, pkg_new(&p, PKG_FILE)); ATF_REQUIRE(p != NULL); ATF_REQUIRE_EQ(EPKG_OK, pkg_parse_manifest(p, manifest)); #if 0 ATF_REQUIRE(strcmp(pkg_get(p, PKG_NAME), "foobar") == 0); ATF_REQUIRE(strcmp(pkg_get(p, PKG_VERSION), "0.3") == 0); ATF_REQUIRE(strcmp(pkg_get(p, PKG_ORIGIN), "foo/bar") == 0); ATF_REQUIRE(strcmp(pkg_get(p, PKG_COMMENT), "A dummy manifest") == 0); ATF_REQUIRE(strcmp(pkg_get(p, PKG_ARCH), "amd64") == 0); ATF_REQUIRE(strcmp(pkg_get(p, PKG_VERSION), "800500") == 0); ATF_REQUIRE(strcmp(pkg_get(p, PKG_WWW), "http://www.foobar.com") == 0); ATF_REQUIRE(strcmp(pkg_get(p, PKG_MAINTAINER), "*****@*****.**") == 0); #endif i = 0; while (pkg_deps(p, &dep) == EPKG_OK) { if (i == 0) { ATF_REQUIRE(strcmp(pkg_dep_name(dep), "depfoo") == 0); ATF_REQUIRE(strcmp(pkg_dep_origin(dep), "dep/foo") == 0); ATF_REQUIRE(strcmp(pkg_dep_version(dep), "1.2") == 0); } else if (i == 1) { ATF_REQUIRE(strcmp(pkg_dep_name(dep), "depbar") == 0); ATF_REQUIRE(strcmp(pkg_dep_origin(dep), "dep/bar") == 0); ATF_REQUIRE(strcmp(pkg_dep_version(dep), "3.4") == 0); } i++; } ATF_REQUIRE(i == 2); i = 0; #if 0 while (pkg_conflicts(p, &conflict) == EPKG_OK) { if (i == 0) { ATF_REQUIRE(strcmp(pkg_conflict_glob(conflict), "foo-*") == 0); } else if (i == 1) { ATF_REQUIRE(strcmp(pkg_conflict_glob(conflict), "bar-*") == 0); } i++; } ATF_REQUIRE(i == 2); #endif i = 0; while (pkg_options(p, &option) == EPKG_OK) { if (i == 0) { ATF_REQUIRE(strcmp(pkg_option_opt(option), "foo") == 0); ATF_REQUIRE(strcmp(pkg_option_value(option), "true") == 0); } else if (i == 1) { ATF_REQUIRE(strcmp(pkg_option_opt(option), "bar") == 0); ATF_REQUIRE(strcmp(pkg_option_value(option), "false") == 0); } i++; } ATF_REQUIRE(i == 2); ATF_REQUIRE(pkg_files(p, &file) == EPKG_OK); ATF_REQUIRE(strcmp(pkg_file_path(file), "/usr/local/bin/foo") == 0); #if 0 ATF_REQUIRE(strcmp(pkg_file_sha256(file), "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b") == 0); #endif pkg_free(p); /* p = NULL; ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK); ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest1) == EPKG_FATAL); pkg_free(p); p = NULL; ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK); ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest2) == EPKG_FATAL); pkg_free(p); p = NULL; ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK); ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest3) == EPKG_FATAL); pkg_free(p); p = NULL; ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK); ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest4) == EPKG_FATAL); pkg_free(p); */ }
static int pkg_open_legacy(struct pkg **pkg_p, struct archive **a, struct archive_entry **ae, const char *path, struct pkg_manifest_key *keys, int flags, int fd) { struct pkg *pkg = NULL; pkg_error_t retcode = EPKG_OK; int ret; const char *fpath; bool manifest = false; bool read_from_stdin = 0; *a = archive_read_new(); archive_read_support_filter_all(*a); archive_read_support_format_tar(*a); /* archive_read_open_filename() treats a path of NULL as * meaning "read from stdin," but we want this behaviour if * path is exactly "-". In the unlikely event of wanting to * read an on-disk file called "-", just say "./-" or some * other leading path. */ if (fd == -1) { read_from_stdin = (strncmp(path, "-", 2) == 0); if (archive_read_open_filename(*a, read_from_stdin ? NULL : path, 4096) != ARCHIVE_OK) { if ((flags & PKG_OPEN_TRY) == 0) pkg_emit_error("archive_read_open_filename(%s): %s", path, archive_error_string(*a)); retcode = EPKG_FATAL; goto cleanup; } } else { if (archive_read_open_fd(*a, fd, 4096) != ARCHIVE_OK) { if ((flags & PKG_OPEN_TRY) == 0) pkg_emit_error("archive_read_open_fd: %s", archive_error_string(*a)); retcode = EPKG_FATAL; goto cleanup; } } retcode = pkg_new(pkg_p, PKG_FILE); if (retcode != EPKG_OK) goto cleanup; pkg = *pkg_p; while ((ret = archive_read_next_header(*a, ae)) == ARCHIVE_OK) { fpath = archive_entry_pathname(*ae); if (fpath[0] != '+') break; if (!manifest && (flags & PKG_OPEN_MANIFEST_COMPACT) && strcmp(fpath, "+COMPACT_MANIFEST") == 0) { char *buffer; manifest = true; size_t len = archive_entry_size(*ae); buffer = xmalloc(len); archive_read_data(*a, buffer, archive_entry_size(*ae)); ret = pkg_parse_manifest(pkg, buffer, len, keys); free(buffer); if (ret != EPKG_OK) { retcode = EPKG_FATAL; goto cleanup; } /* Do not read anything more */ break; } if (!manifest && strcmp(fpath, "+MANIFEST") == 0) { manifest = true; char *buffer; size_t len = archive_entry_size(*ae); buffer = xmalloc(len); archive_read_data(*a, buffer, archive_entry_size(*ae)); ret = pkg_parse_manifest(pkg, buffer, len, keys); free(buffer); if (ret != EPKG_OK) { if ((flags & PKG_OPEN_TRY) == 0) pkg_emit_error("%s is not a valid package: " "Invalid manifest", path); retcode = EPKG_FATAL; goto cleanup; } if (flags & PKG_OPEN_MANIFEST_ONLY) break; } } if (ret != ARCHIVE_OK && ret != ARCHIVE_EOF) { if ((flags & PKG_OPEN_TRY) == 0) pkg_emit_error("archive_read_next_header(): %s", archive_error_string(*a)); retcode = EPKG_FATAL; } if (ret == ARCHIVE_EOF) retcode = EPKG_END; if (!manifest) { retcode = EPKG_FATAL; if ((flags & PKG_OPEN_TRY) == 0) pkg_emit_error("%s is not a valid package: no manifest found", path); } cleanup: if (retcode != EPKG_OK && retcode != EPKG_END) { if (*a != NULL) { archive_read_close(*a); archive_read_free(*a); } free(pkg); *pkg_p = NULL; *a = NULL; *ae = NULL; } return (retcode); }