int pkg_create_fakeroot(const char *outdir, pkg_formats format, const char *rootdir, const char *metadatadir) { struct pkg *pkg = NULL; struct packing *pkg_archive = NULL; char *manifest = NULL, *manifest_path = NULL; int ret = ENOMEM; /* Load the manifest from the metadata directory */ if (asprintf(&manifest_path, "%s/+MANIFEST", metadatadir) == -1) goto cleanup; pkg_new(&pkg, PKG_FILE); if (pkg == NULL) goto cleanup; ret = pkg_load_manifest_file(pkg, manifest_path); /* Create the archive */ pkg_archive = pkg_create_archive(outdir, pkg, format, 0); if (pkg_archive == NULL) { ret = EPKG_FATAL; /* XXX do better */ goto cleanup; } /* Now traverse the file directories, adding to the archive */ packing_append_tree(pkg_archive, metadatadir, NULL); packing_append_tree(pkg_archive, rootdir, "/"); ret = EPKG_OK; cleanup: if (pkg != NULL) free(pkg); if (manifest_path != NULL) free(manifest_path); if (manifest != NULL) free(manifest); if (ret == EPKG_OK) ret = packing_finish(pkg_archive); return ret; }
int exec_register(int argc, char **argv) { struct pkg *pkg = NULL; struct pkgdb *db = NULL; regex_t preg; regmatch_t pmatch[2]; int ch; char *plist = NULL; char *arch = NULL; char myarch[BUFSIZ]; char *mdir = NULL; char *www = NULL; char *input_path = NULL; char fpath[MAXPATHLEN + 1]; const char *message; const char *desc = NULL; size_t size; bool legacy = false; bool developer = false; int i; int ret = EPKG_OK, retcode = EX_OK; if (geteuid() != 0) { warnx("registering packages can only be done as root"); return (EX_NOPERM); } pkg_config_bool(PKG_CONFIG_DEVELOPER_MODE, &developer); pkg_new(&pkg, PKG_INSTALLED); while ((ch = getopt(argc, argv, "f:m:i:ld")) != -1) { switch (ch) { case 'f': if ((plist = strdup(optarg)) == NULL) err(1, "cannot allocate memory"); break; case 'm': if ((mdir = strdup(optarg)) == NULL) err(1, "cannot allocate memory"); break; case 'd': pkg_set(pkg, PKG_AUTOMATIC, true); break; case 'i': if ((input_path = strdup(optarg)) == NULL) err(1, "cannot allocate memory"); break; case 'l': legacy = true; break; default: printf("%c\n", ch); usage_register(); return (EX_USAGE); } } if (plist == NULL) errx(EX_USAGE, "missing -f flag"); if (mdir == NULL) errx(EX_USAGE, "missing -m flag"); snprintf(fpath, sizeof(fpath), "%s/+MANIFEST", mdir); if ((ret = pkg_load_manifest_file(pkg, fpath)) != EPKG_OK) { return (EX_IOERR); } snprintf(fpath, sizeof(fpath), "%s/+DESC", mdir); pkg_set_from_file(pkg, PKG_DESC, fpath); snprintf(fpath, sizeof(fpath), "%s/+DISPLAY", mdir); if (access(fpath, F_OK) == 0) pkg_set_from_file(pkg, PKG_MESSAGE, fpath); snprintf(fpath, sizeof(fpath), "%s/+MTREE_DIRS", mdir); if (access(fpath, F_OK) == 0) pkg_set_from_file(pkg, PKG_MTREE, fpath); for (i = 0; scripts[i] != NULL; i++) { snprintf(fpath, sizeof(fpath), "%s/%s", mdir, scripts[i]); if (access(fpath, F_OK) == 0) pkg_addscript_file(pkg, fpath); } /* if www is not given then try to determine it from description */ if (www == NULL) { pkg_get(pkg, PKG_DESC, &desc); regcomp(&preg, "^WWW:[[:space:]]*(.*)$", REG_EXTENDED|REG_ICASE|REG_NEWLINE); if (regexec(&preg, desc, 2, pmatch, 0) == 0) { size = pmatch[1].rm_eo - pmatch[1].rm_so; www = strndup(&desc[pmatch[1].rm_so], size); pkg_set(pkg, PKG_WWW, www); free(www); } else { pkg_set(pkg, PKG_WWW, "UNKNOWN"); } regfree(&preg); } else { pkg_set(pkg, PKG_WWW, www); free(www); } ret += ports_parse_plist(pkg, plist, input_path); if (ret != EPKG_OK) { return (EX_IOERR); } if (plist != NULL) free(plist); if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) { return (EX_IOERR); } pkg_analyse_files(db, pkg); pkg_get(pkg, PKG_ARCH, &arch); if (arch == NULL) { /* * do not take the one from configuration on purpose * but the real abi of the package. */ pkg_get_myarch(myarch, BUFSIZ); if (developer) pkg_suggest_arch(pkg, myarch, true); pkg_set(pkg, PKG_ARCH, myarch); } else { if (developer) pkg_suggest_arch(pkg, arch, false); } if (input_path != NULL) { pkg_copy_tree(pkg, input_path, "/"); free(input_path); } if (pkgdb_register_ports(db, pkg) != EPKG_OK) retcode = EX_SOFTWARE; pkg_get(pkg, PKG_MESSAGE, &message); if (message != NULL && !legacy) printf("%s\n", message); pkgdb_close(db); pkg_free(pkg); return (retcode); }
int exec_register(int argc, char **argv) { struct pkg *pkg; struct pkgdb *db; struct utsname u; regex_t preg; regmatch_t pmatch[2]; int ch; char *plist = NULL; char *v = NULL; char *arch = NULL; char *mdir = NULL; char *www = NULL; char *input_path = NULL; char fpath[MAXPATHLEN]; const char *desc = NULL; size_t size; bool heuristic = false; bool legacy = false; int retcode = 0; int ret = 0; if (geteuid() != 0) { warnx("registering packages can only be done as root"); return (EX_NOPERM); } pkg_new(&pkg, PKG_INSTALLED); while ((ch = getopt(argc, argv, "a:f:m:i:l")) != -1) { switch (ch) { case 'f': if ((plist = strdup(optarg)) == NULL) errx(1, "cannot allocate memory"); break; case 'm': mdir = strdup(optarg); break; case 'a': arch = strdup(optarg); break; case 'i': if ((input_path = strdup(optarg)) == NULL) errx(1, "cannot allocate memory"); break; case 'l': legacy = true; break; default: printf("%c\n", ch); usage_register(); return (-1); } } if (ret != 0) { pkg_error_warn("can not parse arguments"); return (1); } if (plist == NULL) errx(EX_USAGE, "missing -f flag"); uname(&u); if (arch == NULL) { pkg_set(pkg, PKG_ARCH, u.machine); } else { pkg_set(pkg, PKG_ARCH, arch); free(arch); } if (mdir == NULL) errx(EX_USAGE, "missing -m flag"); snprintf(fpath, MAXPATHLEN, "%s/+MANIFEST", mdir); if ((ret = pkg_load_manifest_file(pkg, fpath)) != EPKG_OK) { pkg_error_warn("can not parse manifest %s", fpath); return (EX_SOFTWARE); } snprintf(fpath, MAXPATHLEN, "%s/+DESC", mdir); pkg_set_from_file(pkg, PKG_DESC, fpath); snprintf(fpath, MAXPATHLEN, "%s/+DISPLAY", mdir); pkg_set_from_file(pkg, PKG_MESSAGE, fpath); snprintf(fpath, MAXPATHLEN, "%s/+MTREE_DIR", mdir); pkg_set_from_file(pkg, PKG_MTREE, mdir); snprintf(fpath, MAXPATHLEN, "%s/+INSTALL", mdir); pkg_addscript(pkg, fpath); snprintf(fpath, MAXPATHLEN, "%s/+PRE_INSTALL", mdir); pkg_addscript(pkg, fpath); snprintf(fpath, MAXPATHLEN, "%s/+POST_INSTALL", mdir); pkg_addscript(pkg, fpath); snprintf(fpath, MAXPATHLEN, "%s/+DEINSTALL", mdir); pkg_addscript(pkg, fpath); snprintf(fpath, MAXPATHLEN, "%s/+PRE_DEINSTALL", mdir); pkg_addscript(pkg, fpath); snprintf(fpath, MAXPATHLEN, "%s/+POST_DEINSTALL", mdir); pkg_addscript(pkg, fpath); snprintf(fpath, MAXPATHLEN, "%s/+UPGRADE", mdir); pkg_addscript(pkg, fpath); snprintf(fpath, MAXPATHLEN, "%s/+PRE_UPGRADE", mdir); pkg_addscript(pkg, fpath); snprintf(fpath, MAXPATHLEN, "%s/+POST_UPGRADE", mdir); pkg_addscript(pkg, fpath); snprintf(fpath, MAXPATHLEN, "%s/pkg-install", mdir); pkg_addscript(pkg, fpath); snprintf(fpath, MAXPATHLEN, "%s/pkg-pre-install", mdir); pkg_addscript(pkg, fpath); snprintf(fpath, MAXPATHLEN, "%s/pkg-post-install", mdir); pkg_addscript(pkg, fpath); snprintf(fpath, MAXPATHLEN, "%s/pkg-pre-deinstall", mdir); pkg_addscript(pkg, fpath); snprintf(fpath, MAXPATHLEN, "%s/pkg-post-deinstall", mdir); pkg_addscript(pkg, fpath); snprintf(fpath, MAXPATHLEN, "%s/pkg-upgrade", mdir); pkg_addscript(pkg, fpath); snprintf(fpath, MAXPATHLEN, "%s/pkg-pre-deupgrade", mdir); pkg_addscript(pkg, fpath); snprintf(fpath, MAXPATHLEN, "%s/pkg-post-deupgrade", mdir); pkg_addscript(pkg, fpath); /* if www is not given then try to determine it from description */ if (www == NULL) { desc = pkg_get(pkg, PKG_DESC); regcomp(&preg, "^WWW:[:space:]*(.*)$", REG_EXTENDED|REG_ICASE|REG_NEWLINE); if (regexec(&preg, desc, 2, pmatch, 0) == 0) { size = pmatch[1].rm_eo - pmatch[1].rm_so; www = strndup(&desc[pmatch[1].rm_so], size); pkg_set(pkg, PKG_WWW, www); free(www); } else { pkg_set(pkg, PKG_WWW, "UNKNOWN"); } regfree(&preg); } else { pkg_set(pkg, PKG_WWW, www); free(www); } if (strstr(u.release, "RELEASE") == NULL) { asprintf(&v, "%s-%d", u.release, __FreeBSD_version); pkg_set(pkg, PKG_OSVERSION, v); free(v); } else { pkg_set(pkg, PKG_OSVERSION, u.release); } /* TODO: missing osversion get it from uname*/ ret += ports_parse_plist(pkg, plist); if (ret != 0) { pkg_error_warn("can not parse plist file"); return (-1); } if (plist != NULL) free(plist); if (pkgdb_open(&db, PKGDB_DEFAULT, R_OK|W_OK) != EPKG_OK) { pkg_error_warn("can not open database"); return (-1); } if (heuristic) pkg_analyse_files(db, pkg); if (input_path != NULL) { pkg_copy_tree(pkg, input_path, "/"); free(input_path); } if (pkgdb_register_pkg(db, pkg) != EPKG_OK) { pkg_error_warn("can not register package"); retcode = 1; } pkgdb_register_finale(db, ret); if (ret != EPKG_OK) { pkg_error_warn("can not register package"); retcode = 1; } if (pkg_get(pkg, PKG_MESSAGE) != NULL && !legacy) printf("%s\n", pkg_get(pkg, PKG_MESSAGE)); pkgdb_close(db); pkg_free(pkg); return (retcode); }
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 path[MAXPATHLEN]; char arch[BUFSIZ]; int ret = ENOMEM; char *buf; int i; regex_t preg; regmatch_t pmatch[2]; size_t size; char *www; /* Load the manifest from the metadata directory */ if (snprintf(path, sizeof(path), "%s/+MANIFEST", md_dir) == -1) goto cleanup; pkg_new(&pkg, PKG_FILE); if (pkg == NULL) goto cleanup; if ((ret = pkg_load_manifest_file(pkg, path)) != EPKG_OK) { ret = EPKG_FATAL; goto cleanup; } /* if no descriptions provided then try to get it from a file */ pkg_get(pkg, PKG_DESC, &buf); if (buf == NULL) { if (snprintf(path, sizeof(path), "%s/+DESC", md_dir) == -1) goto cleanup; if (access(path, F_OK) == 0) pkg_set_from_file(pkg, PKG_DESC, path); } /* if no message try to get it from a file */ pkg_get(pkg, PKG_MESSAGE, &buf); if (buf == NULL) { ret = snprintf(path, sizeof(path), "%s/+DISPLAY", md_dir); if (ret == -1) goto cleanup; if (access(path, F_OK) == 0) pkg_set_from_file(pkg, PKG_MESSAGE, path); } /* if no arch autodetermine it */ pkg_get(pkg, PKG_ARCH, &buf); if (buf == NULL) { pkg_get_myarch(arch, BUFSIZ); pkg_set(pkg, PKG_ARCH, arch); } /* if no mtree try to get it from a file */ pkg_get(pkg, PKG_MTREE, &buf); if (buf == NULL) { ret = snprintf(path, sizeof(path), "%s/+MTREE_DIRS", md_dir); if (ret == -1) goto cleanup; if (access(path, F_OK) == 0) pkg_set_from_file(pkg, PKG_MTREE, path); } for (i = 0; scripts[i] != NULL; i++) { snprintf(path, sizeof(path), "%s/%s", md_dir, scripts[i]); if (access(path, F_OK) == 0) pkg_addscript_file(pkg, path); } if (plist != NULL && ports_parse_plist(pkg, plist, rootdir) != EPKG_OK) { ret = EPKG_FATAL; goto cleanup; } /* if www is not given then try to determine it from description */ pkg_get(pkg, PKG_WWW, &www); if (www == NULL) { pkg_get(pkg, PKG_DESC, &buf); regcomp(&preg, "^WWW:[[:space:]]*(.*)$", REG_EXTENDED|REG_ICASE|REG_NEWLINE); if (regexec(&preg, buf, 2, pmatch, 0) == 0) { size = pmatch[1].rm_eo - pmatch[1].rm_so; www = strndup(&buf[pmatch[1].rm_so], size); pkg_set(pkg, PKG_WWW, www); free(www); } else { pkg_set(pkg, PKG_WWW, "UNKNOWN"); } regfree(&preg); } else { pkg_set(pkg, PKG_WWW, www); free(www); } /* Create the archive */ pkg_archive = pkg_create_archive(outdir, pkg, format, 0); if (pkg_archive == NULL) { ret = EPKG_FATAL; /* XXX do better */ goto cleanup; } if (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, "/"); } else { pkg_create_from_dir(pkg, rootdir, pkg_archive); } ret = EPKG_OK; cleanup: if (pkg != NULL) free(pkg); if (manifest != NULL) free(manifest); if (ret == EPKG_OK) ret = packing_finish(pkg_archive); return ret; }
int exec_register(int argc, char **argv) { struct pkg *pkg = NULL; struct pkgdb *db = NULL; struct pkg_manifest_key *keys = NULL; regex_t preg; regmatch_t pmatch[2]; char *arch = NULL; char myarch[BUFSIZ]; char *www = NULL; char fpath[MAXPATHLEN + 1]; const char *plist = NULL; const char *mdir = NULL; const char *mfile = NULL; const char *input_path = NULL; const char *desc = NULL; size_t size; bool developer; bool legacy = false; bool old = false; bool __unused metadata_only = false; bool testing_mode = false; int ch; int i; int ret = EPKG_OK; int retcode = EX_OK; pkg_config_bool(PKG_CONFIG_DEVELOPER_MODE, &developer); if (pkg_new(&pkg, PKG_INSTALLED) != EPKG_OK) err(EX_OSERR, "malloc"); while ((ch = getopt(argc, argv, "df:i:lM:m:Ot")) != -1) { switch (ch) { case 'd': pkg_set(pkg, PKG_AUTOMATIC, (int64_t)true); break; case 'f': plist = optarg; break; case 'i': input_path = optarg; break; case 'l': legacy = true; break; case 'M': metadata_only = true; mfile = optarg; break; case 'm': mdir = optarg; break; case 'O': old = true; break; case 't': testing_mode = true; break; default: warnx("Unrecognised option -%c\n", ch); usage_register(); return (EX_USAGE); } } if (!old) { retcode = pkgdb_access(PKGDB_MODE_READ | PKGDB_MODE_WRITE | PKGDB_MODE_CREATE, PKGDB_DB_LOCAL); if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privilege to register packages"); return (EX_NOPERM); } else if (retcode != EPKG_OK) return (EX_IOERR); else retcode = EX_OK; } /* * Ideally, the +MANIFEST should be all that is necessary, * since it can contain all of the meta-data supplied by the * other files mentioned below. These are here for backwards * compatibility with the way the ports tree works with * pkg_tools. * * The -M option specifies one manifest file to read the * meta-data from, and overrides the use of legacy meta-data * inputs. * * Dependencies, shlibs, files etc. may be derived by * analysing the package files (maybe discovered as the * content of the staging directory) unless -t (testing_mode) * is used. */ if (mfile != NULL && mdir != NULL) { warnx("Cannot use both -m and -M together"); usage_register(); return (EX_USAGE); } if (mfile == NULL && mdir == NULL) { warnx("one of either -m or -M flags is required"); usage_register(); return (EX_USAGE); } if (mfile != NULL && plist != NULL) { warnx("-M incompatible with -f option"); usage_register(); return (EX_USAGE); } if (testing_mode && input_path != NULL) { warnx("-i incompatible with -t option"); usage_register(); return (EX_USAGE); } pkg_manifest_keys_new(&keys); if (mfile != NULL) { ret = pkg_load_manifest_file(pkg, mfile, keys); pkg_manifest_keys_free(keys); if (ret != EPKG_OK) return (EX_IOERR); } else { snprintf(fpath, sizeof(fpath), "%s/+MANIFEST", mdir); ret = pkg_load_manifest_file(pkg, fpath, keys); pkg_manifest_keys_free(keys); if (ret != EPKG_OK) return (EX_IOERR); snprintf(fpath, sizeof(fpath), "%s/+DESC", mdir); pkg_set_from_file(pkg, PKG_DESC, fpath, false); snprintf(fpath, sizeof(fpath), "%s/+DISPLAY", mdir); if (access(fpath, F_OK) == 0) pkg_set_from_file(pkg, PKG_MESSAGE, fpath, false); snprintf(fpath, sizeof(fpath), "%s/+MTREE_DIRS", mdir); if (access(fpath, F_OK) == 0) pkg_set_from_file(pkg, PKG_MTREE, fpath, false); for (i = 0; scripts[i] != NULL; i++) { snprintf(fpath, sizeof(fpath), "%s/%s", mdir, scripts[i]); if (access(fpath, F_OK) == 0) pkg_addscript_file(pkg, fpath); } if (www != NULL) { pkg_set(pkg, PKG_WWW, www); free(www); } pkg_get(pkg, PKG_WWW, &www); /* * if www is not given then try to determine it from * description */ if (www == NULL) { pkg_get(pkg, PKG_DESC, &desc); regcomp(&preg, "^WWW:[[:space:]]*(.*)$", REG_EXTENDED|REG_ICASE|REG_NEWLINE); if (regexec(&preg, desc, 2, pmatch, 0) == 0) { size = pmatch[1].rm_eo - pmatch[1].rm_so; www = strndup(&desc[pmatch[1].rm_so], size); pkg_set(pkg, PKG_WWW, www); free(www); } else { pkg_set(pkg, PKG_WWW, "UNKNOWN"); } regfree(&preg); } if (plist != NULL) ret += ports_parse_plist(pkg, plist, input_path); } if (ret != EPKG_OK) { return (EX_IOERR); } if (!old && pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) { return (EX_IOERR); } /* * testing_mode allows updating the local package database * without any check that the files etc. listed in the meta * data actually exist on the system. Inappropriate use of * testing_mode can really screw things up. */ if (!testing_mode) pkg_analyse_files(db, pkg); pkg_get(pkg, PKG_ARCH, &arch); if (arch == NULL) { /* * do not take the one from configuration on purpose * but the real abi of the package. */ pkg_get_myarch(myarch, BUFSIZ); if (developer) pkg_suggest_arch(pkg, myarch, true); pkg_set(pkg, PKG_ARCH, myarch); } else { if (developer) pkg_suggest_arch(pkg, arch, false); } if (!testing_mode && input_path != NULL) pkg_copy_tree(pkg, input_path, "/"); if (old) { if (pkg_register_old(pkg) != EPKG_OK) retcode = EX_SOFTWARE; } else { if (pkgdb_register_ports(db, pkg) != EPKG_OK) retcode = EX_SOFTWARE; } if (!legacy && pkg_has_message(pkg)) pkg_printf("%M\n", pkg); if (!old) pkgdb_close(db); pkg_free(pkg); return (retcode); }