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 resolveFlavors(pkg_t *pkg, char *flavors, int gentopo);
49 static void resolveDepString(pkg_t *pkg, char *depstr,
50 int gentopo, int dep_type);
51 static pkg_t *processPackageListBulk(int total);
52 static int scan_and_queue_dir(const char *path, const char *level1, int level);
53 static int scan_binary_repo(const char *path);
55 static void pkgfree(pkg_t *pkg);
58 static int PrepareSystemFlag;
60 pkg_t *PkgHash1[PKG_HSIZE]; /* by portdir */
61 pkg_t *PkgHash2[PKG_HSIZE]; /* by pkgfile */
64 * Allocate a new pkg structure plus basic initialization.
66 static __inline pkg_t *
71 pkg = calloc(1, sizeof(*pkg));
72 pkg->idepon_list.next = &pkg->idepon_list;
73 pkg->idepon_list.prev = &pkg->idepon_list;
74 pkg->deponi_list.next = &pkg->deponi_list;
75 pkg->deponi_list.prev = &pkg->deponi_list;
81 * Simple hash for lookups
84 pkghash(const char *str)
88 hv = (hv << 5) ^ *str;
91 hv = hv ^ (hv / PKG_HSIZE) ^ (hv / PKG_HSIZE / PKG_HSIZE);
92 return (hv & PKG_HMASK);
102 pkgp = &PkgHash1[pkghash(pkg->portdir)];
103 while ((scan = *pkgp) != NULL) {
104 if (strcmp(pkg->portdir, scan->portdir) == 0)
106 pkgp = &scan->hnext1;
108 ddassert(scan == NULL || (scan->flags & PKGF_PLACEHOLD));
109 if (scan && (scan->flags & PKGF_PLACEHOLD)) {
110 ddassert(scan->idepon_list.next == &scan->idepon_list);
111 ddassert(scan->deponi_list.next == &scan->deponi_list);
113 pkg->hnext1 = scan->hnext1;
123 pkgp = &PkgHash2[pkghash(pkg->pkgfile)];
124 while ((scan = *pkgp) != NULL) {
125 if (strcmp(pkg->pkgfile, scan->pkgfile) == 0)
127 pkgp = &scan->hnext2;
135 pkg_find(const char *match)
140 pkgp = &PkgHash1[pkghash(match)];
141 for (pkg = *pkgp; pkg; pkg = pkg->hnext1) {
142 if (strcmp(pkg->portdir, match) == 0)
145 pkgp = &PkgHash2[pkghash(match)];
146 for (pkg = *pkgp; pkg; pkg = pkg->hnext2) {
147 if (strcmp(pkg->pkgfile, match) == 0)
154 * Parse a specific list of ports via origin name (portdir/subdir)
157 ParsePackageList(int n, char **ary, int debugstop)
166 initbulk(childGetPackageInfo, MaxBulk);
169 * Always include ports-mgmt/pkg. s4 is "x" meaning not a manual
170 * selection, "d" meaning DEBUGSTOP mode, or NULL.
172 queuebulk("ports-mgmt", "pkg", NULL, "x");
174 for (i = 0; i < n; ++i) {
181 if (stat(l1, &st) == 0 && S_ISREG(st.st_mode)) {
182 total += parsepkglist_file(l1, debugstop);
186 l2 = strchr(l1, '/');
188 printf("Bad portdir specification: %s\n", l1);
194 l3 = strchr(l2, '@');
197 queuebulk(l1, l2, l3, (debugstop ? "d" : NULL));
201 printf("Processing %d ports\n", total);
203 list = processPackageListBulk(total);
205 dfatal("Bad specifications, exiting");
214 parsepkglist_file(const char *path, int debugstop)
224 if ((fp = fopen(path, "r")) == NULL) {
225 dpanic_errno("Cannot read %s\n", path);
232 while ((base = fgetln(fp, &len)) != NULL) {
233 if (len == 0 || base[len-1] != '\n')
236 l1 = strtok(base, " \t\r\n");
238 printf("Badly formatted pkg info line: %s\n", base);
241 l2 = strchr(l1, '/');
243 printf("Badly formatted specification: %s\n", l1);
247 l3 = strchr(l2, '@');
250 queuebulk(l1, l2, l3, (debugstop ? "d" : NULL));
259 * Parse packages from the list installed on the system.
262 GetLocalPackageList(void)
275 PrepareSystemFlag = 1;
276 initbulk(childGetPackageInfo, MaxBulk);
283 fp = popen("pkg info -a -o -A", "r");
286 * Always include ports-mgmt/pkg. s4 is "x" meaning not a manual
287 * selection, "d" meaning DEBUGSTOP mode, or NULL.
289 queuebulk("ports-mgmt", "pkg", NULL, "x");
291 while ((base = fgetln(fp, &len)) != NULL) {
292 if (len == 0 || base[len-1] != '\n')
296 data = strchr(base, ':');
301 base = strtok(base, " \t\r");
302 data = strtok(data, " \t\r");
304 if (base == NULL || data == NULL)
307 if (strcmp(base, "Origin") == 0) {
309 queuebulk(l1, l2, NULL, NULL);
314 if (strchr(data, '/') == NULL) {
315 printf("Badly formatted origin: %s\n", l1);
322 l2 = strchr(l1, '/');
324 l3 = strchr(l2, '@'); /* typically NULL */
331 * Don't queue ports-mgmt/pkg twice, we already
332 * queued it manually.
334 if (strcmp(l1, "ports-mgmt") != 0 ||
335 strcmp(l2, "pkg") != 0) {
340 if (state == 1 && strcmp(base, "flavor") == 0) {
341 queuebulk(l1, l2, data, NULL);
347 queuebulk(l1, l2, NULL, NULL);
348 /*state = 0; not needed */
357 printf("Processing %d ports\n", total);
359 list = processPackageListBulk(total);
365 GetFullPackageList(void)
369 initbulk(childGetPackageInfo, MaxBulk);
370 total = scan_and_queue_dir(DPortsPath, NULL, 1);
371 printf("Scanning %d ports\n", total);
373 return processPackageListBulk(total);
377 * Caller has queued the process list for bulk operation. We retrieve
378 * the results and clean up the bulk operation (we may have to do a second
379 * bulk operation so we have to be the ones to clean it up).
382 processPackageListBulk(int total)
399 while ((bulk = getbulk()) != NULL) {
401 if ((count & 255) == 0) {
403 (double)count * 100.0 / (double)total + 0.001);
407 *list_tail = bulk->list;
409 while ((scan = *list_tail) != NULL) {
410 if (bulk->s4 == NULL || bulk->s4[0] != 'x')
411 scan->flags |= PKGF_MANUALSEL;
413 list_tail = &scan->bnext;
418 printf("100.00%%\n");
419 printf("\nTotal %d\n", count);
423 * Resolve all dependencies for the related packages, potentially
424 * adding anything that could not be found to the list. This will
425 * continue to issue bulk operations and process the result until
426 * no dependencies are left.
428 printf("Resolving dependencies...");
432 dep_list = resolveDeps(dep_list, &list_tail, 0);
439 * Generate the topology
441 resolveDeps(list, NULL, 1);
444 * Do a final count, ignore place holders.
446 * Also set stop_fail if appropriate. Check for direct specifications
447 * which fail to probe and any direct dependencies of those
448 * specifications, but don't recurse (for now)... don't check indirect
449 * dependencies (i.e. A -> B -> C where A is directly specified, B
450 * is adirect dependency, and C fails to probe).
455 for (scan = list; scan; scan = scan->bnext) {
456 if ((scan->flags & PKGF_ERROR) == 0) {
459 if ((scan->flags & PKGF_MANUALSEL) && MaskProbeAbort == 0) {
463 * Directly specified package failed to probe
465 if (scan->flags & PKGF_CORRUPT) {
471 * Directly specified package had a direct dependency
472 * that failed to probe (don't go further).
474 PKGLIST_FOREACH(link, &scan->idepon_list) {
476 (link->pkg->flags & PKGF_CORRUPT)) {
482 printf("Total Returned %d\n", count);
485 * Check to see if any PKGF_MANUALSEL packages
488 printf("%d packages failed to probe\n", stop_fail);
489 if (PrepareSystemFlag) {
490 if (stop_fail == stop_base_list) {
492 "prepare-system: Some of your installed packages no longer exist in\n"
493 "dports, do you wish to continue rebuilding what does exist?\n");
494 if (askyn("Continue anyway? "))
498 "prepare-system: Some of your installed packages have dependencies\n"
499 "which could not be found in dports, cannot continue, aborting\n");
502 printf("unable to continue, aborting\n");
504 if (remove_corrupt == 0)
509 * Remove corrupt packages before continuing
511 if (remove_corrupt) {
513 while ((scan = *list_tail) != NULL) {
514 if (scan->flags & PKGF_CORRUPT)
515 *list_tail = scan->bnext;
517 list_tail = &scan->bnext;
522 * Scan our binary distributions and related dependencies looking
523 * for any packages that have already been built.
525 initbulk(childGetBinaryDistInfo, MaxBulk);
526 total = scan_binary_repo(RepositoryPath);
528 printf("Scanning %d packages\n", total);
530 while ((bulk = getbulk()) != NULL) {
532 if ((count & 255) == 0) {
534 (double)count * 100.0 / (double)total + 0.001);
539 printf("100.00%%\n");
540 printf("\nTotal %d\n", count);
544 printf("all done\n");
550 GetPkgPkg(pkg_t **listp)
556 for (scan = *listp; scan; scan = scan->bnext) {
557 if (strcmp(scan->portdir, "ports-mgmt/pkg") == 0)
562 * This will force pkg to be built, but generally this code
563 * is not reached because the package list processing code
564 * adds ports-mgmt/pkg unconditionally.
566 initbulk(childGetPackageInfo, MaxBulk);
567 queuebulk("ports-mgmt", "pkg", NULL, "x");
569 dassert(bulk, "Cannot find ports-mgmt/pkg");
577 * Include added packages to the total and add the initial bulk
578 * built packages to the list so they get counted.
580 for (s2 = scan; s2->bnext; s2 = s2->bnext)
582 for (s2 = scan; s2->bnext; s2 = s2->bnext)
592 * Try to optimize the environment by supplying information that
593 * the ports system would generally have to run stuff to get on
596 * See childOptimizeEnv() for the actual handling. We execute
597 * a single make -V... -V... for ports-mgmt/pkg from within the
598 * bulk system (which handles the environment and disables
599 * /etc/make.conf), and we then call addbuildenv() as appropriate.
609 initbulk(childOptimizeEnv, MaxBulk);
610 queuebulk("ports-mgmt", "pkg", NULL, NULL);
617 * Run through the list resolving dependencies and constructing the topology
618 * linkages. This may append packages to the list. Dependencies to dummy
619 * nodes which do not specify a flavor do not need special handling, the
620 * search code in build.c will properly follow the first flavor.
623 resolveDeps(pkg_t *list, pkg_t ***list_tailp, int gentopo)
625 pkg_t *ret_list = NULL;
630 for (scan = list; scan; scan = scan->bnext) {
631 use = pkg_find(scan->portdir);
632 resolveFlavors(use, scan->flavors, gentopo);
633 resolveDepString(use, scan->fetch_deps,
634 gentopo, DEP_TYPE_FETCH);
635 resolveDepString(use, scan->ext_deps,
636 gentopo, DEP_TYPE_EXT);
637 resolveDepString(use, scan->patch_deps,
638 gentopo, DEP_TYPE_PATCH);
639 resolveDepString(use, scan->build_deps,
640 gentopo, DEP_TYPE_BUILD);
641 resolveDepString(use, scan->lib_deps,
642 gentopo, DEP_TYPE_LIB);
643 resolveDepString(use, scan->run_deps,
644 gentopo, DEP_TYPE_RUN);
648 * No bulk ops are queued when doing the final topology
651 * Avoid entering duplicate results from the bulk ops. Duplicate
652 * results are mostly filtered out, but not always. A dummy node
653 * representing multiple flavors will parse-out the flavors
657 while ((bulk = getbulk()) != NULL) {
659 if (ret_list == NULL)
660 ret_list = bulk->list;
661 **list_tailp = bulk->list;
663 while ((scan = **list_tailp) != NULL) {
665 *list_tailp = &scan->bnext;
674 * Resolve a generic node that has flavors, queue to retrieve info for
675 * each flavor and setup linkages as appropriate.
678 resolveFlavors(pkg_t *pkg, char *flavors, int gentopo)
689 if ((pkg->flags & PKGF_DUMMY) == 0)
691 if (pkg->flavors == NULL || pkg->flavors[0] == 0)
693 flavor_base = strdup(flavors);
694 flavor_scan = flavor_base;
698 flavor = strsep(&flavor_scan, " \t");
699 } while (flavor && *flavor == 0);
704 * Iterate each flavor generating "s1/s2@flavor".
706 * queuebulk() info for each flavor, and set-up the
707 * linkages in the topology generation pass.
709 asprintf(&portdir, "%s@%s", pkg->portdir, flavor);
710 s1 = strdup(pkg->portdir);
711 s2 = strchr(s1, '/');
714 dpkg = pkg_find(portdir);
715 if (dpkg && gentopo) {
721 link = calloc(1, sizeof(*link));
723 link->next = &pkg->idepon_list;
724 link->prev = pkg->idepon_list.prev;
725 link->next->prev = link;
726 link->prev->next = link;
727 link->dep_type = DEP_TYPE_BUILD;
729 link = calloc(1, sizeof(*link));
731 link->next = &dpkg->deponi_list;
732 link->prev = dpkg->deponi_list.prev;
733 link->next->prev = link;
734 link->prev->next = link;
735 link->dep_type = DEP_TYPE_BUILD;
737 } else if (gentopo == 0 && dpkg == NULL) {
739 * Use a place-holder to prevent duplicate
740 * dependencies from being processed. The placeholder
741 * will be replaced by the actual dependency.
744 dpkg->portdir = portdir;
745 dpkg->flags = PKGF_PLACEHOLD;
747 queuebulk(s1, s2, flavor, NULL);
755 resolveDepString(pkg_t *pkg, char *depstr, int gentopo, int dep_type)
765 if (depstr == NULL || depstr[0] == 0)
768 copy_base = strdup(depstr);
773 dep = strsep(©, " \t");
774 } while (dep && *dep == 0);
779 * Ignore dependencies prefixed with ${NONEXISTENT}
781 if (strncmp(dep, "/nonexistent:", 13) == 0)
784 dep = strchr(dep, ':');
785 if (dep == NULL || *dep != ':') {
786 printf("Error parsing dependency for %s: %s\n",
787 pkg->portdir, copy_base);
793 * Strip-off any DPortsPath prefix. EXTRACT_DEPENDS
794 * often (always?) generates this prefix.
796 if (strncmp(dep, DPortsPath, strlen(DPortsPath)) == 0) {
797 dep += strlen(DPortsPath);
803 * Strip-off any tag (such as :patch). We don't try to
804 * organize dependencies at this fine a grain (for now).
806 tag = strchr(dep, ':');
811 * Locate the dependency
813 if ((dpkg = pkg_find(dep)) != NULL) {
818 * NOTE: idep_count is calculated recursively
821 ddprintf(0, "Add Dependency %s -> %s\n",
822 pkg->portdir, dpkg->portdir);
823 link = calloc(1, sizeof(*link));
825 link->next = &pkg->idepon_list;
826 link->prev = pkg->idepon_list.prev;
827 link->next->prev = link;
828 link->prev->next = link;
829 link->dep_type = dep_type;
831 link = calloc(1, sizeof(*link));
833 link->next = &dpkg->deponi_list;
834 link->prev = dpkg->deponi_list.prev;
835 link->next->prev = link;
836 link->prev->next = link;
837 link->dep_type = dep_type;
844 * This shouldn't happen because we already took a first
845 * pass and should have generated the pkgs.
848 printf("Topology Generate failed for %s: %s\n",
849 pkg->portdir, copy_base);
854 * Separate out the two dports directory components and
855 * extract the optional '@flavor' specification.
857 sep = strchr(dep, '/');
859 printf("Error parsing dependency for %s: %s\n",
860 pkg->portdir, copy_base);
866 * The flavor hangs off the separator, not the tag
868 flavor = strrchr(sep, '@');
871 flavor = strrchr(tag, '@');
873 flavor = strrchr(sep, '@');
879 ddprintf(0, "QUEUE DEPENDENCY FROM PKG %s: %s/%s@%s\n",
880 pkg->portdir, dep, sep, flavor);
882 ddprintf(0, "QUEUE DEPENDENCY FROM PKG %s: %s/%s\n",
883 pkg->portdir, dep, sep);
886 * Use a place-holder to prevent duplicate dependencies from
887 * being processed. The placeholder will be replaced by
888 * the actual dependency.
892 asprintf(&dpkg->portdir, "%s/%s@%s", dep, sep, flavor);
894 asprintf(&dpkg->portdir, "%s/%s", dep, sep);
895 dpkg->flags = PKGF_PLACEHOLD;
898 queuebulk(dep, sep, flavor, NULL);
904 FreePackageList(pkg_t *pkgs __unused)
906 dfatal("not implemented");
910 * Scan some or all dports to allocate the related pkg structure. Dependencies
911 * are stored but not processed.
916 childGetPackageInfo(bulk_t *bulk)
926 const char *cav[MAXCAC];
931 * If the package has flavors we will loop on each one. If a flavor
932 * is not passed in s3 we will loop on all flavors, otherwise we will
933 * only process the passed-in flavor.
935 flavor = bulk->s3; /* usually NULL */
939 asprintf(&portpath, "%s/%s/%s", DPortsPath, bulk->s1, bulk->s2);
941 asprintf(&flavarg, "FLAVOR=%s", flavor);
946 cav[cac++] = MAKE_BINARY;
948 cav[cac++] = portpath;
950 cav[cac++] = flavarg;
951 cav[cac++] = "-VPKGVERSION";
952 cav[cac++] = "-VPKGFILE:T";
953 cav[cac++] = "-VALLFILES";
954 cav[cac++] = "-VDIST_SUBDIR";
955 cav[cac++] = "-VMAKE_JOBS_NUMBER";
956 cav[cac++] = "-VIGNORE";
957 cav[cac++] = "-VFETCH_DEPENDS";
958 cav[cac++] = "-VEXTRACT_DEPENDS";
959 cav[cac++] = "-VPATCH_DEPENDS";
960 cav[cac++] = "-VBUILD_DEPENDS";
961 cav[cac++] = "-VLIB_DEPENDS";
962 cav[cac++] = "-VRUN_DEPENDS";
963 cav[cac++] = "-VSELECTED_OPTIONS";
964 cav[cac++] = "-VDESELECTED_OPTIONS";
965 cav[cac++] = "-VUSE_LINUX";
966 cav[cac++] = "-VFLAVORS";
967 cav[cac++] = "-VUSES";
969 fp = dexec_open(cav, cac, &pid, NULL, 1, 1);
975 asprintf(&pkg->portdir, "%s/%s@%s", bulk->s1, bulk->s2, flavor);
977 asprintf(&pkg->portdir, "%s/%s", bulk->s1, bulk->s2);
980 while ((ptr = fgetln(fp, &len)) != NULL) {
981 if (len == 0 || ptr[len-1] != '\n') {
982 dfatal("Bad package info for %s/%s response line %d",
983 bulk->s1, bulk->s2, line);
988 case 1: /* PKGVERSION */
989 asprintf(&pkg->version, "%s", ptr);
991 case 2: /* PKGFILE */
992 asprintf(&pkg->pkgfile, "%s", ptr);
994 case 3: /* ALLFILES (aka DISTFILES + patch files) */
995 asprintf(&pkg->distfiles, "%s", ptr);
997 case 4: /* DIST_SUBDIR */
998 pkg->distsubdir = strdup_or_null(ptr);
1000 case 5: /* MAKE_JOBS_NUMBER */
1001 pkg->make_jobs_number = strtol(ptr, NULL, 0);
1003 case 6: /* IGNORE */
1004 pkg->ignore = strdup_or_null(ptr);
1006 case 7: /* FETCH_DEPENDS */
1007 pkg->fetch_deps = strdup_or_null(ptr);
1009 case 8: /* EXTRACT_DEPENDS */
1010 pkg->ext_deps = strdup_or_null(ptr);
1012 case 9: /* PATCH_DEPENDS */
1013 pkg->patch_deps = strdup_or_null(ptr);
1015 case 10: /* BUILD_DEPENDS */
1016 pkg->build_deps = strdup_or_null(ptr);
1018 case 11: /* LIB_DEPENDS */
1019 pkg->lib_deps = strdup_or_null(ptr);
1021 case 12: /* RUN_DEPENDS */
1022 pkg->run_deps = strdup_or_null(ptr);
1024 case 13: /* SELECTED_OPTIONS */
1025 pkg->pos_options = strdup_or_null(ptr);
1027 case 14: /* DESELECTED_OPTIONS */
1028 pkg->neg_options = strdup_or_null(ptr);
1030 case 15: /* USE_LINUX */
1034 case 16: /* FLAVORS */
1035 asprintf(&pkg->flavors, "%s", ptr);
1038 asprintf(&pkg->uses, "%s", ptr);
1039 if (strstr(pkg->uses, "metaport"))
1040 pkg->flags |= PKGF_META;
1043 printf("EXTRA LINE: %s\n", ptr);
1049 printf("DPort not found: %s/%s\n", bulk->s1, bulk->s2);
1050 pkg->flags |= PKGF_NOTFOUND;
1051 } else if (line != 17 + 1) {
1052 printf("DPort corrupt: %s/%s\n", bulk->s1, bulk->s2);
1053 pkg->flags |= PKGF_CORRUPT;
1055 if (dexec_close(fp, pid)) {
1056 printf("make -V* command for %s/%s failed\n",
1057 bulk->s1, bulk->s2);
1058 pkg->flags |= PKGF_CORRUPT;
1065 if (bulk->s4 && bulk->s4[0] == 'd')
1066 pkg->flags |= PKGF_DEBUGSTOP;
1069 * Mark as a dummy node, the front-end will iterate the flavors
1070 * and create sub-nodes for us.
1072 * Get rid of elements returned that are for the first flavor.
1073 * We are creating a dummy node here, not the node for the first
1076 if (flavor == NULL && pkg->flavors && pkg->flavors[0]) {
1077 pkg->flags |= PKGF_DUMMY;
1078 freestrp(&pkg->fetch_deps);
1079 freestrp(&pkg->ext_deps);
1080 freestrp(&pkg->patch_deps);
1081 freestrp(&pkg->build_deps);
1082 freestrp(&pkg->lib_deps);
1083 freestrp(&pkg->run_deps);
1084 freestrp(&pkg->pkgfile);
1088 * Only one pkg is put on the return list now. This code no
1089 * longer creates pseudo-nodes for flavors (the frontend requests
1090 * each flavor instead).
1096 * Query the package (at least to make sure it hasn't been truncated)
1097 * and mark it as PACKAGED if found.
1102 childGetBinaryDistInfo(bulk_t *bulk)
1108 const char *cav[MAXCAC];
1115 asprintf(&repopath, "%s/%s", RepositoryPath, bulk->s1);
1118 cav[cac++] = PKG_BINARY;
1119 cav[cac++] = "query";
1121 cav[cac++] = repopath;
1122 cav[cac++] = "%n-%v";
1124 fp = dexec_open(cav, cac, &pid, NULL, 1, 0);
1125 deleteme = DeleteObsoletePkgs;
1127 while ((ptr = fgetln(fp, &len)) != NULL) {
1128 if (len == 0 || ptr[len-1] != '\n')
1131 snprintf(buf, sizeof(buf), "%s%s", ptr, UsePkgSufx);
1133 pkg = pkg_find(buf);
1135 pkg->flags |= PKGF_PACKAGED;
1138 ddprintf(0, "Note: package scan, not in list, "
1139 "skipping %s\n", buf);
1142 if (dexec_close(fp, pid)) {
1143 printf("pkg query command failed for %s\n", repopath);
1146 dlog(DLOG_ALL | DLOG_STDOUT,
1147 "Deleting obsolete package %s\n", repopath);
1154 childOptimizeEnv(bulk_t *bulk)
1161 const char *cav[MAXCAC];
1165 asprintf(&portpath, "%s/%s/%s", DPortsPath, bulk->s1, bulk->s2);
1168 cav[cac++] = MAKE_BINARY;
1170 cav[cac++] = portpath;
1171 cav[cac++] = "-V_PERL5_FROM_BIN";
1173 fp = dexec_open(cav, cac, &pid, NULL, 1, 1);
1177 while ((ptr = fgetln(fp, &len)) != NULL) {
1178 if (len == 0 || ptr[len-1] != '\n') {
1179 dfatal("Bad package info for %s/%s response line %d",
1180 bulk->s1, bulk->s2, line);
1185 case 1: /* _PERL5_FROM_BIN */
1186 addbuildenv("_PERL5_FROM_BIN", ptr, BENV_ENVIRONMENT);
1189 printf("childOptimizeEnv: EXTRA LINE: %s\n", ptr);
1195 printf("DPort not found: %s/%s\n", bulk->s1, bulk->s2);
1196 } else if (line != 1 + 1) {
1197 printf("DPort corrupt: %s/%s\n", bulk->s1, bulk->s2);
1199 if (dexec_close(fp, pid)) {
1200 printf("childOptimizeEnv() failed\n");
1205 scan_and_queue_dir(const char *path, const char *level1, int level)
1214 dir = opendir(path);
1215 dassert(dir, "Cannot open dports path \"%s\"", path);
1217 while ((den = readdir(dir)) != NULL) {
1218 if (den->d_namlen == 1 && den->d_name[0] == '.')
1220 if (den->d_namlen == 2 &&
1221 den->d_name[0] == '.' && den->d_name[1] == '.')
1223 asprintf(&s1, "%s/%s", path, den->d_name);
1224 if (lstat(s1, &st) < 0 || !S_ISDIR(st.st_mode)) {
1229 count += scan_and_queue_dir(s1, den->d_name, 2);
1233 asprintf(&s2, "%s/Makefile", s1);
1234 if (lstat(s2, &st) == 0) {
1235 queuebulk(level1, den->d_name, NULL, NULL);
1247 scan_binary_repo(const char *path)
1255 dir = opendir(path);
1256 dassert(dir, "Cannot open repository path \"%s\"", path);
1259 * NOTE: Test includes the '.' in the suffix.
1261 while ((den = readdir(dir)) != NULL) {
1262 len = strlen(den->d_name);
1264 strcmp(den->d_name + len - 4, UsePkgSufx) == 0) {
1265 queuebulk(den->d_name, NULL, NULL, NULL);
1278 freestrp(&pkg->portdir);
1279 freestrp(&pkg->version);
1280 freestrp(&pkg->pkgfile);
1281 freestrp(&pkg->ignore);
1282 freestrp(&pkg->fetch_deps);
1283 freestrp(&pkg->ext_deps);
1284 freestrp(&pkg->patch_deps);
1285 freestrp(&pkg->build_deps);
1286 freestrp(&pkg->lib_deps);
1287 freestrp(&pkg->run_deps);
1288 freestrp(&pkg->pos_options);
1289 freestrp(&pkg->neg_options);
1290 freestrp(&pkg->flavors);