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 static pkg_t
*PkgHash1
[PKG_HSIZE
]; /* by portdir */
61 static 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
);
95 static __inline
const char *
96 deptype2str(int dep_type
)
100 return("FETCH_DEPENDS");
102 return("EXTRACT_DEPENDS");
104 return("PATCH_DEPENDS");
106 return("BUILD_DEPENDS");
108 return("LIB_DEPENDS");
110 return("RUN_DEPENDS");
117 pkg_enter(pkg_t
*pkg
)
123 pkgp
= &PkgHash1
[pkghash(pkg
->portdir
)];
124 while ((scan
= *pkgp
) != NULL
) {
125 if (strcmp(pkg
->portdir
, scan
->portdir
) == 0)
127 pkgp
= &scan
->hnext1
;
129 ddassert(scan
== NULL
|| (scan
->flags
& PKGF_PLACEHOLD
));
130 if (scan
&& (scan
->flags
& PKGF_PLACEHOLD
)) {
131 ddassert(scan
->idepon_list
.next
== &scan
->idepon_list
);
132 ddassert(scan
->deponi_list
.next
== &scan
->deponi_list
);
134 pkg
->hnext1
= scan
->hnext1
;
144 pkgp
= &PkgHash2
[pkghash(pkg
->pkgfile
)];
145 while ((scan
= *pkgp
) != NULL
) {
146 if (strcmp(pkg
->pkgfile
, scan
->pkgfile
) == 0)
148 pkgp
= &scan
->hnext2
;
156 pkg_find(const char *match
)
161 pkgp
= &PkgHash1
[pkghash(match
)];
162 for (pkg
= *pkgp
; pkg
; pkg
= pkg
->hnext1
) {
163 if (strcmp(pkg
->portdir
, match
) == 0)
166 pkgp
= &PkgHash2
[pkghash(match
)];
167 for (pkg
= *pkgp
; pkg
; pkg
= pkg
->hnext2
) {
168 if (strcmp(pkg
->pkgfile
, match
) == 0)
175 * Parse a specific list of ports via origin name (portdir/subdir)
178 ParsePackageList(int n
, char **ary
, int debugstop
)
187 initbulk(childGetPackageInfo
, MaxBulk
);
190 * Always include ports-mgmt/pkg. s4 is "x" meaning not a manual
191 * selection, "d" meaning DEBUGSTOP mode, or NULL.
193 queuebulk("ports-mgmt", "pkg", NULL
, "x");
195 for (i
= 0; i
< n
; ++i
) {
202 if (stat(l1
, &st
) == 0 && S_ISREG(st
.st_mode
)) {
203 total
+= parsepkglist_file(l1
, debugstop
);
207 l2
= strchr(l1
, '/');
209 printf("Bad portdir specification: %s\n", l1
);
215 l3
= strchr(l2
, '@');
220 * Silently ignore any manually specified ports-mgmt/pkg,
221 * which we already auto-added.
223 if (strcmp(l1
, "ports-mgmt") != 0 ||
224 strcmp(l2
, "pkg") != 0)
226 queuebulk(l1
, l2
, l3
, (debugstop
? "d" : NULL
));
231 printf("Processing %d ports\n", total
);
233 list
= processPackageListBulk(total
);
235 dfatal("Bad specifications, exiting");
244 parsepkglist_file(const char *path
, int debugstop
)
254 if ((fp
= fopen(path
, "r")) == NULL
) {
255 dpanic_errno("Cannot read %s\n", path
);
262 while ((base
= fgetln(fp
, &len
)) != NULL
) {
263 if (len
== 0 || base
[len
-1] != '\n')
266 l1
= strtok(base
, " \t\r\n");
268 printf("Badly formatted pkg info line: %s\n", base
);
271 l2
= strchr(l1
, '/');
273 printf("Badly formatted specification: %s\n", l1
);
277 l3
= strchr(l2
, '@');
280 queuebulk(l1
, l2
, l3
, (debugstop
? "d" : NULL
));
289 * Parse packages from the list installed on the system.
292 GetLocalPackageList(void)
305 PrepareSystemFlag
= 1;
306 initbulk(childGetPackageInfo
, MaxBulk
);
313 fp
= popen("pkg info -a -o -A", "r");
316 * Always include ports-mgmt/pkg. s4 is "x" meaning not a manual
317 * selection, "d" meaning DEBUGSTOP mode, or NULL.
319 queuebulk("ports-mgmt", "pkg", NULL
, "x");
321 while ((base
= fgetln(fp
, &len
)) != NULL
) {
322 if (len
== 0 || base
[len
-1] != '\n')
326 data
= strchr(base
, ':');
331 base
= strtok(base
, " \t\r");
332 data
= strtok(data
, " \t\r");
334 if (base
== NULL
|| data
== NULL
)
337 if (strcmp(base
, "Origin") == 0) {
339 queuebulk(l1
, l2
, NULL
, NULL
);
344 if (strchr(data
, '/') == NULL
) {
345 printf("Badly formatted origin: %s\n", l1
);
352 l2
= strchr(l1
, '/');
354 l3
= strchr(l2
, '@'); /* typically NULL */
361 * Don't queue ports-mgmt/pkg twice, we already
362 * queued it manually.
364 if (strcmp(l1
, "ports-mgmt") != 0 ||
365 strcmp(l2
, "pkg") != 0) {
370 if (state
== 1 && strcmp(base
, "flavor") == 0) {
371 queuebulk(l1
, l2
, data
, NULL
);
377 queuebulk(l1
, l2
, NULL
, NULL
);
378 /*state = 0; not needed */
387 printf("Processing %d ports\n", total
);
389 list
= processPackageListBulk(total
);
395 GetFullPackageList(void)
399 initbulk(childGetPackageInfo
, MaxBulk
);
400 total
= scan_and_queue_dir(DPortsPath
, NULL
, 1);
401 printf("Scanning %d ports\n", total
);
403 return processPackageListBulk(total
);
407 * Caller has queued the process list for bulk operation. We retrieve
408 * the results and clean up the bulk operation (we may have to do a second
409 * bulk operation so we have to be the ones to clean it up).
412 processPackageListBulk(int total
)
429 while ((bulk
= getbulk()) != NULL
) {
431 if ((count
& 255) == 0) {
433 (double)count
* 100.0 / (double)total
+ 0.001);
437 *list_tail
= bulk
->list
;
439 while ((scan
= *list_tail
) != NULL
) {
440 if (bulk
->s4
== NULL
|| bulk
->s4
[0] != 'x')
441 scan
->flags
|= PKGF_MANUALSEL
;
443 list_tail
= &scan
->bnext
;
448 printf("100.00%%\n");
449 printf("\nTotal %d\n", count
);
453 * Resolve all dependencies for the related packages, potentially
454 * adding anything that could not be found to the list. This will
455 * continue to issue bulk operations and process the result until
456 * no dependencies are left.
458 printf("Resolving dependencies...");
462 dep_list
= resolveDeps(dep_list
, &list_tail
, 0);
469 * Generate the topology
471 resolveDeps(list
, NULL
, 1);
474 * Do a final count, ignore place holders.
476 * Also set stop_fail if appropriate. Check for direct specifications
477 * which fail to probe and any direct dependencies of those
478 * specifications, but don't recurse (for now)... don't check indirect
479 * dependencies (i.e. A -> B -> C where A is directly specified, B
480 * is adirect dependency, and C fails to probe).
485 for (scan
= list
; scan
; scan
= scan
->bnext
) {
486 if ((scan
->flags
& PKGF_ERROR
) == 0) {
489 if ((scan
->flags
& PKGF_MANUALSEL
) && MaskProbeAbort
== 0) {
493 * Directly specified package failed to probe
495 if (scan
->flags
& PKGF_CORRUPT
) {
501 * Directly specified package had a direct dependency
502 * that failed to probe (don't go further).
504 PKGLIST_FOREACH(link
, &scan
->idepon_list
) {
506 (link
->pkg
->flags
& PKGF_CORRUPT
)) {
512 printf("Total Returned %d\n", count
);
515 * Check to see if any PKGF_MANUALSEL packages
518 printf("%d packages failed to probe\n", stop_fail
);
519 if (PrepareSystemFlag
) {
520 if (stop_fail
== stop_base_list
) {
522 "prepare-system: Some of your installed packages no longer exist in\n"
523 "dports, do you wish to continue rebuilding what does exist?\n");
524 if (askyn("Continue anyway? "))
528 "prepare-system: Some of your installed packages have dependencies\n"
529 "which could not be found in dports, cannot continue, aborting\n");
534 printf("continuing despite pkglist "
537 printf("unable to continue, aborting\n");
540 if (remove_corrupt
== 0)
545 * Remove corrupt packages before continuing
547 if (remove_corrupt
) {
549 while ((scan
= *list_tail
) != NULL
) {
550 if (scan
->flags
& PKGF_CORRUPT
)
551 *list_tail
= scan
->bnext
;
553 list_tail
= &scan
->bnext
;
558 * Scan our binary distributions and related dependencies looking
559 * for any packages that have already been built.
561 initbulk(childGetBinaryDistInfo
, MaxBulk
);
562 total
= scan_binary_repo(RepositoryPath
);
564 printf("Scanning %d packages\n", total
);
566 while ((bulk
= getbulk()) != NULL
) {
568 if ((count
& 255) == 0) {
570 (double)count
* 100.0 / (double)total
+ 0.001);
575 printf("100.00%%\n");
576 printf("\nTotal %d\n", count
);
580 printf("all done\n");
586 GetPkgPkg(pkg_t
**listp
)
592 for (scan
= *listp
; scan
; scan
= scan
->bnext
) {
593 if (strcmp(scan
->portdir
, "ports-mgmt/pkg") == 0)
598 * This will force pkg to be built, but generally this code
599 * is not reached because the package list processing code
600 * adds ports-mgmt/pkg unconditionally.
602 initbulk(childGetPackageInfo
, MaxBulk
);
603 queuebulk("ports-mgmt", "pkg", NULL
, "x");
605 dassert(bulk
, "Cannot find ports-mgmt/pkg");
613 * Include added packages to the total and add the initial bulk
614 * built packages to the list so they get counted.
616 for (s2
= scan
; s2
->bnext
; s2
= s2
->bnext
)
618 for (s2
= scan
; s2
->bnext
; s2
= s2
->bnext
)
628 * Try to optimize the environment by supplying information that
629 * the ports system would generally have to run stuff to get on
632 * See childOptimizeEnv() for the actual handling. We execute
633 * a single make -V... -V... for ports-mgmt/pkg from within the
634 * bulk system (which handles the environment and disables
635 * /etc/make.conf), and we then call addbuildenv() as appropriate.
645 initbulk(childOptimizeEnv
, MaxBulk
);
646 queuebulk("ports-mgmt", "pkg", NULL
, NULL
);
653 * Run through the list resolving dependencies and constructing the topology
654 * linkages. This may append packages to the list. Dependencies to dummy
655 * nodes which do not specify a flavor do not need special handling, the
656 * search code in build.c will properly follow the first flavor.
659 resolveDeps(pkg_t
*list
, pkg_t
***list_tailp
, int gentopo
)
661 pkg_t
*ret_list
= NULL
;
666 for (scan
= list
; scan
; scan
= scan
->bnext
) {
667 use
= pkg_find(scan
->portdir
);
668 resolveFlavors(use
, scan
->flavors
, gentopo
);
669 resolveDepString(use
, scan
->fetch_deps
,
670 gentopo
, DEP_TYPE_FETCH
);
671 resolveDepString(use
, scan
->ext_deps
,
672 gentopo
, DEP_TYPE_EXT
);
673 resolveDepString(use
, scan
->patch_deps
,
674 gentopo
, DEP_TYPE_PATCH
);
675 resolveDepString(use
, scan
->build_deps
,
676 gentopo
, DEP_TYPE_BUILD
);
677 resolveDepString(use
, scan
->lib_deps
,
678 gentopo
, DEP_TYPE_LIB
);
679 resolveDepString(use
, scan
->run_deps
,
680 gentopo
, DEP_TYPE_RUN
);
684 * No bulk ops are queued when doing the final topology
687 * Avoid entering duplicate results from the bulk ops. Duplicate
688 * results are mostly filtered out, but not always. A dummy node
689 * representing multiple flavors will parse-out the flavors
693 while ((bulk
= getbulk()) != NULL
) {
695 if (ret_list
== NULL
)
696 ret_list
= bulk
->list
;
697 **list_tailp
= bulk
->list
;
699 while ((scan
= **list_tailp
) != NULL
) {
701 *list_tailp
= &scan
->bnext
;
710 * Resolve a generic node that has flavors, queue to retrieve info for
711 * each flavor and setup linkages as appropriate.
714 resolveFlavors(pkg_t
*pkg
, char *flavors
, int gentopo
)
725 if ((pkg
->flags
& PKGF_DUMMY
) == 0)
727 if (pkg
->flavors
== NULL
|| pkg
->flavors
[0] == 0)
729 flavor_base
= strdup(flavors
);
730 flavor_scan
= flavor_base
;
734 flavor
= strsep(&flavor_scan
, " \t");
735 } while (flavor
&& *flavor
== 0);
740 * Iterate each flavor generating "s1/s2@flavor".
742 * queuebulk() info for each flavor, and set-up the
743 * linkages in the topology generation pass.
745 asprintf(&portdir
, "%s@%s", pkg
->portdir
, flavor
);
746 s1
= strdup(pkg
->portdir
);
747 s2
= strchr(s1
, '/');
750 dpkg
= pkg_find(portdir
);
751 if (dpkg
&& gentopo
) {
757 link
= calloc(1, sizeof(*link
));
759 link
->next
= &pkg
->idepon_list
;
760 link
->prev
= pkg
->idepon_list
.prev
;
761 link
->next
->prev
= link
;
762 link
->prev
->next
= link
;
763 link
->dep_type
= DEP_TYPE_BUILD
;
765 link
= calloc(1, sizeof(*link
));
767 link
->next
= &dpkg
->deponi_list
;
768 link
->prev
= dpkg
->deponi_list
.prev
;
769 link
->next
->prev
= link
;
770 link
->prev
->next
= link
;
771 link
->dep_type
= DEP_TYPE_BUILD
;
773 } else if (gentopo
== 0 && dpkg
== NULL
) {
775 * Use a place-holder to prevent duplicate
776 * dependencies from being processed. The placeholder
777 * will be replaced by the actual dependency.
780 dpkg
->portdir
= portdir
;
781 dpkg
->flags
= PKGF_PLACEHOLD
;
783 queuebulk(s1
, s2
, flavor
, NULL
);
791 resolveDepString(pkg_t
*pkg
, char *depstr
, int gentopo
, int dep_type
)
802 if (depstr
== NULL
|| depstr
[0] == 0)
805 copy_base
= strdup(depstr
);
807 log_component
= copy
;
811 dep
= strsep(©
, " \t");
812 } while (dep
&& *dep
== 0);
817 * Ignore dependencies prefixed with ${NONEXISTENT}
819 if (strncmp(dep
, "/nonexistent:", 13) == 0)
823 dep
= strchr(dep
, ':');
824 if (dep
== NULL
|| *dep
!= ':') {
825 printf("Error parsing %s dependency for "
826 "%s: '%s' at index %zd '%s' "
827 "(looking for ':')\n",
828 deptype2str(dep_type
),
829 pkg
->portdir
, depstr
,
830 log_component
- copy_base
,
837 * Strip-off any DPortsPath prefix. EXTRACT_DEPENDS
838 * often (always?) generates this prefix.
840 if (strncmp(dep
, DPortsPath
, strlen(DPortsPath
)) == 0) {
841 dep
+= strlen(DPortsPath
);
847 * Strip-off any tag (such as :patch). We don't try to
848 * organize dependencies at this fine a grain (for now).
850 tag
= strchr(dep
, ':');
856 * Locate the dependency
858 if ((dpkg
= pkg_find(dep
)) != NULL
) {
863 * NOTE: idep_count is calculated recursively
866 ddprintf(0, "Add Dependency %s -> %s\n",
867 pkg
->portdir
, dpkg
->portdir
);
868 link
= calloc(1, sizeof(*link
));
870 link
->next
= &pkg
->idepon_list
;
871 link
->prev
= pkg
->idepon_list
.prev
;
872 link
->next
->prev
= link
;
873 link
->prev
->next
= link
;
874 link
->dep_type
= dep_type
;
876 link
= calloc(1, sizeof(*link
));
878 link
->next
= &dpkg
->deponi_list
;
879 link
->prev
= dpkg
->deponi_list
.prev
;
880 link
->next
->prev
= link
;
881 link
->prev
->next
= link
;
882 link
->dep_type
= dep_type
;
889 * This shouldn't happen because we already took a first
890 * pass and should have generated the pkgs.
893 printf("Topology Generate failed for %s: %s\n",
894 pkg
->portdir
, copy_base
);
899 * Separate out the two dports directory components and
900 * extract the optional '@flavor' specification.
902 sep
= strchr(dep
, '/');
904 printf("Error parsing %s dependency for "
905 "%s: '%s' at index %zd '%s' "
906 "(looking for '/')\n",
907 deptype2str(dep_type
),
908 pkg
->portdir
, depstr
,
909 log_component
- copy_base
,
916 * The flavor hangs off the separator, not the tag
918 flavor
= strrchr(sep
, '@');
921 flavor
= strrchr(tag
, '@');
923 flavor
= strrchr(sep
, '@');
929 ddprintf(0, "QUEUE DEPENDENCY FROM PKG %s: %s/%s@%s\n",
930 pkg
->portdir
, dep
, sep
, flavor
);
932 ddprintf(0, "QUEUE DEPENDENCY FROM PKG %s: %s/%s\n",
933 pkg
->portdir
, dep
, sep
);
936 * Use a place-holder to prevent duplicate dependencies from
937 * being processed. The placeholder will be replaced by
938 * the actual dependency.
942 asprintf(&dpkg
->portdir
, "%s/%s@%s", dep
, sep
, flavor
);
944 asprintf(&dpkg
->portdir
, "%s/%s", dep
, sep
);
945 dpkg
->flags
= PKGF_PLACEHOLD
;
948 queuebulk(dep
, sep
, flavor
, NULL
);
954 FreePackageList(pkg_t
*pkgs __unused
)
956 dfatal("not implemented");
960 * Scan some or all dports to allocate the related pkg structure. Dependencies
961 * are stored but not processed.
966 childGetPackageInfo(bulk_t
*bulk
)
977 const char *cav
[MAXCAC
];
982 * If the package has flavors we will loop on each one. If a flavor
983 * is not passed in s3 we will loop on all flavors, otherwise we will
984 * only process the passed-in flavor.
986 flavor
= bulk
->s3
; /* usually NULL */
990 asprintf(&portpath
, "%s/%s/%s", DPortsPath
, bulk
->s1
, bulk
->s2
);
992 asprintf(&flavarg
, "FLAVOR=%s", flavor
);
997 cav
[cac
++] = MAKE_BINARY
;
999 cav
[cac
++] = portpath
;
1001 cav
[cac
++] = flavarg
;
1004 * Prevent postgresql, mysql, and other package Makefile tests
1005 * from accessing the host system's /usr/local by setting LOCALBASE
1006 * to an empty directory.
1008 asprintf(&localbase
, "LOCALBASE=%s/empty", BuildBase
);
1009 cav
[cac
++] = localbase
;
1012 * Variables we need to retrieve (order is specific to the switch
1015 cav
[cac
++] = "-VPKGVERSION";
1016 cav
[cac
++] = "-VPKGFILE:T";
1017 cav
[cac
++] = "-VALLFILES";
1018 cav
[cac
++] = "-VDIST_SUBDIR";
1019 cav
[cac
++] = "-VMAKE_JOBS_NUMBER";
1020 cav
[cac
++] = "-VIGNORE";
1021 cav
[cac
++] = "-VFETCH_DEPENDS";
1022 cav
[cac
++] = "-VEXTRACT_DEPENDS";
1023 cav
[cac
++] = "-VPATCH_DEPENDS";
1024 cav
[cac
++] = "-VBUILD_DEPENDS";
1025 cav
[cac
++] = "-VLIB_DEPENDS";
1026 cav
[cac
++] = "-VRUN_DEPENDS";
1027 cav
[cac
++] = "-VSELECTED_OPTIONS";
1028 cav
[cac
++] = "-VDESELECTED_OPTIONS";
1029 cav
[cac
++] = "-VUSE_LINUX";
1030 cav
[cac
++] = "-VFLAVORS";
1031 cav
[cac
++] = "-VUSES";
1033 fp
= dexec_open(portpath
+ strlen(DPortsPath
) + 1, cav
, cac
,
1036 freestrp(&localbase
);
1040 asprintf(&pkg
->portdir
, "%s/%s@%s", bulk
->s1
, bulk
->s2
, flavor
);
1042 asprintf(&pkg
->portdir
, "%s/%s", bulk
->s1
, bulk
->s2
);
1045 while ((ptr
= fgetln(fp
, &len
)) != NULL
) {
1046 if (len
== 0 || ptr
[len
-1] != '\n') {
1047 dfatal("Bad package info for %s/%s response line %d",
1048 bulk
->s1
, bulk
->s2
, line
);
1053 case 1: /* PKGVERSION */
1054 asprintf(&pkg
->version
, "%s", ptr
);
1056 case 2: /* PKGFILE */
1057 asprintf(&pkg
->pkgfile
, "%s", ptr
);
1059 case 3: /* ALLFILES (aka DISTFILES + patch files) */
1060 asprintf(&pkg
->distfiles
, "%s", ptr
);
1062 case 4: /* DIST_SUBDIR */
1063 pkg
->distsubdir
= strdup_or_null(ptr
);
1065 case 5: /* MAKE_JOBS_NUMBER */
1066 pkg
->make_jobs_number
= strtol(ptr
, NULL
, 0);
1068 case 6: /* IGNORE */
1069 pkg
->ignore
= strdup_or_null(ptr
);
1071 case 7: /* FETCH_DEPENDS */
1072 pkg
->fetch_deps
= strdup_or_null(ptr
);
1074 case 8: /* EXTRACT_DEPENDS */
1075 pkg
->ext_deps
= strdup_or_null(ptr
);
1077 case 9: /* PATCH_DEPENDS */
1078 pkg
->patch_deps
= strdup_or_null(ptr
);
1080 case 10: /* BUILD_DEPENDS */
1081 pkg
->build_deps
= strdup_or_null(ptr
);
1083 case 11: /* LIB_DEPENDS */
1084 pkg
->lib_deps
= strdup_or_null(ptr
);
1086 case 12: /* RUN_DEPENDS */
1087 pkg
->run_deps
= strdup_or_null(ptr
);
1089 case 13: /* SELECTED_OPTIONS */
1090 pkg
->pos_options
= strdup_or_null(ptr
);
1092 case 14: /* DESELECTED_OPTIONS */
1093 pkg
->neg_options
= strdup_or_null(ptr
);
1095 case 15: /* USE_LINUX */
1099 case 16: /* FLAVORS */
1100 asprintf(&pkg
->flavors
, "%s", ptr
);
1103 asprintf(&pkg
->uses
, "%s", ptr
);
1104 if (strstr(pkg
->uses
, "metaport"))
1105 pkg
->flags
|= PKGF_META
;
1108 printf("EXTRA LINE: %s\n", ptr
);
1114 printf("DPort not found: %s/%s\n", bulk
->s1
, bulk
->s2
);
1115 pkg
->flags
|= PKGF_NOTFOUND
;
1116 } else if (line
!= 17 + 1) {
1117 printf("DPort corrupt: %s/%s\n", bulk
->s1
, bulk
->s2
);
1118 pkg
->flags
|= PKGF_CORRUPT
;
1120 if (dexec_close(fp
, pid
)) {
1121 printf("make -V* command for %s/%s failed\n",
1122 bulk
->s1
, bulk
->s2
);
1123 pkg
->flags
|= PKGF_CORRUPT
;
1130 if (bulk
->s4
&& bulk
->s4
[0] == 'd')
1131 pkg
->flags
|= PKGF_DEBUGSTOP
;
1134 * Mark as a dummy node, the front-end will iterate the flavors
1135 * and create sub-nodes for us.
1137 * Get rid of elements returned that are for the first flavor.
1138 * We are creating a dummy node here, not the node for the first
1141 if (flavor
== NULL
&& pkg
->flavors
&& pkg
->flavors
[0]) {
1142 pkg
->flags
|= PKGF_DUMMY
;
1143 freestrp(&pkg
->fetch_deps
);
1144 freestrp(&pkg
->ext_deps
);
1145 freestrp(&pkg
->patch_deps
);
1146 freestrp(&pkg
->build_deps
);
1147 freestrp(&pkg
->lib_deps
);
1148 freestrp(&pkg
->run_deps
);
1149 freestrp(&pkg
->pkgfile
);
1153 * Checksum the port directory tree. This just rollsup crcs of the
1154 * path names and a few stat fields (mtime, size) in order to detect
1155 * if any modification has been made to the port.
1157 pkg
->crc32
= crcDirTree(portpath
);
1160 * Only one pkg is put on the return list now. This code no
1161 * longer creates pseudo-nodes for flavors (the frontend requests
1162 * each flavor instead).
1169 * Query the package (at least to make sure it hasn't been truncated)
1170 * and mark it as PACKAGED if found.
1172 * This is a pre-req prior to doing builds, so we cannot assume that
1173 * the template has its pkg-static binary yet.
1178 childGetBinaryDistInfo(bulk_t
*bulk
)
1184 const char *cav
[MAXCAC
];
1191 asprintf(&repopath
, "%s/%s", RepositoryPath
, bulk
->s1
);
1194 cav
[cac
++] = PKG_BINARY
;
1195 cav
[cac
++] = "query";
1197 cav
[cac
++] = repopath
;
1198 cav
[cac
++] = "%n-%v";
1200 fp
= dexec_open(NULL
, cav
, cac
, &pid
, NULL
, 1, 0);
1201 deleteme
= DeleteObsoletePkgs
;
1203 while ((ptr
= fgetln(fp
, &len
)) != NULL
) {
1204 if (len
== 0 || ptr
[len
-1] != '\n')
1209 * As of pkg 1.17 the binary dist files use a .pkg suffix
1210 * regardless of the compression format, so always check
1213 snprintf(buf
, sizeof(buf
), "%s%s", ptr
, ".pkg");
1214 pkg
= pkg_find(buf
);
1216 snprintf(buf
, sizeof(buf
), "%s%s", ptr
, UsePkgSufx
);
1217 pkg
= pkg_find(buf
);
1221 ddprintf(0, "Note: Package is already packaged, ignore for -f: %s\n", ptr
);
1224 pkg
->flags
|= PKGF_PACKAGED
;
1228 ddprintf(0, "Note: package scan, not in list, "
1229 "skipping %s{.%s,.pkg}\n", ptr
, UsePkgSufx
);
1232 if (dexec_close(fp
, pid
)) {
1233 printf("pkg query command failed for %s\n", repopath
);
1236 dlog(DLOG_ALL
| DLOG_STDOUT
,
1237 "Deleting obsolete package %s\n", repopath
);
1244 childOptimizeEnv(bulk_t
*bulk
)
1252 const char *cav
[MAXCAC
];
1256 asprintf(&portpath
, "%s/%s/%s", DPortsPath
, bulk
->s1
, bulk
->s2
);
1259 * Prevent postgresql, mysql, and other package Makefile tests
1260 * from accessing the host system's /usr/local by setting LOCALBASE
1261 * to an empty directory.
1263 asprintf(&localbase
, "LOCALBASE=%s/empty", BuildBase
);
1266 cav
[cac
++] = MAKE_BINARY
;
1268 cav
[cac
++] = portpath
;
1269 cav
[cac
++] = localbase
;
1270 cav
[cac
++] = "-V_PERL5_FROM_BIN";
1272 fp
= dexec_open(portpath
+ strlen(DPortsPath
) + 1, cav
, cac
,
1278 while ((ptr
= fgetln(fp
, &len
)) != NULL
) {
1279 if (len
== 0 || ptr
[len
-1] != '\n') {
1280 dfatal("Bad package info for %s/%s response line %d",
1281 bulk
->s1
, bulk
->s2
, line
);
1286 case 1: /* _PERL5_FROM_BIN */
1287 addbuildenv("_PERL5_FROM_BIN", ptr
, BENV_ENVIRONMENT
);
1290 printf("childOptimizeEnv: EXTRA LINE: %s\n", ptr
);
1296 printf("DPort not found: %s/%s\n", bulk
->s1
, bulk
->s2
);
1297 } else if (line
!= 1 + 1) {
1298 printf("DPort corrupt: %s/%s\n", bulk
->s1
, bulk
->s2
);
1300 if (dexec_close(fp
, pid
)) {
1301 printf("childOptimizeEnv() failed\n");
1306 scan_and_queue_dir(const char *path
, const char *level1
, int level
)
1315 dir
= opendir(path
);
1316 dassert(dir
, "Cannot open dports path \"%s\"", path
);
1318 while ((den
= readdir(dir
)) != NULL
) {
1319 if (den
->d_namlen
== 1 && den
->d_name
[0] == '.')
1321 if (den
->d_namlen
== 2 &&
1322 den
->d_name
[0] == '.' && den
->d_name
[1] == '.')
1324 asprintf(&s1
, "%s/%s", path
, den
->d_name
);
1325 if (lstat(s1
, &st
) < 0 || !S_ISDIR(st
.st_mode
)) {
1330 count
+= scan_and_queue_dir(s1
, den
->d_name
, 2);
1334 asprintf(&s2
, "%s/Makefile", s1
);
1335 if (lstat(s2
, &st
) == 0) {
1336 queuebulk(level1
, den
->d_name
, NULL
, NULL
);
1348 scan_binary_repo(const char *path
)
1355 dir
= opendir(path
);
1356 dassert(dir
, "Cannot open repository path \"%s\"", path
);
1359 * NOTE: Test includes the '.' in the suffix.
1361 while ((den
= readdir(dir
)) != NULL
) {
1364 suffix
= strrchr(den
->d_name
, '.');
1365 if (suffix
&& suffix
!= den
->d_name
&&
1366 strcmp(suffix
, UsePkgSufx
) == 0)
1368 queuebulk(den
->d_name
, NULL
, NULL
, NULL
);
1373 * As of 1.17, pkg generates .pkg files.
1375 if (suffix
&& suffix
!= den
->d_name
&&
1376 strcmp(suffix
, ".pkg") == 0)
1378 queuebulk(den
->d_name
, NULL
, NULL
, NULL
);
1391 freestrp(&pkg
->portdir
);
1392 freestrp(&pkg
->version
);
1393 freestrp(&pkg
->pkgfile
);
1394 freestrp(&pkg
->ignore
);
1395 freestrp(&pkg
->fetch_deps
);
1396 freestrp(&pkg
->ext_deps
);
1397 freestrp(&pkg
->patch_deps
);
1398 freestrp(&pkg
->build_deps
);
1399 freestrp(&pkg
->lib_deps
);
1400 freestrp(&pkg
->run_deps
);
1401 freestrp(&pkg
->pos_options
);
1402 freestrp(&pkg
->neg_options
);
1403 freestrp(&pkg
->flavors
);