int pkg_create_staged(const char *outdir, pkg_formats format, const char *rootdir, const char *md_dir, char *plist) { struct pkg *pkg = NULL; struct pkg_file *file = NULL; struct pkg_dir *dir = NULL; struct packing *pkg_archive = NULL; char *manifest = NULL; char arch[BUFSIZ]; int ret = ENOMEM; int i, mfd; regex_t preg; regmatch_t pmatch[2]; size_t size; struct pkg_manifest_key *keys = NULL; pkg_debug(1, "Creating package from stage directory: '%s'", rootdir); if ((mfd = open(md_dir, O_DIRECTORY)) == -1) { pkg_emit_errno("open", md_dir); goto cleanup; } if(pkg_new(&pkg, PKG_FILE) != EPKG_OK) { ret = EPKG_FATAL; goto cleanup; } pkg_manifest_keys_new(&keys); /* Load the manifest from the metadata directory */ if ((ret = pkg_parse_manifest_fileat(mfd, pkg, "+MANIFEST", keys)) != EPKG_OK) { ret = EPKG_FATAL; goto cleanup; } /* if no descriptions provided then try to get it from a file */ if (pkg->desc == NULL) pkg_load_from_file(mfd, pkg, PKG_DESC, "+DESC"); /* if no message try to get it from a file */ if (pkg->message == NULL) { /* Try ucl version first */ if (pkg_load_message_from_file(mfd, pkg, "+DISPLAY.ucl", true) != EPKG_OK) { pkg_load_message_from_file(mfd, pkg, "+DISPLAY", false); } } /* if no arch autodetermine it */ if (pkg->abi == NULL) { pkg_get_myarch(arch, BUFSIZ); pkg->abi = strdup(arch); } for (i = 0; scripts[i] != NULL; i++) { if (faccessat(mfd, scripts[i], F_OK, 0) == 0) pkg_addscript_fileat(mfd, pkg, scripts[i]); } if (plist != NULL && ports_parse_plist(pkg, plist, rootdir) != EPKG_OK) { ret = EPKG_FATAL; goto cleanup; } if (pkg->www == NULL) { if (pkg->desc == NULL) { pkg_emit_error("No www or desc defined in manifest"); ret = EPKG_FATAL; goto cleanup; } regcomp(&preg, "^WWW:[[:space:]]*(.*)$", REG_EXTENDED|REG_ICASE|REG_NEWLINE); if (regexec(&preg, pkg->desc, 2, pmatch, 0) == 0) { size = pmatch[1].rm_eo - pmatch[1].rm_so; pkg->www = strndup(&pkg->desc[pmatch[1].rm_so], size); } else { pkg->www = strdup("UNKNOWN"); } regfree(&preg); } /* Create the archive */ pkg_archive = pkg_create_archive(outdir, pkg, format, 0); if (pkg_archive == NULL) { ret = EPKG_FATAL; /* XXX do better */ goto cleanup; } /* XXX: autoplist support doesn't work right with meta-ports */ if (0 && pkg_files(pkg, &file) != EPKG_OK && pkg_dirs(pkg, &dir) != EPKG_OK) { /* Now traverse the file directories, adding to the archive */ packing_append_tree(pkg_archive, md_dir, NULL); packing_append_tree(pkg_archive, rootdir, "/"); ret = EPKG_OK; } else { ret = pkg_create_from_dir(pkg, rootdir, pkg_archive); } cleanup: if (mfd != -1) close(mfd); free(pkg); free(manifest); pkg_manifest_keys_free(keys); packing_finish(pkg_archive); return (ret); }
int pkg_load_metadata(struct pkg *pkg, const char *mfile, const char *md_dir, const char *plist, const char *rootdir, bool testing) { struct pkg_manifest_key *keys = NULL; char arch[BUFSIZ]; regex_t preg; regmatch_t pmatch[2]; int i, ret = EPKG_OK; int mfd = -1; size_t size; bool defaultarch = false; if (md_dir != NULL && (mfd = open(md_dir, O_DIRECTORY|O_CLOEXEC)) == -1) { pkg_emit_errno("open", md_dir); goto cleanup; } pkg_manifest_keys_new(&keys); if (mfile != NULL) { ret = pkg_parse_manifest_file(pkg, mfile, keys); } /* Load the manifest from the metadata directory */ if (mfile == NULL && mfd != -1 && (ret = pkg_parse_manifest_fileat(mfd, pkg, "+MANIFEST", keys)) != EPKG_OK) { ret = EPKG_FATAL; goto cleanup; } /* if no descriptions provided then try to get it from a file */ if (mfd != -1 && pkg->desc == NULL) pkg_load_from_file(mfd, pkg, PKG_DESC, "+DESC"); /* if no message try to get it from a file */ if (mfd != -1 && pkg->message == NULL) { /* Try ucl version first */ pkg_load_message_from_file(mfd, pkg, "+DISPLAY"); } /* if no arch autodetermine it */ if (pkg->abi == NULL) { pkg_get_myarch(arch, BUFSIZ); pkg->abi = strdup(arch); defaultarch = true; } for (i = 0; scripts[i] != NULL; i++) { if (faccessat(mfd, scripts[i], F_OK, 0) == 0) pkg_addscript_fileat(mfd, pkg, scripts[i]); } if (plist != NULL && ports_parse_plist(pkg, plist, rootdir) != EPKG_OK) { ret = EPKG_FATAL; goto cleanup; } if (pkg->www == NULL) { if (pkg->desc == NULL) { pkg_emit_error("No www or desc defined in manifest"); ret = EPKG_FATAL; goto cleanup; } regcomp(&preg, "^WWW:[[:space:]]*(.*)$", REG_EXTENDED|REG_ICASE|REG_NEWLINE); if (regexec(&preg, pkg->desc, 2, pmatch, 0) == 0) { size = pmatch[1].rm_eo - pmatch[1].rm_so; pkg->www = strndup(&pkg->desc[pmatch[1].rm_so], size); } else { pkg->www = strdup("UNKNOWN"); } regfree(&preg); } if (!testing) pkg_analyse_files(NULL, pkg, rootdir); if (developer_mode) pkg_suggest_arch(pkg, pkg->abi, defaultarch); cleanup: if (mfd != -1) close(mfd); pkg_manifest_keys_free(keys); return (ret); }