2 * Copyright (c) 2019 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * This code uses concepts and configuration based on 'synth', by
8 * John R. Marino <draco@marino.st>, which was written in ada.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
20 * 3. Neither the name of The DragonFly Project nor the names of its
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific, prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
32 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
34 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 #define PKG_HSIZE 32768
41 #define PKG_HMASK 32767
43 static int parsepkglist_file(const char *path, int debugstop);
44 static void childGetPackageInfo(bulk_t *bulk);
45 static void childGetBinaryDistInfo(bulk_t *bulk);
46 static void childOptimizeEnv(bulk_t *bulk);
47 static pkg_t *resolveDeps(pkg_t *dep_list, pkg_t ***list_tailp, int gentopo);
48 static void resolveDepString(pkg_t *pkg, char *depstr,
49 int gentopo, int dep_type);
50 static pkg_t *processPackageListBulk(int total);
51 static int scan_and_queue_dir(const char *path, const char *level1, int level);
52 static int scan_binary_repo(const char *path);
54 static void pkgfree(pkg_t *pkg);
57 pkg_t *PkgHash1[PKG_HSIZE]; /* by portdir */
58 pkg_t *PkgHash2[PKG_HSIZE]; /* by pkgfile */
61 * Allocate a new pkg structure plus basic initialization.
63 static __inline pkg_t *
68 pkg = calloc(1, sizeof(*pkg));
69 pkg->idepon_list.next = &pkg->idepon_list;
70 pkg->idepon_list.prev = &pkg->idepon_list;
71 pkg->deponi_list.next = &pkg->deponi_list;
72 pkg->deponi_list.prev = &pkg->deponi_list;
78 * Simple hash for lookups
81 pkghash(const char *str)
85 hv = (hv << 5) ^ *str;
88 hv = hv ^ (hv / PKG_HSIZE) ^ (hv / PKG_HSIZE / PKG_HSIZE);
89 return (hv & PKG_HMASK);
99 pkgp = &PkgHash1[pkghash(pkg->portdir)];
100 while ((scan = *pkgp) != NULL) {
101 if (strcmp(pkg->portdir, scan->portdir) == 0)
103 pkgp = &scan->hnext1;
105 if (scan && (scan->flags & PKGF_PLACEHOLD)) {
107 pkg->hnext1 = scan->hnext1;
117 pkgp = &PkgHash2[pkghash(pkg->pkgfile)];
118 while ((scan = *pkgp) != NULL) {
119 if (strcmp(pkg->pkgfile, scan->pkgfile) == 0)
121 pkgp = &scan->hnext2;
129 pkg_find(const char *match)
134 pkgp = &PkgHash1[pkghash(match)];
135 for (pkg = *pkgp; pkg; pkg = pkg->hnext1) {
136 if (strcmp(pkg->portdir, match) == 0)
139 pkgp = &PkgHash2[pkghash(match)];
140 for (pkg = *pkgp; pkg; pkg = pkg->hnext2) {
141 if (strcmp(pkg->pkgfile, match) == 0)
148 * Parse a specific list of ports via origin name (portdir/subdir)
151 ParsePackageList(int n, char **ary, int debugstop)
158 initbulk(childGetPackageInfo, MaxBulk);
161 * Always include ports-mgmt/pkg. s4 is "x" meaning not a manual
162 * selection, "d" meaning DEBUGSTOP mode, or NULL.
164 queuebulk("ports-mgmt", "pkg", NULL, "x");
166 for (i = 0; i < n; ++i) {
173 if (stat(l1, &st) == 0 && S_ISREG(st.st_mode)) {
174 total += parsepkglist_file(l1, debugstop);
178 l2 = strchr(l1, '/');
180 printf("Bad portdir specification: %s\n", l1);
185 l3 = strchr(l2, '@');
188 queuebulk(l1, l2, l3, (debugstop ? "d" : NULL));
192 printf("Processing %d ports\n", total);
194 list = processPackageListBulk(total);
201 parsepkglist_file(const char *path, int debugstop)
211 if ((fp = fopen(path, "r")) == NULL) {
212 dpanic_errno("Cannot read %s\n", path);
219 while ((base = fgetln(fp, &len)) != NULL) {
220 if (len == 0 || base[len-1] != '\n')
223 l1 = strtok(base, " \t\r\n");
225 printf("Badly formatted pkg info line: %s\n", base);
228 l2 = strchr(l1, '/');
230 printf("Badly formatted specification: %s\n", l1);
234 l3 = strchr(l2, '@');
237 queuebulk(l1, l2, l3, (debugstop ? "d" : NULL));
246 * Parse packages from the list installed on the system.
249 GetLocalPackageList(void)
260 initbulk(childGetPackageInfo, MaxBulk);
263 fp = popen("pkg info -a -o", "r");
266 * Always include ports-mgmt/pkg. s4 is "x" meaning not a manual
267 * selection, "d" meaning DEBUGSTOP mode, or NULL.
269 queuebulk("ports-mgmt", "pkg", NULL, "x");
271 while ((base = fgetln(fp, &len)) != NULL) {
272 if (len == 0 || base[len-1] != '\n')
275 if (strtok(base, " \t") == NULL) {
276 printf("Badly formatted pkg info line: %s\n", base);
279 l1 = strtok(NULL, " \t");
281 printf("Badly formatted pkg info line: %s\n", base);
285 l2 = strchr(l1, '/');
287 printf("Badly formatted specification: %s\n", l1);
291 l3 = strchr(l2, '@');
294 queuebulk(l1, l2, l3, NULL);
299 printf("Processing %d ports\n", total);
301 list = processPackageListBulk(total);
307 GetFullPackageList(void)
311 initbulk(childGetPackageInfo, MaxBulk);
313 total = scan_and_queue_dir(DPortsPath, NULL, 1);
314 printf("Scanning %d ports\n", total);
316 return processPackageListBulk(total);
320 * Caller has queued the process list for bulk operation. We retrieve
321 * the results and clean up the bulk operation (we may have to do a second
322 * bulk operation so we have to be the ones to clean it up).
325 processPackageListBulk(int total)
338 while ((bulk = getbulk()) != NULL) {
340 if ((count & 255) == 0) {
342 (double)count * 100.0 / (double)total + 0.001);
346 *list_tail = bulk->list;
348 while ((scan = *list_tail) != NULL) {
349 if (bulk->s4 == NULL || bulk->s4[0] != 'x')
350 scan->flags |= PKGF_MANUALSEL;
352 list_tail = &scan->bnext;
357 printf("100.00%%\n");
358 printf("\nTotal %d\n", count);
362 * Resolve all dependencies for the related packages, potentially
363 * adding anything that could not be found to the list. This will
364 * continue to issue bulk operations and process the result until
365 * no dependencies are left.
367 printf("Resolving dependencies...");
371 dep_list = resolveDeps(dep_list, &list_tail, 0);
378 * Generate the topology
380 resolveDeps(list, NULL, 1);
383 * Do a final count, ignore place holders.
386 for (scan = list; scan; scan = scan->bnext) {
387 if ((scan->flags & PKGF_ERROR) == 0) {
391 printf("Total Returned %d\n", count);
394 * Scan our binary distributions and related dependencies looking
395 * for any packages that have already been built.
397 initbulk(childGetBinaryDistInfo, MaxBulk);
398 total = scan_binary_repo(RepositoryPath);
400 printf("Scanning %d packages\n", total);
402 while ((bulk = getbulk()) != NULL) {
404 if ((count & 255) == 0) {
406 (double)count * 100.0 / (double)total + 0.001);
411 printf("100.00%%\n");
412 printf("\nTotal %d\n", count);
416 printf("all done\n");
422 GetPkgPkg(pkg_t *list)
427 for (scan = list; scan; scan = scan->bnext) {
428 if (strcmp(scan->portdir, "ports-mgmt/pkg") == 0)
433 * This will force pkg to be built, but generally this code
434 * is not reached because the package list processing code
435 * adds ports-mgmt/pkg unconditionally.
437 initbulk(childGetPackageInfo, MaxBulk);
438 queuebulk("ports-mgmt", "pkg", NULL, "x");
440 dassert(bulk, "Cannot find ports-mgmt/pkg");
450 * Try to optimize the environment by supplying information that
451 * the ports system would generally have to run stuff to get on
454 * See childOptimizeEnv() for the actual handling. We execute
455 * a single make -V... -V... for ports-mgmt/pkg from within the
456 * bulk system (which handles the environment and disables
457 * /etc/make.conf), and we then call addbuildenv() as appropriate.
467 initbulk(childOptimizeEnv, MaxBulk);
468 queuebulk("ports-mgmt", "pkg", NULL, NULL);
475 * Run through the list resolving dependencies and constructing the topology
476 * linkages. This may append packages to the list.
479 resolveDeps(pkg_t *list, pkg_t ***list_tailp, int gentopo)
482 pkg_t *ret_list = NULL;
485 for (scan = list; scan; scan = scan->bnext) {
486 resolveDepString(scan, scan->fetch_deps,
487 gentopo, DEP_TYPE_FETCH);
488 resolveDepString(scan, scan->ext_deps,
489 gentopo, DEP_TYPE_EXT);
490 resolveDepString(scan, scan->patch_deps,
491 gentopo, DEP_TYPE_PATCH);
492 resolveDepString(scan, scan->build_deps,
493 gentopo, DEP_TYPE_BUILD);
494 resolveDepString(scan, scan->lib_deps,
495 gentopo, DEP_TYPE_LIB);
496 resolveDepString(scan, scan->run_deps,
497 gentopo, DEP_TYPE_RUN);
501 * No bulk ops are queued when doing the final topology
506 while ((bulk = getbulk()) != NULL) {
508 if (ret_list == NULL)
509 ret_list = bulk->list;
510 **list_tailp = bulk->list;
512 while (**list_tailp) {
513 pkg_enter(**list_tailp);
514 *list_tailp = &(**list_tailp)->bnext;
523 resolveDepString(pkg_t *pkg, char *depstr, int gentopo, int dep_type)
533 if (depstr == NULL || depstr[0] == 0)
536 copy_base = strdup(depstr);
541 dep = strsep(©, " \t");
542 } while (dep && *dep == 0);
547 * Ignore dependencies prefixed with ${NONEXISTENT}
549 if (strncmp(dep, "/nonexistent:", 13) == 0)
552 dep = strchr(dep, ':');
553 if (dep == NULL || *dep != ':') {
554 printf("Error parsing dependency for %s: %s\n",
555 pkg->portdir, copy_base);
561 * Strip-off any DPortsPath prefix. EXTRACT_DEPENDS
562 * often (always?) generates this prefix.
564 if (strncmp(dep, DPortsPath, strlen(DPortsPath)) == 0) {
565 dep += strlen(DPortsPath);
571 * Strip-off any tag (such as :patch). We don't try to
572 * organize dependencies at this fine a grain (for now).
574 tag = strchr(dep, ':');
579 * Locate the dependency
581 if ((dpkg = pkg_find(dep)) != NULL) {
586 * NOTE: idep_count is calculated recursively
589 ddprintf(0, "Add Dependency %s -> %s\n",
590 pkg->portdir, dpkg->portdir);
591 link = calloc(1, sizeof(*link));
593 link->next = &pkg->idepon_list;
594 link->prev = pkg->idepon_list.prev;
595 link->next->prev = link;
596 link->prev->next = link;
597 link->dep_type = dep_type;
599 link = calloc(1, sizeof(*link));
601 link->next = &dpkg->deponi_list;
602 link->prev = dpkg->deponi_list.prev;
603 link->next->prev = link;
604 link->prev->next = link;
605 link->dep_type = dep_type;
612 * This shouldn't happen because we already took a first
613 * pass and should have generated the pkgs.
616 printf("Topology Generate failed for %s: %s\n",
617 pkg->portdir, copy_base);
622 * Separate out the two dports directory components and
623 * extract the optional '@flavor' specification.
625 sep = strchr(dep, '/');
627 printf("Error parsing dependency for %s: %s\n",
628 pkg->portdir, copy_base);
634 flavor = strrchr(tag, '@');
636 flavor = strrchr(sep, '@');
642 ddprintf(0, "QUEUE DEPENDENCY FROM PKG %s: %s/%s@%s\n",
643 pkg->portdir, dep, sep, flavor);
645 ddprintf(0, "QUEUE DEPENDENCY FROM PKG %s: %s/%s\n",
646 pkg->portdir, dep, sep);
649 * Use a place-holder to prevent duplicate dependencies from
650 * being processed. The placeholder will be replaced by
651 * the actual dependency.
655 asprintf(&dpkg->portdir, "%s/%s@%s", dep, sep, flavor);
657 asprintf(&dpkg->portdir, "%s/%s", dep, sep);
658 dpkg->flags = PKGF_PLACEHOLD;
661 queuebulk(dep, sep, flavor, NULL);
667 FreePackageList(pkg_t *pkgs __unused)
669 dfatal("not implemented");
673 * Scan some or all dports to allocate the related pkg structure. Dependencies
674 * are stored but not processed.
679 childGetPackageInfo(bulk_t *bulk)
693 const char *cav[MAXCAC];
698 * If the package has flavors we will loop on each one. If a flavor
699 * is not passed in s3 we will loop on all flavors, otherwise we will
700 * only process the passed-in flavor.
702 flavor = bulk->s3; /* usually NULL */
708 list_tail = &bulk->list;
710 asprintf(&portpath, "%s/%s/%s", DPortsPath, bulk->s1, bulk->s2);
712 asprintf(&flavarg, "FLAVOR=%s", flavor);
717 cav[cac++] = MAKE_BINARY;
719 cav[cac++] = portpath;
721 cav[cac++] = flavarg;
722 cav[cac++] = "-VPKGVERSION";
723 cav[cac++] = "-VPKGFILE:T";
724 cav[cac++] = "-VDISTFILES";
725 cav[cac++] = "-VDIST_SUBDIR";
726 cav[cac++] = "-VMAKE_JOBS_NUMBER";
727 cav[cac++] = "-VIGNORE";
728 cav[cac++] = "-VFETCH_DEPENDS";
729 cav[cac++] = "-VEXTRACT_DEPENDS";
730 cav[cac++] = "-VPATCH_DEPENDS";
731 cav[cac++] = "-VBUILD_DEPENDS";
732 cav[cac++] = "-VLIB_DEPENDS";
733 cav[cac++] = "-VRUN_DEPENDS";
734 cav[cac++] = "-VSELECTED_OPTIONS";
735 cav[cac++] = "-VDESELECTED_OPTIONS";
736 cav[cac++] = "-VUSE_LINUX";
737 cav[cac++] = "-VFLAVORS";
738 cav[cac++] = "-VUSES";
740 fp = dexec_open(cav, cac, &pid, NULL, 1, 1);
746 asprintf(&pkg->portdir, "%s/%s@%s", bulk->s1, bulk->s2, flavor);
748 asprintf(&pkg->portdir, "%s/%s", bulk->s1, bulk->s2);
751 while ((ptr = fgetln(fp, &len)) != NULL) {
752 if (len == 0 || ptr[len-1] != '\n') {
753 dfatal("Bad package info for %s/%s response line %d",
754 bulk->s1, bulk->s2, line);
759 case 1: /* PKGVERSION */
760 asprintf(&pkg->version, "%s", ptr);
762 case 2: /* PKGFILE */
763 asprintf(&pkg->pkgfile, "%s", ptr);
765 case 3: /* DISTFILES */
766 asprintf(&pkg->distfiles, "%s", ptr);
768 case 4: /* DIST_SUBDIR */
769 pkg->distsubdir = strdup_or_null(ptr);
771 case 5: /* MAKE_JOBS_NUMBER */
772 pkg->make_jobs_number = strtol(ptr, NULL, 0);
775 pkg->ignore = strdup_or_null(ptr);
777 case 7: /* FETCH_DEPENDS */
778 pkg->fetch_deps = strdup_or_null(ptr);
780 case 8: /* EXTRACT_DEPENDS */
781 pkg->ext_deps = strdup_or_null(ptr);
783 case 9: /* PATCH_DEPENDS */
784 pkg->patch_deps = strdup_or_null(ptr);
786 case 10: /* BUILD_DEPENDS */
787 pkg->build_deps = strdup_or_null(ptr);
789 case 11: /* LIB_DEPENDS */
790 pkg->lib_deps = strdup_or_null(ptr);
792 case 12: /* RUN_DEPENDS */
793 pkg->run_deps = strdup_or_null(ptr);
795 case 13: /* SELECTED_OPTIONS */
796 pkg->pos_options = strdup_or_null(ptr);
798 case 14: /* DESELECTED_OPTIONS */
799 pkg->neg_options = strdup_or_null(ptr);
801 case 15: /* USE_LINUX */
805 case 16: /* FLAVORS */
806 asprintf(&pkg->flavors, "%s", ptr);
809 asprintf(&pkg->uses, "%s", ptr);
810 if (strstr(pkg->uses, "metaport"))
811 pkg->flags |= PKGF_META;
814 printf("EXTRA LINE: %s\n", ptr);
820 printf("DPort not found: %s/%s\n", bulk->s1, bulk->s2);
821 pkg->flags |= PKGF_NOTFOUND;
822 } else if (line != 17 + 1) {
823 printf("DPort corrupt: %s/%s\n", bulk->s1, bulk->s2);
824 pkg->flags |= PKGF_CORRUPT;
826 if (dexec_close(fp, pid)) {
827 printf("make -V* command for %s/%s failed\n",
829 pkg->flags |= PKGF_CORRUPT;
836 if (bulk->s4 && bulk->s4[0] == 'd')
837 pkg->flags |= PKGF_DEBUGSTOP;
842 if (flavor == NULL) {
844 * If there are flavors add the current unflavored pkg
845 * as a dummy node so dependencies can attach to it,
846 * then iterate the first flavor and loop.
848 * We must NULL out pkgfile because it will have the
849 * default flavor and conflict with the actual flavored
852 if (pkg->flavors && pkg->flavors[0]) {
855 pkg->flags |= PKGF_DUMMY;
857 freestrp(&pkg->fetch_deps);
858 freestrp(&pkg->ext_deps);
859 freestrp(&pkg->patch_deps);
860 freestrp(&pkg->build_deps);
861 freestrp(&pkg->lib_deps);
862 freestrp(&pkg->run_deps);
864 freestrp(&pkg->pkgfile);
867 list_tail = &(*list_tail)->bnext;
869 flavors_save = strdup(pkg->flavors);
870 flavors = flavors_save;
872 flavor = strsep(&flavors, " \t");
873 } while (flavor && *flavor == 0);
878 * No flavors, add the current unflavored pkg as a real
883 list_tail = &(*list_tail)->bnext;
886 * Add flavored package and iterate.
890 list_tail = &(*list_tail)->bnext;
893 * Flavor iteration under dummy node, add dependency
898 ddprintf(0, "Add Dependency %s -> %s (flavor rollup)\n",
899 dummy_node->portdir, pkg->portdir);
900 link = calloc(1, sizeof(*link));
902 link->next = &dummy_node->idepon_list;
903 link->prev = dummy_node->idepon_list.prev;
904 link->next->prev = link;
905 link->prev->next = link;
906 link->dep_type = DEP_TYPE_BUILD;
908 link = calloc(1, sizeof(*link));
909 link->pkg = dummy_node;
910 link->next = &pkg->deponi_list;
911 link->prev = pkg->deponi_list.prev;
912 link->next->prev = link;
913 link->prev->next = link;
914 link->dep_type = DEP_TYPE_BUILD;
920 flavor = strsep(&flavors, " \t");
921 } while (flavor && *flavor == 0);
930 * Query the package (at least to make sure it hasn't been truncated)
931 * and mark it as PACKAGED if found.
936 childGetBinaryDistInfo(bulk_t *bulk)
942 const char *cav[MAXCAC];
948 asprintf(&repopath, "%s/%s", RepositoryPath, bulk->s1);
951 cav[cac++] = PKG_BINARY;
952 cav[cac++] = "query";
954 cav[cac++] = repopath;
955 cav[cac++] = "%n-%v";
957 fp = dexec_open(cav, cac, &pid, NULL, 1, 0);
959 while ((ptr = fgetln(fp, &len)) != NULL) {
960 if (len == 0 || ptr[len-1] != '\n')
963 snprintf(buf, sizeof(buf), "%s%s", ptr, UsePkgSufx);
967 pkg->flags |= PKGF_PACKAGED;
969 ddprintf(0, "Note: package scan, not in list, "
970 "skipping %s\n", buf);
973 if (dexec_close(fp, pid)) {
974 printf("pkg query command failed for %s\n", repopath);
980 childOptimizeEnv(bulk_t *bulk)
987 const char *cav[MAXCAC];
991 asprintf(&portpath, "%s/%s/%s", DPortsPath, bulk->s1, bulk->s2);
994 cav[cac++] = MAKE_BINARY;
996 cav[cac++] = portpath;
997 cav[cac++] = "-V_PERL5_FROM_BIN";
999 fp = dexec_open(cav, cac, &pid, NULL, 1, 1);
1003 while ((ptr = fgetln(fp, &len)) != NULL) {
1004 if (len == 0 || ptr[len-1] != '\n') {
1005 dfatal("Bad package info for %s/%s response line %d",
1006 bulk->s1, bulk->s2, line);
1011 case 1: /* _PERL5_FROM_BIN */
1012 addbuildenv("_PERL5_FROM_BIN", ptr, BENV_ENVIRONMENT);
1015 printf("childOptimizeEnv: EXTRA LINE: %s\n", ptr);
1021 printf("DPort not found: %s/%s\n", bulk->s1, bulk->s2);
1022 } else if (line != 1 + 1) {
1023 printf("DPort corrupt: %s/%s\n", bulk->s1, bulk->s2);
1025 if (dexec_close(fp, pid)) {
1026 printf("childOptimizeEnv() failed\n");
1031 scan_and_queue_dir(const char *path, const char *level1, int level)
1040 dir = opendir(path);
1041 dassert(dir, "Cannot open dports path \"%s\"", path);
1043 while ((den = readdir(dir)) != NULL) {
1044 if (den->d_namlen == 1 && den->d_name[0] == '.')
1046 if (den->d_namlen == 2 &&
1047 den->d_name[0] == '.' && den->d_name[1] == '.')
1049 asprintf(&s1, "%s/%s", path, den->d_name);
1050 if (lstat(s1, &st) < 0 || !S_ISDIR(st.st_mode)) {
1055 count += scan_and_queue_dir(s1, den->d_name, 2);
1059 asprintf(&s2, "%s/Makefile", s1);
1060 if (lstat(s2, &st) == 0) {
1061 queuebulk(level1, den->d_name, NULL, NULL);
1073 scan_binary_repo(const char *path)
1081 dir = opendir(path);
1082 dassert(dir, "Cannot open repository path \"%s\"", path);
1085 * NOTE: Test includes the '.' in the suffix.
1087 while ((den = readdir(dir)) != NULL) {
1088 len = strlen(den->d_name);
1090 strcmp(den->d_name + len - 4, UsePkgSufx) == 0) {
1091 queuebulk(den->d_name, NULL, NULL, NULL);
1104 freestrp(&pkg->portdir);
1105 freestrp(&pkg->version);
1106 freestrp(&pkg->pkgfile);
1107 freestrp(&pkg->ignore);
1108 freestrp(&pkg->fetch_deps);
1109 freestrp(&pkg->ext_deps);
1110 freestrp(&pkg->patch_deps);
1111 freestrp(&pkg->build_deps);
1112 freestrp(&pkg->lib_deps);
1113 freestrp(&pkg->run_deps);
1114 freestrp(&pkg->pos_options);
1115 freestrp(&pkg->neg_options);
1116 freestrp(&pkg->flavors);