xref: /dflybsd-src/usr.bin/dsynth/pkglist.c (revision 2c5f241e87010055dd25089bf9d737b2502b25ff)
18e25f19bSMatthew Dillon /*
28e25f19bSMatthew Dillon  * Copyright (c) 2019 The DragonFly Project.  All rights reserved.
38e25f19bSMatthew Dillon  *
48e25f19bSMatthew Dillon  * This code is derived from software contributed to The DragonFly Project
58e25f19bSMatthew Dillon  * by Matthew Dillon <dillon@backplane.com>
68e25f19bSMatthew Dillon  *
78e25f19bSMatthew Dillon  * This code uses concepts and configuration based on 'synth', by
88e25f19bSMatthew Dillon  * John R. Marino <draco@marino.st>, which was written in ada.
98e25f19bSMatthew Dillon  *
108e25f19bSMatthew Dillon  * Redistribution and use in source and binary forms, with or without
118e25f19bSMatthew Dillon  * modification, are permitted provided that the following conditions
128e25f19bSMatthew Dillon  * are met:
138e25f19bSMatthew Dillon  *
148e25f19bSMatthew Dillon  * 1. Redistributions of source code must retain the above copyright
158e25f19bSMatthew Dillon  *    notice, this list of conditions and the following disclaimer.
168e25f19bSMatthew Dillon  * 2. Redistributions in binary form must reproduce the above copyright
178e25f19bSMatthew Dillon  *    notice, this list of conditions and the following disclaimer in
188e25f19bSMatthew Dillon  *    the documentation and/or other materials provided with the
198e25f19bSMatthew Dillon  *    distribution.
208e25f19bSMatthew Dillon  * 3. Neither the name of The DragonFly Project nor the names of its
218e25f19bSMatthew Dillon  *    contributors may be used to endorse or promote products derived
228e25f19bSMatthew Dillon  *    from this software without specific, prior written permission.
238e25f19bSMatthew Dillon  *
248e25f19bSMatthew Dillon  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
258e25f19bSMatthew Dillon  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
268e25f19bSMatthew Dillon  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
278e25f19bSMatthew Dillon  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
288e25f19bSMatthew Dillon  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
298e25f19bSMatthew Dillon  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
308e25f19bSMatthew Dillon  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
318e25f19bSMatthew Dillon  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
328e25f19bSMatthew Dillon  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
338e25f19bSMatthew Dillon  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
348e25f19bSMatthew Dillon  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
358e25f19bSMatthew Dillon  * SUCH DAMAGE.
368e25f19bSMatthew Dillon  */
378e25f19bSMatthew Dillon 
388e25f19bSMatthew Dillon #include "dsynth.h"
398e25f19bSMatthew Dillon 
408e25f19bSMatthew Dillon #define PKG_HSIZE	32768
418e25f19bSMatthew Dillon #define PKG_HMASK	32767
428e25f19bSMatthew Dillon 
43710838f7SMatthew Dillon static int parsepkglist_file(const char *path, int debugstop);
448e25f19bSMatthew Dillon static void childGetPackageInfo(bulk_t *bulk);
458e25f19bSMatthew Dillon static void childGetBinaryDistInfo(bulk_t *bulk);
46a67bf8dbSMatthew Dillon static void childOptimizeEnv(bulk_t *bulk);
478e25f19bSMatthew Dillon static pkg_t *resolveDeps(pkg_t *dep_list, pkg_t ***list_tailp, int gentopo);
4877ac77e7SMatthew Dillon static void resolveFlavors(pkg_t *pkg, char *flavors, int gentopo);
4963fcce5bSMatthew Dillon static void resolveDepString(pkg_t *pkg, char *depstr,
5063fcce5bSMatthew Dillon 			int gentopo, int dep_type);
518e25f19bSMatthew Dillon static pkg_t *processPackageListBulk(int total);
528e25f19bSMatthew Dillon static int scan_and_queue_dir(const char *path, const char *level1, int level);
538e25f19bSMatthew Dillon static int scan_binary_repo(const char *path);
548e25f19bSMatthew Dillon #if 0
558e25f19bSMatthew Dillon static void pkgfree(pkg_t *pkg);
568e25f19bSMatthew Dillon #endif
578e25f19bSMatthew Dillon 
58eea2aa9aSMatthew Dillon static int PrepareSystemFlag;
59eea2aa9aSMatthew Dillon 
60d50f9ae3SSascha Wildner static pkg_t *PkgHash1[PKG_HSIZE];	/* by portdir */
61d50f9ae3SSascha Wildner static pkg_t *PkgHash2[PKG_HSIZE];	/* by pkgfile */
628e25f19bSMatthew Dillon 
638e25f19bSMatthew Dillon /*
648e25f19bSMatthew Dillon  * Allocate a new pkg structure plus basic initialization.
658e25f19bSMatthew Dillon  */
668e25f19bSMatthew Dillon static __inline pkg_t *
allocpkg(void)678e25f19bSMatthew Dillon allocpkg(void)
688e25f19bSMatthew Dillon {
698e25f19bSMatthew Dillon 	pkg_t *pkg;
708e25f19bSMatthew Dillon 
718e25f19bSMatthew Dillon 	pkg = calloc(1, sizeof(*pkg));
728e25f19bSMatthew Dillon 	pkg->idepon_list.next = &pkg->idepon_list;
738e25f19bSMatthew Dillon 	pkg->idepon_list.prev = &pkg->idepon_list;
748e25f19bSMatthew Dillon 	pkg->deponi_list.next = &pkg->deponi_list;
758e25f19bSMatthew Dillon 	pkg->deponi_list.prev = &pkg->deponi_list;
768e25f19bSMatthew Dillon 
778e25f19bSMatthew Dillon 	return pkg;
788e25f19bSMatthew Dillon }
798e25f19bSMatthew Dillon 
808e25f19bSMatthew Dillon /*
818e25f19bSMatthew Dillon  * Simple hash for lookups
828e25f19bSMatthew Dillon  */
838e25f19bSMatthew Dillon static __inline int
pkghash(const char * str)848e25f19bSMatthew Dillon pkghash(const char *str)
858e25f19bSMatthew Dillon {
868e25f19bSMatthew Dillon 	int hv = 0xABC32923;
878e25f19bSMatthew Dillon 	while (*str) {
888e25f19bSMatthew Dillon 		hv = (hv << 5) ^ *str;
898e25f19bSMatthew Dillon 		++str;
908e25f19bSMatthew Dillon 	}
918e25f19bSMatthew Dillon 	hv = hv ^ (hv / PKG_HSIZE) ^ (hv / PKG_HSIZE / PKG_HSIZE);
928e25f19bSMatthew Dillon 	return (hv & PKG_HMASK);
938e25f19bSMatthew Dillon }
948e25f19bSMatthew Dillon 
9593fe0327SMatthew Dillon static __inline const char *
deptype2str(int dep_type)9693fe0327SMatthew Dillon deptype2str(int dep_type)
9793fe0327SMatthew Dillon {
9893fe0327SMatthew Dillon     switch (dep_type) {
9993fe0327SMatthew Dillon     case DEP_TYPE_FETCH:
10093fe0327SMatthew Dillon 	return("FETCH_DEPENDS");
10193fe0327SMatthew Dillon     case DEP_TYPE_EXT:
10293fe0327SMatthew Dillon 	return("EXTRACT_DEPENDS");
10393fe0327SMatthew Dillon     case DEP_TYPE_PATCH:
10493fe0327SMatthew Dillon 	return("PATCH_DEPENDS");
10593fe0327SMatthew Dillon     case DEP_TYPE_BUILD:
10693fe0327SMatthew Dillon 	return("BUILD_DEPENDS");
10793fe0327SMatthew Dillon     case DEP_TYPE_LIB:
10893fe0327SMatthew Dillon 	return("LIB_DEPENDS");
10993fe0327SMatthew Dillon     case DEP_TYPE_RUN:
11093fe0327SMatthew Dillon 	return("RUN_DEPENDS");
11193fe0327SMatthew Dillon     default:
112bc91b54aSAlexandr Savca (chinarulezzz) 	return("UNKNOWN");
11393fe0327SMatthew Dillon     }
11493fe0327SMatthew Dillon }
11593fe0327SMatthew Dillon 
1168e25f19bSMatthew Dillon static void
pkg_enter(pkg_t * pkg)1178e25f19bSMatthew Dillon pkg_enter(pkg_t *pkg)
1188e25f19bSMatthew Dillon {
1198e25f19bSMatthew Dillon 	pkg_t **pkgp;
1208e25f19bSMatthew Dillon 	pkg_t *scan;
1218e25f19bSMatthew Dillon 
1228e25f19bSMatthew Dillon 	if (pkg->portdir) {
1238e25f19bSMatthew Dillon 		pkgp = &PkgHash1[pkghash(pkg->portdir)];
1248e25f19bSMatthew Dillon 		while ((scan = *pkgp) != NULL) {
1258e25f19bSMatthew Dillon 			if (strcmp(pkg->portdir, scan->portdir) == 0)
1268e25f19bSMatthew Dillon 				break;
1278e25f19bSMatthew Dillon 			pkgp = &scan->hnext1;
1288e25f19bSMatthew Dillon 		}
12977ac77e7SMatthew Dillon 		ddassert(scan == NULL || (scan->flags & PKGF_PLACEHOLD));
1308e25f19bSMatthew Dillon 		if (scan && (scan->flags & PKGF_PLACEHOLD)) {
13177ac77e7SMatthew Dillon 			ddassert(scan->idepon_list.next == &scan->idepon_list);
13277ac77e7SMatthew Dillon 			ddassert(scan->deponi_list.next == &scan->deponi_list);
1338e25f19bSMatthew Dillon 			*pkgp = pkg;
1348e25f19bSMatthew Dillon 			pkg->hnext1 = scan->hnext1;
1358e25f19bSMatthew Dillon 			free(scan->portdir);
1368e25f19bSMatthew Dillon 			free(scan);
1378e25f19bSMatthew Dillon 			scan = NULL;
1388e25f19bSMatthew Dillon 		}
1398e25f19bSMatthew Dillon 		if (scan == NULL)
1408e25f19bSMatthew Dillon 			*pkgp = pkg;
1418e25f19bSMatthew Dillon 	}
1428e25f19bSMatthew Dillon 
1438e25f19bSMatthew Dillon 	if (pkg->pkgfile) {
1448e25f19bSMatthew Dillon 		pkgp = &PkgHash2[pkghash(pkg->pkgfile)];
1458e25f19bSMatthew Dillon 		while ((scan = *pkgp) != NULL) {
1468e25f19bSMatthew Dillon 			if (strcmp(pkg->pkgfile, scan->pkgfile) == 0)
1478e25f19bSMatthew Dillon 				break;
1488e25f19bSMatthew Dillon 			pkgp = &scan->hnext2;
1498e25f19bSMatthew Dillon 		}
1508e25f19bSMatthew Dillon 		if (scan == NULL)
1518e25f19bSMatthew Dillon 			*pkgp = pkg;
1528e25f19bSMatthew Dillon 	}
1538e25f19bSMatthew Dillon }
1548e25f19bSMatthew Dillon 
1558e25f19bSMatthew Dillon static pkg_t *
pkg_find(const char * match)1568e25f19bSMatthew Dillon pkg_find(const char *match)
1578e25f19bSMatthew Dillon {
1588e25f19bSMatthew Dillon 	pkg_t **pkgp;
1598e25f19bSMatthew Dillon 	pkg_t *pkg;
1608e25f19bSMatthew Dillon 
1618e25f19bSMatthew Dillon 	pkgp = &PkgHash1[pkghash(match)];
1628e25f19bSMatthew Dillon 	for (pkg = *pkgp; pkg; pkg = pkg->hnext1) {
1638e25f19bSMatthew Dillon 		if (strcmp(pkg->portdir, match) == 0)
1648e25f19bSMatthew Dillon 			return pkg;
1658e25f19bSMatthew Dillon 	}
1668e25f19bSMatthew Dillon 	pkgp = &PkgHash2[pkghash(match)];
1678e25f19bSMatthew Dillon 	for (pkg = *pkgp; pkg; pkg = pkg->hnext2) {
1688e25f19bSMatthew Dillon 		if (strcmp(pkg->pkgfile, match) == 0)
1698e25f19bSMatthew Dillon 			return pkg;
1708e25f19bSMatthew Dillon 	}
1718e25f19bSMatthew Dillon 	return NULL;
1728e25f19bSMatthew Dillon }
1738e25f19bSMatthew Dillon 
1748e25f19bSMatthew Dillon /*
1758e25f19bSMatthew Dillon  * Parse a specific list of ports via origin name (portdir/subdir)
1768e25f19bSMatthew Dillon  */
1778e25f19bSMatthew Dillon pkg_t *
ParsePackageList(int n,char ** ary,int debugstop)178710838f7SMatthew Dillon ParsePackageList(int n, char **ary, int debugstop)
1798e25f19bSMatthew Dillon {
1808e25f19bSMatthew Dillon 	pkg_t *list;
1818e25f19bSMatthew Dillon 	int total;
182310ce99fSMatthew Dillon 	int fail;
183310ce99fSMatthew Dillon 	int i;
1848e25f19bSMatthew Dillon 
1858e25f19bSMatthew Dillon 	total = 0;
186310ce99fSMatthew Dillon 	fail = 0;
1878e25f19bSMatthew Dillon 	initbulk(childGetPackageInfo, MaxBulk);
1888e25f19bSMatthew Dillon 
189f4094b20SMatthew Dillon 	/*
190710838f7SMatthew Dillon 	 * Always include ports-mgmt/pkg.  s4 is "x" meaning not a manual
191710838f7SMatthew Dillon 	 * selection, "d" meaning DEBUGSTOP mode, or NULL.
192f4094b20SMatthew Dillon 	 */
193f4094b20SMatthew Dillon 	queuebulk("ports-mgmt", "pkg", NULL, "x");
194f4094b20SMatthew Dillon 
1958e25f19bSMatthew Dillon 	for (i = 0; i < n; ++i) {
1968e25f19bSMatthew Dillon 		char *l1;
1978e25f19bSMatthew Dillon 		char *l2;
19853c9b6f3SMatthew Dillon 		char *l3;
19953c9b6f3SMatthew Dillon 		struct stat st;
2008e25f19bSMatthew Dillon 
2018e25f19bSMatthew Dillon 		l1 = strdup(ary[i]);
20253c9b6f3SMatthew Dillon 		if (stat(l1, &st) == 0 && S_ISREG(st.st_mode)) {
203710838f7SMatthew Dillon 			total += parsepkglist_file(l1, debugstop);
20453c9b6f3SMatthew Dillon 			continue;
2058e25f19bSMatthew Dillon 		}
20653c9b6f3SMatthew Dillon 
20753c9b6f3SMatthew Dillon 		l2 = strchr(l1, '/');
20853c9b6f3SMatthew Dillon 		if (l2 == NULL) {
20953c9b6f3SMatthew Dillon 			printf("Bad portdir specification: %s\n", l1);
21053c9b6f3SMatthew Dillon 			free(l1);
211310ce99fSMatthew Dillon 			fail = 1;
21253c9b6f3SMatthew Dillon 			continue;
21353c9b6f3SMatthew Dillon 		}
21453c9b6f3SMatthew Dillon 		*l2++ = 0;
21553c9b6f3SMatthew Dillon 		l3 = strchr(l2, '@');
21653c9b6f3SMatthew Dillon 		if (l3)
21753c9b6f3SMatthew Dillon 			*l3++ = 0;
218416608a0SMatthew Dillon 
219416608a0SMatthew Dillon 		/*
220416608a0SMatthew Dillon 		 * Silently ignore any manually specified ports-mgmt/pkg,
221416608a0SMatthew Dillon 		 * which we already auto-added.
222416608a0SMatthew Dillon 		 */
223416608a0SMatthew Dillon 		if (strcmp(l1, "ports-mgmt") != 0 ||
224416608a0SMatthew Dillon 		    strcmp(l2, "pkg") != 0)
225416608a0SMatthew Dillon 		{
226710838f7SMatthew Dillon 			queuebulk(l1, l2, l3, (debugstop ? "d" : NULL));
227416608a0SMatthew Dillon 		}
22853c9b6f3SMatthew Dillon 		++total;
2298e25f19bSMatthew Dillon 		free(l1);
2308e25f19bSMatthew Dillon 	}
2318e25f19bSMatthew Dillon 	printf("Processing %d ports\n", total);
2328e25f19bSMatthew Dillon 
2338e25f19bSMatthew Dillon 	list = processPackageListBulk(total);
234310ce99fSMatthew Dillon 	if (fail) {
235310ce99fSMatthew Dillon 		dfatal("Bad specifications, exiting");
236310ce99fSMatthew Dillon 		exit(1);
237310ce99fSMatthew Dillon 	}
2388e25f19bSMatthew Dillon 
2398e25f19bSMatthew Dillon 	return list;
2408e25f19bSMatthew Dillon }
2418e25f19bSMatthew Dillon 
24253c9b6f3SMatthew Dillon static
24353c9b6f3SMatthew Dillon int
parsepkglist_file(const char * path,int debugstop)244710838f7SMatthew Dillon parsepkglist_file(const char *path, int debugstop)
24553c9b6f3SMatthew Dillon {
24653c9b6f3SMatthew Dillon 	FILE *fp;
24753c9b6f3SMatthew Dillon 	char *base;
24853c9b6f3SMatthew Dillon 	char *l1;
24953c9b6f3SMatthew Dillon 	char *l2;
25053c9b6f3SMatthew Dillon 	char *l3;
25153c9b6f3SMatthew Dillon 	size_t len;
25253c9b6f3SMatthew Dillon 	int total;
25353c9b6f3SMatthew Dillon 
25453c9b6f3SMatthew Dillon 	if ((fp = fopen(path, "r")) == NULL) {
25553c9b6f3SMatthew Dillon 		dpanic_errno("Cannot read %s\n", path);
25653c9b6f3SMatthew Dillon 		/* NOT REACHED */
25753c9b6f3SMatthew Dillon 		return 0;
25853c9b6f3SMatthew Dillon 	}
25953c9b6f3SMatthew Dillon 
26053c9b6f3SMatthew Dillon 	total = 0;
26153c9b6f3SMatthew Dillon 
26253c9b6f3SMatthew Dillon 	while ((base = fgetln(fp, &len)) != NULL) {
26353c9b6f3SMatthew Dillon 		if (len == 0 || base[len-1] != '\n')
26453c9b6f3SMatthew Dillon 			continue;
26553c9b6f3SMatthew Dillon 		base[--len] = 0;
26653c9b6f3SMatthew Dillon 		l1 = strtok(base, " \t\r\n");
26753c9b6f3SMatthew Dillon 		if (l1 == NULL) {
26853c9b6f3SMatthew Dillon 			printf("Badly formatted pkg info line: %s\n", base);
26953c9b6f3SMatthew Dillon 			continue;
27053c9b6f3SMatthew Dillon 		}
27153c9b6f3SMatthew Dillon 		l2 = strchr(l1, '/');
27253c9b6f3SMatthew Dillon 		if (l2 == NULL) {
27353c9b6f3SMatthew Dillon 			printf("Badly formatted specification: %s\n", l1);
27453c9b6f3SMatthew Dillon 			continue;
27553c9b6f3SMatthew Dillon 		}
27653c9b6f3SMatthew Dillon 		*l2++ = 0;
27753c9b6f3SMatthew Dillon 		l3 = strchr(l2, '@');
27853c9b6f3SMatthew Dillon 		if (l3)
27953c9b6f3SMatthew Dillon 			*l3++ = 0;
280710838f7SMatthew Dillon 		queuebulk(l1, l2, l3, (debugstop ? "d" : NULL));
28153c9b6f3SMatthew Dillon 		++total;
28253c9b6f3SMatthew Dillon 	}
28353c9b6f3SMatthew Dillon 	fclose(fp);
28453c9b6f3SMatthew Dillon 
28553c9b6f3SMatthew Dillon 	return total;
28653c9b6f3SMatthew Dillon }
28753c9b6f3SMatthew Dillon 
2888e25f19bSMatthew Dillon /*
2898e25f19bSMatthew Dillon  * Parse packages from the list installed on the system.
2908e25f19bSMatthew Dillon  */
2918e25f19bSMatthew Dillon pkg_t *
GetLocalPackageList(void)2928e25f19bSMatthew Dillon GetLocalPackageList(void)
2938e25f19bSMatthew Dillon {
2948e25f19bSMatthew Dillon 	pkg_t *list;
2958e25f19bSMatthew Dillon 	FILE *fp;
2968e25f19bSMatthew Dillon 	char *base;
297eea2aa9aSMatthew Dillon 	char *data;
2988e25f19bSMatthew Dillon 	char *l1;
2998e25f19bSMatthew Dillon 	char *l2;
30053c9b6f3SMatthew Dillon 	char *l3;
3018e25f19bSMatthew Dillon 	int total;
302eea2aa9aSMatthew Dillon 	int state;
3038e25f19bSMatthew Dillon 	size_t len;
3048e25f19bSMatthew Dillon 
305eea2aa9aSMatthew Dillon 	PrepareSystemFlag = 1;
3068e25f19bSMatthew Dillon 	initbulk(childGetPackageInfo, MaxBulk);
3078e25f19bSMatthew Dillon 	total = 0;
308eea2aa9aSMatthew Dillon 	state = 0;
309eea2aa9aSMatthew Dillon 	l1 = NULL;
310eea2aa9aSMatthew Dillon 	l2 = NULL;
311eea2aa9aSMatthew Dillon 	l3 = NULL;
3128e25f19bSMatthew Dillon 
313eea2aa9aSMatthew Dillon 	fp = popen("pkg info -a -o -A", "r");
3148e25f19bSMatthew Dillon 
315f4094b20SMatthew Dillon 	/*
316710838f7SMatthew Dillon 	 * Always include ports-mgmt/pkg.  s4 is "x" meaning not a manual
317710838f7SMatthew Dillon 	 * selection, "d" meaning DEBUGSTOP mode, or NULL.
318f4094b20SMatthew Dillon 	 */
319f4094b20SMatthew Dillon 	queuebulk("ports-mgmt", "pkg", NULL, "x");
320f4094b20SMatthew Dillon 
3218e25f19bSMatthew Dillon 	while ((base = fgetln(fp, &len)) != NULL) {
3228e25f19bSMatthew Dillon 		if (len == 0 || base[len-1] != '\n')
3238e25f19bSMatthew Dillon 			continue;
3248e25f19bSMatthew Dillon 		base[--len] = 0;
3258e25f19bSMatthew Dillon 
326eea2aa9aSMatthew Dillon 		data = strchr(base, ':');
327eea2aa9aSMatthew Dillon 		if (data == NULL)
32853c9b6f3SMatthew Dillon 			continue;
329eea2aa9aSMatthew Dillon 		*data++ = 0;
330eea2aa9aSMatthew Dillon 
331eea2aa9aSMatthew Dillon 		base = strtok(base, " \t\r");
332eea2aa9aSMatthew Dillon 		data = strtok(data, " \t\r");
333eea2aa9aSMatthew Dillon 
334eea2aa9aSMatthew Dillon 		if (base == NULL || data == NULL)
335eea2aa9aSMatthew Dillon 			continue;
336eea2aa9aSMatthew Dillon 
337eea2aa9aSMatthew Dillon 		if (strcmp(base, "Origin") == 0) {
338eea2aa9aSMatthew Dillon 			if (state == 1) {
339eea2aa9aSMatthew Dillon 				queuebulk(l1, l2, NULL, NULL);
340eea2aa9aSMatthew Dillon 				state = 0;
34153c9b6f3SMatthew Dillon 				++total;
3428e25f19bSMatthew Dillon 			}
343eea2aa9aSMatthew Dillon 
344eea2aa9aSMatthew Dillon 			if (strchr(data, '/') == NULL) {
345eea2aa9aSMatthew Dillon 				printf("Badly formatted origin: %s\n", l1);
346eea2aa9aSMatthew Dillon 			}
347eea2aa9aSMatthew Dillon 			if (l1)
348eea2aa9aSMatthew Dillon 				free(l1);
349eea2aa9aSMatthew Dillon 			if (l3)
350eea2aa9aSMatthew Dillon 				free(l3);
351eea2aa9aSMatthew Dillon 			l1 = strdup(data);
352eea2aa9aSMatthew Dillon 			l2 = strchr(l1, '/');
353eea2aa9aSMatthew Dillon 			*l2++ = 0;
354eea2aa9aSMatthew Dillon 			l3 = strchr(l2, '@');	/* typically NULL */
355eea2aa9aSMatthew Dillon 			if (l3) {
356eea2aa9aSMatthew Dillon 				*l3++ = 0;
357eea2aa9aSMatthew Dillon 				l3 = strdup(l3);
358eea2aa9aSMatthew Dillon 			}
359eea2aa9aSMatthew Dillon 
360eea2aa9aSMatthew Dillon 			/*
361eea2aa9aSMatthew Dillon 			 * Don't queue ports-mgmt/pkg twice, we already
362eea2aa9aSMatthew Dillon 			 * queued it manually.
363eea2aa9aSMatthew Dillon 			 */
364eea2aa9aSMatthew Dillon 			if (strcmp(l1, "ports-mgmt") != 0 ||
365eea2aa9aSMatthew Dillon 			    strcmp(l2, "pkg") != 0) {
366eea2aa9aSMatthew Dillon 				state = 1;
367eea2aa9aSMatthew Dillon 			}
368eea2aa9aSMatthew Dillon 			continue;
369eea2aa9aSMatthew Dillon 		}
370eea2aa9aSMatthew Dillon 		if (state == 1 && strcmp(base, "flavor") == 0) {
371eea2aa9aSMatthew Dillon 			queuebulk(l1, l2, data, NULL);
372eea2aa9aSMatthew Dillon 			state = 0;
373eea2aa9aSMatthew Dillon 			++total;
374eea2aa9aSMatthew Dillon 		}
375eea2aa9aSMatthew Dillon 	}
376eea2aa9aSMatthew Dillon 	if (state == 1) {
377eea2aa9aSMatthew Dillon 		queuebulk(l1, l2, NULL, NULL);
378eea2aa9aSMatthew Dillon 		/*state = 0; not needed */
379eea2aa9aSMatthew Dillon 	}
380eea2aa9aSMatthew Dillon 	if (l1)
381eea2aa9aSMatthew Dillon 		free(l1);
382eea2aa9aSMatthew Dillon 	if (l3)
383eea2aa9aSMatthew Dillon 		free(l3);
384eea2aa9aSMatthew Dillon 
3858e25f19bSMatthew Dillon 	pclose(fp);
3868e25f19bSMatthew Dillon 
3878e25f19bSMatthew Dillon 	printf("Processing %d ports\n", total);
3888e25f19bSMatthew Dillon 
3898e25f19bSMatthew Dillon 	list = processPackageListBulk(total);
3908e25f19bSMatthew Dillon 
3918e25f19bSMatthew Dillon 	return list;
3928e25f19bSMatthew Dillon }
3938e25f19bSMatthew Dillon 
3948e25f19bSMatthew Dillon pkg_t *
GetFullPackageList(void)3958e25f19bSMatthew Dillon GetFullPackageList(void)
3968e25f19bSMatthew Dillon {
3978e25f19bSMatthew Dillon 	int total;
3988e25f19bSMatthew Dillon 
3998e25f19bSMatthew Dillon 	initbulk(childGetPackageInfo, MaxBulk);
4008e25f19bSMatthew Dillon 	total = scan_and_queue_dir(DPortsPath, NULL, 1);
4018e25f19bSMatthew Dillon 	printf("Scanning %d ports\n", total);
4028e25f19bSMatthew Dillon 
4038e25f19bSMatthew Dillon 	return processPackageListBulk(total);
4048e25f19bSMatthew Dillon }
4058e25f19bSMatthew Dillon 
4068e25f19bSMatthew Dillon /*
4078e25f19bSMatthew Dillon  * Caller has queued the process list for bulk operation.  We retrieve
4088e25f19bSMatthew Dillon  * the results and clean up the bulk operation (we may have to do a second
4098e25f19bSMatthew Dillon  * bulk operation so we have to be the ones to clean it up).
4108e25f19bSMatthew Dillon  */
4118e25f19bSMatthew Dillon static pkg_t *
processPackageListBulk(int total)4128e25f19bSMatthew Dillon processPackageListBulk(int total)
4138e25f19bSMatthew Dillon {
4148e25f19bSMatthew Dillon 	bulk_t *bulk;
4158e25f19bSMatthew Dillon 	pkg_t *scan;
4168e25f19bSMatthew Dillon 	pkg_t *list;
4178e25f19bSMatthew Dillon 	pkg_t *dep_list;
4188e25f19bSMatthew Dillon 	pkg_t **list_tail;
4198e25f19bSMatthew Dillon 	int count;
420927e4e3eSMatthew Dillon 	int stop_fail;
421eea2aa9aSMatthew Dillon 	int stop_base_list;
422eea2aa9aSMatthew Dillon 	int remove_corrupt;
4238e25f19bSMatthew Dillon 
4248e25f19bSMatthew Dillon 	list = NULL;
4258e25f19bSMatthew Dillon 	list_tail = &list;
4268e25f19bSMatthew Dillon 	count = 0;
427eea2aa9aSMatthew Dillon 	remove_corrupt = 0;
4288e25f19bSMatthew Dillon 
4298e25f19bSMatthew Dillon 	while ((bulk = getbulk()) != NULL) {
4308e25f19bSMatthew Dillon 		++count;
4318e25f19bSMatthew Dillon 		if ((count & 255) == 0) {
4328e25f19bSMatthew Dillon 			printf("%6.2f%%\r",
4338e25f19bSMatthew Dillon 				(double)count * 100.0 / (double)total + 0.001);
4348e25f19bSMatthew Dillon 			fflush(stdout);
4358e25f19bSMatthew Dillon 		}
4368e25f19bSMatthew Dillon 		if (bulk->list) {
4378e25f19bSMatthew Dillon 			*list_tail = bulk->list;
4388e25f19bSMatthew Dillon 			bulk->list = NULL;
439f4094b20SMatthew Dillon 			while ((scan = *list_tail) != NULL) {
440710838f7SMatthew Dillon 				if (bulk->s4 == NULL || bulk->s4[0] != 'x')
441f4094b20SMatthew Dillon 					scan->flags |= PKGF_MANUALSEL;
442f4094b20SMatthew Dillon 				pkg_enter(scan);
443f4094b20SMatthew Dillon 				list_tail = &scan->bnext;
4448e25f19bSMatthew Dillon 			}
4458e25f19bSMatthew Dillon 		}
4468e25f19bSMatthew Dillon 		freebulk(bulk);
4478e25f19bSMatthew Dillon 	}
4481645cafeSMatthew Dillon 	printf("100.00%%\n");
4498e25f19bSMatthew Dillon 	printf("\nTotal %d\n", count);
4508e25f19bSMatthew Dillon 	fflush(stdout);
4518e25f19bSMatthew Dillon 
4528e25f19bSMatthew Dillon 	/*
4538e25f19bSMatthew Dillon 	 * Resolve all dependencies for the related packages, potentially
4548e25f19bSMatthew Dillon 	 * adding anything that could not be found to the list.  This will
4558e25f19bSMatthew Dillon 	 * continue to issue bulk operations and process the result until
4568e25f19bSMatthew Dillon 	 * no dependencies are left.
4578e25f19bSMatthew Dillon 	 */
4588e25f19bSMatthew Dillon 	printf("Resolving dependencies...");
4598e25f19bSMatthew Dillon 	fflush(stdout);
4608e25f19bSMatthew Dillon 	dep_list = list;
4618e25f19bSMatthew Dillon 	while (dep_list) {
4628e25f19bSMatthew Dillon 		dep_list = resolveDeps(dep_list, &list_tail, 0);
4638e25f19bSMatthew Dillon 	}
4648e25f19bSMatthew Dillon 	printf("done\n");
4658e25f19bSMatthew Dillon 
4668e25f19bSMatthew Dillon 	donebulk();
4678e25f19bSMatthew Dillon 
4688e25f19bSMatthew Dillon 	/*
4698e25f19bSMatthew Dillon 	 * Generate the topology
4708e25f19bSMatthew Dillon 	 */
4718e25f19bSMatthew Dillon 	resolveDeps(list, NULL, 1);
4728e25f19bSMatthew Dillon 
4738e25f19bSMatthew Dillon 	/*
4748e25f19bSMatthew Dillon 	 * Do a final count, ignore place holders.
475927e4e3eSMatthew Dillon 	 *
476927e4e3eSMatthew Dillon 	 * Also set stop_fail if appropriate.  Check for direct specifications
477927e4e3eSMatthew Dillon 	 * which fail to probe and any direct dependencies of those
478927e4e3eSMatthew Dillon 	 * specifications, but don't recurse (for now)... don't check indirect
479927e4e3eSMatthew Dillon 	 * dependencies (i.e. A -> B -> C where A is directly specified, B
480927e4e3eSMatthew Dillon 	 * is adirect dependency, and C fails to probe).
4818e25f19bSMatthew Dillon 	 */
4828e25f19bSMatthew Dillon 	count = 0;
483927e4e3eSMatthew Dillon 	stop_fail = 0;
484eea2aa9aSMatthew Dillon 	stop_base_list = 0;
4858e25f19bSMatthew Dillon 	for (scan = list; scan; scan = scan->bnext) {
4868e25f19bSMatthew Dillon 		if ((scan->flags & PKGF_ERROR) == 0) {
4878e25f19bSMatthew Dillon 			++count;
4888e25f19bSMatthew Dillon 		}
489927e4e3eSMatthew Dillon 		if ((scan->flags & PKGF_MANUALSEL) && MaskProbeAbort == 0) {
490927e4e3eSMatthew Dillon 			pkglink_t *link;
491927e4e3eSMatthew Dillon 
492927e4e3eSMatthew Dillon 			/*
493927e4e3eSMatthew Dillon 			 * Directly specified package failed to probe
494927e4e3eSMatthew Dillon 			 */
495eea2aa9aSMatthew Dillon 			if (scan->flags & PKGF_CORRUPT) {
496927e4e3eSMatthew Dillon 				++stop_fail;
497eea2aa9aSMatthew Dillon 				++stop_base_list;
498eea2aa9aSMatthew Dillon 			}
499927e4e3eSMatthew Dillon 
500927e4e3eSMatthew Dillon 			/*
501927e4e3eSMatthew Dillon 			 * Directly specified package had a direct dependency
502927e4e3eSMatthew Dillon 			 * that failed to probe (don't go further).
503927e4e3eSMatthew Dillon 			 */
504927e4e3eSMatthew Dillon 			PKGLIST_FOREACH(link, &scan->idepon_list) {
505927e4e3eSMatthew Dillon 				if (link->pkg &&
506927e4e3eSMatthew Dillon 				    (link->pkg->flags & PKGF_CORRUPT)) {
507927e4e3eSMatthew Dillon 					++stop_fail;
508927e4e3eSMatthew Dillon 				}
509927e4e3eSMatthew Dillon 			}
510927e4e3eSMatthew Dillon 		}
5118e25f19bSMatthew Dillon 	}
5128e25f19bSMatthew Dillon 	printf("Total Returned %d\n", count);
5138e25f19bSMatthew Dillon 
5148e25f19bSMatthew Dillon 	/*
515927e4e3eSMatthew Dillon 	 * Check to see if any PKGF_MANUALSEL packages
516927e4e3eSMatthew Dillon 	 */
517927e4e3eSMatthew Dillon 	if (stop_fail) {
518eea2aa9aSMatthew Dillon 		printf("%d packages failed to probe\n", stop_fail);
519eea2aa9aSMatthew Dillon 		if (PrepareSystemFlag) {
520eea2aa9aSMatthew Dillon 			if (stop_fail == stop_base_list) {
521eea2aa9aSMatthew Dillon 				printf(
522eea2aa9aSMatthew Dillon   "prepare-system: Some of your installed packages no longer exist in\n"
523eea2aa9aSMatthew Dillon   "dports, do you wish to continue rebuilding what does exist?\n");
524eea2aa9aSMatthew Dillon 			        if (askyn("Continue anyway? "))
525eea2aa9aSMatthew Dillon 					remove_corrupt = 1;
526eea2aa9aSMatthew Dillon 			} else {
527eea2aa9aSMatthew Dillon 				printf(
528eea2aa9aSMatthew Dillon   "prepare-system: Some of your installed packages have dependencies\n"
529eea2aa9aSMatthew Dillon   "which could not be found in dports, cannot continue, aborting\n");
530eea2aa9aSMatthew Dillon 			}
531eea2aa9aSMatthew Dillon 		} else {
532*2c5f241eSMatthew Dillon 			if (ForceOpt) {
533*2c5f241eSMatthew Dillon 				remove_corrupt = 1;
534*2c5f241eSMatthew Dillon 				printf("continuing despite pkglist "
535*2c5f241eSMatthew Dillon 				       "errors (-f)\n");
536*2c5f241eSMatthew Dillon 			} else {
537eea2aa9aSMatthew Dillon 				printf("unable to continue, aborting\n");
538eea2aa9aSMatthew Dillon 			}
539*2c5f241eSMatthew Dillon 		}
540eea2aa9aSMatthew Dillon 		if (remove_corrupt == 0)
541927e4e3eSMatthew Dillon 			exit(1);
542927e4e3eSMatthew Dillon 	}
543927e4e3eSMatthew Dillon 
544927e4e3eSMatthew Dillon 	/*
545eea2aa9aSMatthew Dillon 	 * Remove corrupt packages before continuing
546eea2aa9aSMatthew Dillon 	 */
547eea2aa9aSMatthew Dillon 	if (remove_corrupt) {
548eea2aa9aSMatthew Dillon 		list_tail = &list;
549eea2aa9aSMatthew Dillon 		while ((scan = *list_tail) != NULL) {
550eea2aa9aSMatthew Dillon 			if (scan->flags & PKGF_CORRUPT)
551eea2aa9aSMatthew Dillon 				*list_tail = scan->bnext;
552eea2aa9aSMatthew Dillon 			else
553eea2aa9aSMatthew Dillon 				list_tail = &scan->bnext;
554eea2aa9aSMatthew Dillon 		}
555eea2aa9aSMatthew Dillon 	}
556eea2aa9aSMatthew Dillon 
557eea2aa9aSMatthew Dillon 	/*
5588e25f19bSMatthew Dillon 	 * Scan our binary distributions and related dependencies looking
5598e25f19bSMatthew Dillon 	 * for any packages that have already been built.
5608e25f19bSMatthew Dillon 	 */
5618e25f19bSMatthew Dillon 	initbulk(childGetBinaryDistInfo, MaxBulk);
5628e25f19bSMatthew Dillon 	total = scan_binary_repo(RepositoryPath);
5638e25f19bSMatthew Dillon 	count = 0;
5648e25f19bSMatthew Dillon 	printf("Scanning %d packages\n", total);
5658e25f19bSMatthew Dillon 
5668e25f19bSMatthew Dillon 	while ((bulk = getbulk()) != NULL) {
5678e25f19bSMatthew Dillon 		++count;
5688e25f19bSMatthew Dillon 		if ((count & 255) == 0) {
5698e25f19bSMatthew Dillon 			printf("%6.2f%%\r",
5708e25f19bSMatthew Dillon 				(double)count * 100.0 / (double)total + 0.001);
5718e25f19bSMatthew Dillon 			fflush(stdout);
5728e25f19bSMatthew Dillon 		}
5738e25f19bSMatthew Dillon 		freebulk(bulk);
5748e25f19bSMatthew Dillon 	}
5751645cafeSMatthew Dillon 	printf("100.00%%\n");
5768e25f19bSMatthew Dillon 	printf("\nTotal %d\n", count);
5778e25f19bSMatthew Dillon 	fflush(stdout);
5788e25f19bSMatthew Dillon 	donebulk();
5798e25f19bSMatthew Dillon 
5808e25f19bSMatthew Dillon 	printf("all done\n");
5818e25f19bSMatthew Dillon 
5828e25f19bSMatthew Dillon 	return list;
5838e25f19bSMatthew Dillon }
5848e25f19bSMatthew Dillon 
5858e25f19bSMatthew Dillon pkg_t *
GetPkgPkg(pkg_t ** listp)586549987f1SMatthew Dillon GetPkgPkg(pkg_t **listp)
5878e25f19bSMatthew Dillon {
5888e25f19bSMatthew Dillon 	bulk_t *bulk;
5898e25f19bSMatthew Dillon 	pkg_t *scan;
590549987f1SMatthew Dillon 	pkg_t *s2;
5918e25f19bSMatthew Dillon 
592549987f1SMatthew Dillon 	for (scan = *listp; scan; scan = scan->bnext) {
5938e25f19bSMatthew Dillon 		if (strcmp(scan->portdir, "ports-mgmt/pkg") == 0)
5948e25f19bSMatthew Dillon 			return scan;
5958e25f19bSMatthew Dillon 	}
5968e25f19bSMatthew Dillon 
597f4094b20SMatthew Dillon 	/*
598f4094b20SMatthew Dillon 	 * This will force pkg to be built, but generally this code
599f4094b20SMatthew Dillon 	 * is not reached because the package list processing code
600f4094b20SMatthew Dillon 	 * adds ports-mgmt/pkg unconditionally.
601f4094b20SMatthew Dillon 	 */
6028e25f19bSMatthew Dillon 	initbulk(childGetPackageInfo, MaxBulk);
603f4094b20SMatthew Dillon 	queuebulk("ports-mgmt", "pkg", NULL, "x");
6048e25f19bSMatthew Dillon 	bulk = getbulk();
6058e25f19bSMatthew Dillon 	dassert(bulk, "Cannot find ports-mgmt/pkg");
6068e25f19bSMatthew Dillon 	scan = bulk->list;
6078e25f19bSMatthew Dillon 	bulk->list = NULL;
6088e25f19bSMatthew Dillon 	freebulk(bulk);
6098e25f19bSMatthew Dillon 	donebulk();
6108e25f19bSMatthew Dillon 
611549987f1SMatthew Dillon 
612549987f1SMatthew Dillon 	/*
613549987f1SMatthew Dillon 	 * Include added packages to the total and add the initial bulk
614549987f1SMatthew Dillon 	 * built packages to the list so they get counted.
615549987f1SMatthew Dillon 	 */
616549987f1SMatthew Dillon 	for (s2 = scan; s2->bnext; s2 = s2->bnext)
617549987f1SMatthew Dillon 		++BuildTotal;
618549987f1SMatthew Dillon 	for (s2 = scan; s2->bnext; s2 = s2->bnext)
619549987f1SMatthew Dillon 		;
620549987f1SMatthew Dillon 	s2->bnext = *listp;
621549987f1SMatthew Dillon 	*listp = scan;
622549987f1SMatthew Dillon 	++BuildTotal;
623549987f1SMatthew Dillon 
6248e25f19bSMatthew Dillon 	return scan;
6258e25f19bSMatthew Dillon }
6268e25f19bSMatthew Dillon 
6278e25f19bSMatthew Dillon /*
628a67bf8dbSMatthew Dillon  * Try to optimize the environment by supplying information that
629a67bf8dbSMatthew Dillon  * the ports system would generally have to run stuff to get on
630a67bf8dbSMatthew Dillon  * every package.
631a67bf8dbSMatthew Dillon  *
632a67bf8dbSMatthew Dillon  * See childOptimizeEnv() for the actual handling.  We execute
633a67bf8dbSMatthew Dillon  * a single make -V... -V... for ports-mgmt/pkg from within the
634a67bf8dbSMatthew Dillon  * bulk system (which handles the environment and disables
635a67bf8dbSMatthew Dillon  * /etc/make.conf), and we then call addbuildenv() as appropriate.
636a67bf8dbSMatthew Dillon  *
637a67bf8dbSMatthew Dillon  * _PERL5_FROM_BIN
638a67bf8dbSMatthew Dillon  * add others...
639a67bf8dbSMatthew Dillon  */
640a67bf8dbSMatthew Dillon void
OptimizeEnv(void)641a67bf8dbSMatthew Dillon OptimizeEnv(void)
642a67bf8dbSMatthew Dillon {
643a67bf8dbSMatthew Dillon 	bulk_t *bulk;
644a67bf8dbSMatthew Dillon 
645a67bf8dbSMatthew Dillon 	initbulk(childOptimizeEnv, MaxBulk);
646a67bf8dbSMatthew Dillon 	queuebulk("ports-mgmt", "pkg", NULL, NULL);
647a67bf8dbSMatthew Dillon 	bulk = getbulk();
648a67bf8dbSMatthew Dillon 	freebulk(bulk);
649a67bf8dbSMatthew Dillon 	donebulk();
650a67bf8dbSMatthew Dillon }
651a67bf8dbSMatthew Dillon 
652a67bf8dbSMatthew Dillon /*
6538e25f19bSMatthew Dillon  * Run through the list resolving dependencies and constructing the topology
65477ac77e7SMatthew Dillon  * linkages.   This may append packages to the list.  Dependencies to dummy
65577ac77e7SMatthew Dillon  * nodes which do not specify a flavor do not need special handling, the
65677ac77e7SMatthew Dillon  * search code in build.c will properly follow the first flavor.
6578e25f19bSMatthew Dillon  */
6588e25f19bSMatthew Dillon static pkg_t *
resolveDeps(pkg_t * list,pkg_t *** list_tailp,int gentopo)6598e25f19bSMatthew Dillon resolveDeps(pkg_t *list, pkg_t ***list_tailp, int gentopo)
6608e25f19bSMatthew Dillon {
6618e25f19bSMatthew Dillon 	pkg_t *ret_list = NULL;
66277ac77e7SMatthew Dillon 	pkg_t *scan;
66377ac77e7SMatthew Dillon 	pkg_t *use;
6648e25f19bSMatthew Dillon 	bulk_t *bulk;
6658e25f19bSMatthew Dillon 
6668e25f19bSMatthew Dillon 	for (scan = list; scan; scan = scan->bnext) {
66777ac77e7SMatthew Dillon 		use = pkg_find(scan->portdir);
66877ac77e7SMatthew Dillon 		resolveFlavors(use, scan->flavors, gentopo);
66977ac77e7SMatthew Dillon 		resolveDepString(use, scan->fetch_deps,
67063fcce5bSMatthew Dillon 				 gentopo, DEP_TYPE_FETCH);
67177ac77e7SMatthew Dillon 		resolveDepString(use, scan->ext_deps,
67263fcce5bSMatthew Dillon 				 gentopo, DEP_TYPE_EXT);
67377ac77e7SMatthew Dillon 		resolveDepString(use, scan->patch_deps,
67463fcce5bSMatthew Dillon 				 gentopo, DEP_TYPE_PATCH);
67577ac77e7SMatthew Dillon 		resolveDepString(use, scan->build_deps,
67663fcce5bSMatthew Dillon 				 gentopo, DEP_TYPE_BUILD);
67777ac77e7SMatthew Dillon 		resolveDepString(use, scan->lib_deps,
67863fcce5bSMatthew Dillon 				 gentopo, DEP_TYPE_LIB);
67977ac77e7SMatthew Dillon 		resolveDepString(use, scan->run_deps,
68063fcce5bSMatthew Dillon 				 gentopo, DEP_TYPE_RUN);
6818e25f19bSMatthew Dillon 	}
6828e25f19bSMatthew Dillon 
6838e25f19bSMatthew Dillon 	/*
6848e25f19bSMatthew Dillon 	 * No bulk ops are queued when doing the final topology
6858e25f19bSMatthew Dillon 	 * generation.
68677ac77e7SMatthew Dillon 	 *
68777ac77e7SMatthew Dillon 	 * Avoid entering duplicate results from the bulk ops.  Duplicate
68877ac77e7SMatthew Dillon 	 * results are mostly filtered out, but not always.  A dummy node
68977ac77e7SMatthew Dillon 	 * representing multiple flavors will parse-out the flavors
6908e25f19bSMatthew Dillon 	 */
6918e25f19bSMatthew Dillon 	if (gentopo)
6928e25f19bSMatthew Dillon 		return NULL;
6938e25f19bSMatthew Dillon 	while ((bulk = getbulk()) != NULL) {
6948e25f19bSMatthew Dillon 		if (bulk->list) {
6958e25f19bSMatthew Dillon 			if (ret_list == NULL)
6968e25f19bSMatthew Dillon 				ret_list = bulk->list;
6978e25f19bSMatthew Dillon 			**list_tailp = bulk->list;
6988e25f19bSMatthew Dillon 			bulk->list = NULL;
69977ac77e7SMatthew Dillon 			while ((scan = **list_tailp) != NULL) {
70077ac77e7SMatthew Dillon 				pkg_enter(scan);
70177ac77e7SMatthew Dillon 				*list_tailp = &scan->bnext;
7028e25f19bSMatthew Dillon 			}
7038e25f19bSMatthew Dillon 		}
7048e25f19bSMatthew Dillon 		freebulk(bulk);
7058e25f19bSMatthew Dillon 	}
7068e25f19bSMatthew Dillon 	return (ret_list);
7078e25f19bSMatthew Dillon }
7088e25f19bSMatthew Dillon 
70977ac77e7SMatthew Dillon /*
71077ac77e7SMatthew Dillon  * Resolve a generic node that has flavors, queue to retrieve info for
71177ac77e7SMatthew Dillon  * each flavor and setup linkages as appropriate.
71277ac77e7SMatthew Dillon  */
71377ac77e7SMatthew Dillon static void
resolveFlavors(pkg_t * pkg,char * flavors,int gentopo)71477ac77e7SMatthew Dillon resolveFlavors(pkg_t *pkg, char *flavors, int gentopo)
71577ac77e7SMatthew Dillon {
71677ac77e7SMatthew Dillon 	char *flavor_base;
71777ac77e7SMatthew Dillon 	char *flavor_scan;
71877ac77e7SMatthew Dillon 	char *flavor;
71977ac77e7SMatthew Dillon 	char *portdir;
72077ac77e7SMatthew Dillon 	char *s1;
72177ac77e7SMatthew Dillon 	char *s2;
72277ac77e7SMatthew Dillon 	pkg_t *dpkg;
72377ac77e7SMatthew Dillon 	pkglink_t *link;
72477ac77e7SMatthew Dillon 
72577ac77e7SMatthew Dillon 	if ((pkg->flags & PKGF_DUMMY) == 0)
72677ac77e7SMatthew Dillon 		return;
72777ac77e7SMatthew Dillon 	if (pkg->flavors == NULL || pkg->flavors[0] == 0)
72877ac77e7SMatthew Dillon 		return;
72977ac77e7SMatthew Dillon 	flavor_base = strdup(flavors);
73077ac77e7SMatthew Dillon 	flavor_scan = flavor_base;
73177ac77e7SMatthew Dillon 
73277ac77e7SMatthew Dillon 	for (;;) {
73377ac77e7SMatthew Dillon 		do {
73477ac77e7SMatthew Dillon 			flavor = strsep(&flavor_scan, " \t");
73577ac77e7SMatthew Dillon 		} while (flavor && *flavor == 0);
73677ac77e7SMatthew Dillon 		if (flavor == NULL)
73777ac77e7SMatthew Dillon 			break;
73877ac77e7SMatthew Dillon 
73977ac77e7SMatthew Dillon 		/*
74077ac77e7SMatthew Dillon 		 * Iterate each flavor generating "s1/s2@flavor".
74177ac77e7SMatthew Dillon 		 *
74277ac77e7SMatthew Dillon 		 * queuebulk() info for each flavor, and set-up the
74377ac77e7SMatthew Dillon 		 * linkages in the topology generation pass.
74477ac77e7SMatthew Dillon 		 */
74577ac77e7SMatthew Dillon 		asprintf(&portdir, "%s@%s", pkg->portdir, flavor);
74677ac77e7SMatthew Dillon 		s1 = strdup(pkg->portdir);
74777ac77e7SMatthew Dillon 		s2 = strchr(s1, '/');
74877ac77e7SMatthew Dillon 		*s2++ = 0;
74977ac77e7SMatthew Dillon 
75077ac77e7SMatthew Dillon 		dpkg = pkg_find(portdir);
75177ac77e7SMatthew Dillon 		if (dpkg && gentopo) {
75277ac77e7SMatthew Dillon 			/*
75377ac77e7SMatthew Dillon 			 * Setup linkages
75477ac77e7SMatthew Dillon 			 */
75577ac77e7SMatthew Dillon 			free(portdir);
75677ac77e7SMatthew Dillon 
75777ac77e7SMatthew Dillon 			link = calloc(1, sizeof(*link));
75877ac77e7SMatthew Dillon 			link->pkg = dpkg;
75977ac77e7SMatthew Dillon 			link->next = &pkg->idepon_list;
76077ac77e7SMatthew Dillon 			link->prev = pkg->idepon_list.prev;
76177ac77e7SMatthew Dillon 			link->next->prev = link;
76277ac77e7SMatthew Dillon 			link->prev->next = link;
76377ac77e7SMatthew Dillon 			link->dep_type = DEP_TYPE_BUILD;
76477ac77e7SMatthew Dillon 
76577ac77e7SMatthew Dillon 			link = calloc(1, sizeof(*link));
76677ac77e7SMatthew Dillon 			link->pkg = pkg;
76777ac77e7SMatthew Dillon 			link->next = &dpkg->deponi_list;
76877ac77e7SMatthew Dillon 			link->prev = dpkg->deponi_list.prev;
76977ac77e7SMatthew Dillon 			link->next->prev = link;
77077ac77e7SMatthew Dillon 			link->prev->next = link;
77177ac77e7SMatthew Dillon 			link->dep_type = DEP_TYPE_BUILD;
77277ac77e7SMatthew Dillon 			++dpkg->depi_count;
77377ac77e7SMatthew Dillon 		} else if (gentopo == 0 && dpkg == NULL) {
77477ac77e7SMatthew Dillon 			/*
77577ac77e7SMatthew Dillon 			 * Use a place-holder to prevent duplicate
77677ac77e7SMatthew Dillon 			 * dependencies from being processed.  The placeholder
77777ac77e7SMatthew Dillon 			 * will be replaced by the actual dependency.
77877ac77e7SMatthew Dillon 			 */
77977ac77e7SMatthew Dillon 			dpkg = allocpkg();
78077ac77e7SMatthew Dillon 			dpkg->portdir = portdir;
78177ac77e7SMatthew Dillon 			dpkg->flags = PKGF_PLACEHOLD;
78277ac77e7SMatthew Dillon 			pkg_enter(dpkg);
78377ac77e7SMatthew Dillon 			queuebulk(s1, s2, flavor, NULL);
78477ac77e7SMatthew Dillon 		}
78577ac77e7SMatthew Dillon 		free(s1);
78677ac77e7SMatthew Dillon 	}
78777ac77e7SMatthew Dillon 	free(flavor_base);
78877ac77e7SMatthew Dillon }
78977ac77e7SMatthew Dillon 
7908e25f19bSMatthew Dillon static void
resolveDepString(pkg_t * pkg,char * depstr,int gentopo,int dep_type)79163fcce5bSMatthew Dillon resolveDepString(pkg_t *pkg, char *depstr, int gentopo, int dep_type)
7928e25f19bSMatthew Dillon {
7938e25f19bSMatthew Dillon 	char *copy_base;
7948e25f19bSMatthew Dillon 	char *copy;
7958e25f19bSMatthew Dillon 	char *dep;
79624b60d12SMatthew Dillon 	char *log_component;
7978e25f19bSMatthew Dillon 	char *sep;
7988e25f19bSMatthew Dillon 	char *tag;
7998e25f19bSMatthew Dillon 	char *flavor;
8008e25f19bSMatthew Dillon 	pkg_t *dpkg;
8018e25f19bSMatthew Dillon 
8028e25f19bSMatthew Dillon 	if (depstr == NULL || depstr[0] == 0)
8038e25f19bSMatthew Dillon 		return;
8048e25f19bSMatthew Dillon 
8058e25f19bSMatthew Dillon 	copy_base = strdup(depstr);
8068e25f19bSMatthew Dillon 	copy = copy_base;
80724b60d12SMatthew Dillon 	log_component = copy;
8088e25f19bSMatthew Dillon 
8098e25f19bSMatthew Dillon 	for (;;) {
8108e25f19bSMatthew Dillon 		do {
8118e25f19bSMatthew Dillon 			dep = strsep(&copy, " \t");
8128e25f19bSMatthew Dillon 		} while (dep && *dep == 0);
8138e25f19bSMatthew Dillon 		if (dep == NULL)
8148e25f19bSMatthew Dillon 			break;
8156fd67931SMatthew Dillon 
8166fd67931SMatthew Dillon 		/*
8176fd67931SMatthew Dillon 		 * Ignore dependencies prefixed with ${NONEXISTENT}
8186fd67931SMatthew Dillon 		 */
8196fd67931SMatthew Dillon 		if (strncmp(dep, "/nonexistent:", 13) == 0)
8206fd67931SMatthew Dillon 			continue;
8216fd67931SMatthew Dillon 
82224b60d12SMatthew Dillon 		log_component = dep;
8238e25f19bSMatthew Dillon 		dep = strchr(dep, ':');
8248e25f19bSMatthew Dillon 		if (dep == NULL || *dep != ':') {
82593fe0327SMatthew Dillon 			printf("Error parsing %s dependency for "
82624b60d12SMatthew Dillon 			       "%s: '%s' at index %zd '%s' "
82724b60d12SMatthew Dillon 			       "(looking for ':')\n",
82893fe0327SMatthew Dillon 			       deptype2str(dep_type),
829baf7c614SMatthew Dillon 			       pkg->portdir, depstr,
83024b60d12SMatthew Dillon 			       log_component - copy_base,
83124b60d12SMatthew Dillon 			       log_component);
8328e25f19bSMatthew Dillon 			continue;
8338e25f19bSMatthew Dillon 		}
8348e25f19bSMatthew Dillon 		++dep;
8358e25f19bSMatthew Dillon 
8368e25f19bSMatthew Dillon 		/*
8378e25f19bSMatthew Dillon 		 * Strip-off any DPortsPath prefix.  EXTRACT_DEPENDS
8388e25f19bSMatthew Dillon 		 * often (always?) generates this prefix.
8398e25f19bSMatthew Dillon 		 */
8408e25f19bSMatthew Dillon 		if (strncmp(dep, DPortsPath, strlen(DPortsPath)) == 0) {
8418e25f19bSMatthew Dillon 			dep += strlen(DPortsPath);
8428e25f19bSMatthew Dillon 			if (*dep == '/')
8438e25f19bSMatthew Dillon 				++dep;
8448e25f19bSMatthew Dillon 		}
8458e25f19bSMatthew Dillon 
8468e25f19bSMatthew Dillon 		/*
8478e25f19bSMatthew Dillon 		 * Strip-off any tag (such as :patch).  We don't try to
8488e25f19bSMatthew Dillon 		 * organize dependencies at this fine a grain (for now).
8498e25f19bSMatthew Dillon 		 */
8508e25f19bSMatthew Dillon 		tag = strchr(dep, ':');
8518e25f19bSMatthew Dillon 		if (tag)
8528e25f19bSMatthew Dillon 			*tag++ = 0;
85324b60d12SMatthew Dillon 		log_component = dep;
8548e25f19bSMatthew Dillon 
8558e25f19bSMatthew Dillon 		/*
8568e25f19bSMatthew Dillon 		 * Locate the dependency
8578e25f19bSMatthew Dillon 		 */
8588e25f19bSMatthew Dillon 		if ((dpkg = pkg_find(dep)) != NULL) {
8598e25f19bSMatthew Dillon 			if (gentopo) {
8608e25f19bSMatthew Dillon 				pkglink_t *link;
8618e25f19bSMatthew Dillon 
8628e25f19bSMatthew Dillon 				/*
8638e25f19bSMatthew Dillon 				 * NOTE: idep_count is calculated recursively
8648e25f19bSMatthew Dillon 				 *	 at build-time
8658e25f19bSMatthew Dillon 				 */
8668e25f19bSMatthew Dillon 				ddprintf(0, "Add Dependency %s -> %s\n",
8678e25f19bSMatthew Dillon 					pkg->portdir, dpkg->portdir);
8688e25f19bSMatthew Dillon 				link = calloc(1, sizeof(*link));
8698e25f19bSMatthew Dillon 				link->pkg = dpkg;
8708e25f19bSMatthew Dillon 				link->next = &pkg->idepon_list;
8718e25f19bSMatthew Dillon 				link->prev = pkg->idepon_list.prev;
8728e25f19bSMatthew Dillon 				link->next->prev = link;
8738e25f19bSMatthew Dillon 				link->prev->next = link;
87463fcce5bSMatthew Dillon 				link->dep_type = dep_type;
8758e25f19bSMatthew Dillon 
8768e25f19bSMatthew Dillon 				link = calloc(1, sizeof(*link));
8778e25f19bSMatthew Dillon 				link->pkg = pkg;
8788e25f19bSMatthew Dillon 				link->next = &dpkg->deponi_list;
8798e25f19bSMatthew Dillon 				link->prev = dpkg->deponi_list.prev;
8808e25f19bSMatthew Dillon 				link->next->prev = link;
8818e25f19bSMatthew Dillon 				link->prev->next = link;
88263fcce5bSMatthew Dillon 				link->dep_type = dep_type;
8838e25f19bSMatthew Dillon 				++dpkg->depi_count;
8848e25f19bSMatthew Dillon 			}
8858e25f19bSMatthew Dillon 			continue;
8868e25f19bSMatthew Dillon 		}
8878e25f19bSMatthew Dillon 
8888e25f19bSMatthew Dillon 		/*
8898e25f19bSMatthew Dillon 		 * This shouldn't happen because we already took a first
8908e25f19bSMatthew Dillon 		 * pass and should have generated the pkgs.
8918e25f19bSMatthew Dillon 		 */
8928e25f19bSMatthew Dillon 		if (gentopo) {
8938e25f19bSMatthew Dillon 			printf("Topology Generate failed for %s: %s\n",
8948e25f19bSMatthew Dillon 				pkg->portdir, copy_base);
8958e25f19bSMatthew Dillon 			continue;
8968e25f19bSMatthew Dillon 		}
8978e25f19bSMatthew Dillon 
8988e25f19bSMatthew Dillon 		/*
8998e25f19bSMatthew Dillon 		 * Separate out the two dports directory components and
9008e25f19bSMatthew Dillon 		 * extract the optional '@flavor' specification.
9018e25f19bSMatthew Dillon 		 */
9028e25f19bSMatthew Dillon 		sep = strchr(dep, '/');
9038e25f19bSMatthew Dillon 		if (sep == NULL) {
90493fe0327SMatthew Dillon 			printf("Error parsing %s dependency for "
90524b60d12SMatthew Dillon 			       "%s: '%s' at index %zd '%s' "
90624b60d12SMatthew Dillon 			       "(looking for '/')\n",
90793fe0327SMatthew Dillon 			       deptype2str(dep_type),
908baf7c614SMatthew Dillon 			       pkg->portdir, depstr,
90924b60d12SMatthew Dillon 			       log_component - copy_base,
91024b60d12SMatthew Dillon 			       log_component);
9118e25f19bSMatthew Dillon 			continue;
9128e25f19bSMatthew Dillon 		}
9138e25f19bSMatthew Dillon 		*sep++ = 0;
9148e25f19bSMatthew Dillon 
91595f08ce8SMatthew Dillon 		/*
91695f08ce8SMatthew Dillon 		 * The flavor hangs off the separator, not the tag
91795f08ce8SMatthew Dillon 		 */
91895f08ce8SMatthew Dillon 		flavor = strrchr(sep, '@');
91995f08ce8SMatthew Dillon #if 0
9208e25f19bSMatthew Dillon 		if (tag)
9218e25f19bSMatthew Dillon 			flavor = strrchr(tag, '@');
9228e25f19bSMatthew Dillon 		else
9238e25f19bSMatthew Dillon 			flavor = strrchr(sep, '@');
92495f08ce8SMatthew Dillon #endif
9258e25f19bSMatthew Dillon 		if (flavor)
9268e25f19bSMatthew Dillon 			*flavor++ = 0;
9278e25f19bSMatthew Dillon 
9288e25f19bSMatthew Dillon 		if (flavor)
9298e25f19bSMatthew Dillon 			ddprintf(0, "QUEUE DEPENDENCY FROM PKG %s: %s/%s@%s\n",
9308e25f19bSMatthew Dillon 			       pkg->portdir, dep, sep, flavor);
9318e25f19bSMatthew Dillon 		else
9328e25f19bSMatthew Dillon 			ddprintf(0, "QUEUE DEPENDENCY FROM PKG %s: %s/%s\n",
9338e25f19bSMatthew Dillon 			       pkg->portdir, dep, sep);
9348e25f19bSMatthew Dillon 
9358e25f19bSMatthew Dillon 		/*
9368e25f19bSMatthew Dillon 		 * Use a place-holder to prevent duplicate dependencies from
9378e25f19bSMatthew Dillon 		 * being processed.  The placeholder will be replaced by
9388e25f19bSMatthew Dillon 		 * the actual dependency.
9398e25f19bSMatthew Dillon 		 */
9408e25f19bSMatthew Dillon 		dpkg = allocpkg();
9418e25f19bSMatthew Dillon 		if (flavor)
9428e25f19bSMatthew Dillon 			asprintf(&dpkg->portdir, "%s/%s@%s", dep, sep, flavor);
9438e25f19bSMatthew Dillon 		else
9448e25f19bSMatthew Dillon 			asprintf(&dpkg->portdir, "%s/%s", dep, sep);
9458e25f19bSMatthew Dillon 		dpkg->flags = PKGF_PLACEHOLD;
9468e25f19bSMatthew Dillon 		pkg_enter(dpkg);
9478e25f19bSMatthew Dillon 
9488e25f19bSMatthew Dillon 		queuebulk(dep, sep, flavor, NULL);
9498e25f19bSMatthew Dillon 	}
9508e25f19bSMatthew Dillon 	free(copy_base);
9518e25f19bSMatthew Dillon }
9528e25f19bSMatthew Dillon 
9538e25f19bSMatthew Dillon void
FreePackageList(pkg_t * pkgs __unused)9548e25f19bSMatthew Dillon FreePackageList(pkg_t *pkgs __unused)
9558e25f19bSMatthew Dillon {
9568e25f19bSMatthew Dillon 	dfatal("not implemented");
9578e25f19bSMatthew Dillon }
9588e25f19bSMatthew Dillon 
9598e25f19bSMatthew Dillon /*
9608e25f19bSMatthew Dillon  * Scan some or all dports to allocate the related pkg structure.  Dependencies
9618e25f19bSMatthew Dillon  * are stored but not processed.
9628e25f19bSMatthew Dillon  *
9638e25f19bSMatthew Dillon  * Threaded function
9648e25f19bSMatthew Dillon  */
9658e25f19bSMatthew Dillon static void
childGetPackageInfo(bulk_t * bulk)9668e25f19bSMatthew Dillon childGetPackageInfo(bulk_t *bulk)
9678e25f19bSMatthew Dillon {
9688e25f19bSMatthew Dillon 	pkg_t *pkg;
9698e25f19bSMatthew Dillon 	char *flavor;
9708e25f19bSMatthew Dillon 	char *ptr;
9718e25f19bSMatthew Dillon 	FILE *fp;
9728e25f19bSMatthew Dillon 	int line;
9738e25f19bSMatthew Dillon 	size_t len;
9746fd67931SMatthew Dillon 	char *portpath;
9756fd67931SMatthew Dillon 	char *flavarg;
9765d0718a8SMatthew Dillon 	char *localbase;
9776fd67931SMatthew Dillon 	const char *cav[MAXCAC];
9786fd67931SMatthew Dillon 	pid_t pid;
9796fd67931SMatthew Dillon 	int cac;
9808e25f19bSMatthew Dillon 
9818e25f19bSMatthew Dillon 	/*
9828e25f19bSMatthew Dillon 	 * If the package has flavors we will loop on each one.  If a flavor
9838e25f19bSMatthew Dillon 	 * is not passed in s3 we will loop on all flavors, otherwise we will
9848e25f19bSMatthew Dillon 	 * only process the passed-in flavor.
9858e25f19bSMatthew Dillon 	 */
9868e25f19bSMatthew Dillon 	flavor = bulk->s3;	/* usually NULL */
9878e25f19bSMatthew Dillon 
9888e25f19bSMatthew Dillon 	bulk->list = NULL;
98977ac77e7SMatthew Dillon 
9906fd67931SMatthew Dillon 	asprintf(&portpath, "%s/%s/%s", DPortsPath, bulk->s1, bulk->s2);
9916fd67931SMatthew Dillon 	if (flavor)
9926fd67931SMatthew Dillon 		asprintf(&flavarg, "FLAVOR=%s", flavor);
9936fd67931SMatthew Dillon 	else
9946fd67931SMatthew Dillon 		flavarg = NULL;
9956fd67931SMatthew Dillon 
9966fd67931SMatthew Dillon 	cac = 0;
9976fd67931SMatthew Dillon 	cav[cac++] = MAKE_BINARY;
9986fd67931SMatthew Dillon 	cav[cac++] = "-C";
9996fd67931SMatthew Dillon 	cav[cac++] = portpath;
10006fd67931SMatthew Dillon 	if (flavarg)
10016fd67931SMatthew Dillon 		cav[cac++] = flavarg;
10025d0718a8SMatthew Dillon 
10035d0718a8SMatthew Dillon 	/*
10045d0718a8SMatthew Dillon 	 * Prevent postgresql, mysql, and other package Makefile tests
10055d0718a8SMatthew Dillon 	 * from accessing the host system's /usr/local by setting LOCALBASE
10065d0718a8SMatthew Dillon 	 * to an empty directory.
10075d0718a8SMatthew Dillon 	 */
10085d0718a8SMatthew Dillon 	asprintf(&localbase, "LOCALBASE=%s/empty", BuildBase);
10095d0718a8SMatthew Dillon 	cav[cac++] = localbase;
10105d0718a8SMatthew Dillon 
10115d0718a8SMatthew Dillon 	/*
10125d0718a8SMatthew Dillon 	 * Variables we need to retrieve (order is specific to the switch
10135d0718a8SMatthew Dillon 	 * below)
10145d0718a8SMatthew Dillon 	 */
10156fd67931SMatthew Dillon 	cav[cac++] = "-VPKGVERSION";
10166fd67931SMatthew Dillon 	cav[cac++] = "-VPKGFILE:T";
10176ec1f604SMatthew Dillon 	cav[cac++] = "-VALLFILES";
10186fd67931SMatthew Dillon 	cav[cac++] = "-VDIST_SUBDIR";
10196fd67931SMatthew Dillon 	cav[cac++] = "-VMAKE_JOBS_NUMBER";
10206fd67931SMatthew Dillon 	cav[cac++] = "-VIGNORE";
10216fd67931SMatthew Dillon 	cav[cac++] = "-VFETCH_DEPENDS";
10226fd67931SMatthew Dillon 	cav[cac++] = "-VEXTRACT_DEPENDS";
10236fd67931SMatthew Dillon 	cav[cac++] = "-VPATCH_DEPENDS";
10246fd67931SMatthew Dillon 	cav[cac++] = "-VBUILD_DEPENDS";
10256fd67931SMatthew Dillon 	cav[cac++] = "-VLIB_DEPENDS";
10266fd67931SMatthew Dillon 	cav[cac++] = "-VRUN_DEPENDS";
10276fd67931SMatthew Dillon 	cav[cac++] = "-VSELECTED_OPTIONS";
10286fd67931SMatthew Dillon 	cav[cac++] = "-VDESELECTED_OPTIONS";
10296fd67931SMatthew Dillon 	cav[cac++] = "-VUSE_LINUX";
10306fd67931SMatthew Dillon 	cav[cac++] = "-VFLAVORS";
1031f4094b20SMatthew Dillon 	cav[cac++] = "-VUSES";
10326fd67931SMatthew Dillon 
1033f9d29536SMatthew Dillon 	fp = dexec_open(portpath + strlen(DPortsPath) + 1, cav, cac,
1034f9d29536SMatthew Dillon 			&pid, NULL, 1, 1);
10356fd67931SMatthew Dillon 	freestrp(&flavarg);
10365d0718a8SMatthew Dillon 	freestrp(&localbase);
10378e25f19bSMatthew Dillon 
10388e25f19bSMatthew Dillon 	pkg = allocpkg();
10398e25f19bSMatthew Dillon 	if (flavor)
10408e25f19bSMatthew Dillon 		asprintf(&pkg->portdir, "%s/%s@%s", bulk->s1, bulk->s2, flavor);
10418e25f19bSMatthew Dillon 	else
10428e25f19bSMatthew Dillon 		asprintf(&pkg->portdir, "%s/%s", bulk->s1, bulk->s2);
10438e25f19bSMatthew Dillon 
10446fd67931SMatthew Dillon 	line = 1;
10458e25f19bSMatthew Dillon 	while ((ptr = fgetln(fp, &len)) != NULL) {
10468e25f19bSMatthew Dillon 		if (len == 0 || ptr[len-1] != '\n') {
10478e25f19bSMatthew Dillon 			dfatal("Bad package info for %s/%s response line %d",
10488e25f19bSMatthew Dillon 			       bulk->s1, bulk->s2, line);
10498e25f19bSMatthew Dillon 		}
10508e25f19bSMatthew Dillon 		ptr[--len] = 0;
10518e25f19bSMatthew Dillon 
10528e25f19bSMatthew Dillon 		switch(line) {
10538e25f19bSMatthew Dillon 		case 1:		/* PKGVERSION */
10548e25f19bSMatthew Dillon 			asprintf(&pkg->version, "%s", ptr);
10558e25f19bSMatthew Dillon 			break;
10568e25f19bSMatthew Dillon 		case 2:		/* PKGFILE */
10578e25f19bSMatthew Dillon 			asprintf(&pkg->pkgfile, "%s", ptr);
10588e25f19bSMatthew Dillon 			break;
10596ec1f604SMatthew Dillon 		case 3:		/* ALLFILES (aka DISTFILES + patch files) */
10601645cafeSMatthew Dillon 			asprintf(&pkg->distfiles, "%s", ptr);
10611645cafeSMatthew Dillon 			break;
10621645cafeSMatthew Dillon 		case 4:		/* DIST_SUBDIR */
10634ea2ee4dSMatthew Dillon 			pkg->distsubdir = strdup_or_null(ptr);
10641645cafeSMatthew Dillon 			break;
10651645cafeSMatthew Dillon 		case 5:		/* MAKE_JOBS_NUMBER */
10668e25f19bSMatthew Dillon 			pkg->make_jobs_number = strtol(ptr, NULL, 0);
10678e25f19bSMatthew Dillon 			break;
10681645cafeSMatthew Dillon 		case 6:		/* IGNORE */
10694ea2ee4dSMatthew Dillon 			pkg->ignore = strdup_or_null(ptr);
10708e25f19bSMatthew Dillon 			break;
10711645cafeSMatthew Dillon 		case 7:		/* FETCH_DEPENDS */
10724ea2ee4dSMatthew Dillon 			pkg->fetch_deps = strdup_or_null(ptr);
10738e25f19bSMatthew Dillon 			break;
10741645cafeSMatthew Dillon 		case 8:		/* EXTRACT_DEPENDS */
10754ea2ee4dSMatthew Dillon 			pkg->ext_deps = strdup_or_null(ptr);
10768e25f19bSMatthew Dillon 			break;
10771645cafeSMatthew Dillon 		case 9:		/* PATCH_DEPENDS */
10784ea2ee4dSMatthew Dillon 			pkg->patch_deps = strdup_or_null(ptr);
10798e25f19bSMatthew Dillon 			break;
10801645cafeSMatthew Dillon 		case 10:	/* BUILD_DEPENDS */
10814ea2ee4dSMatthew Dillon 			pkg->build_deps = strdup_or_null(ptr);
10828e25f19bSMatthew Dillon 			break;
10831645cafeSMatthew Dillon 		case 11:	/* LIB_DEPENDS */
10844ea2ee4dSMatthew Dillon 			pkg->lib_deps = strdup_or_null(ptr);
10858e25f19bSMatthew Dillon 			break;
10861645cafeSMatthew Dillon 		case 12:	/* RUN_DEPENDS */
10874ea2ee4dSMatthew Dillon 			pkg->run_deps = strdup_or_null(ptr);
10888e25f19bSMatthew Dillon 			break;
10891645cafeSMatthew Dillon 		case 13:	/* SELECTED_OPTIONS */
10904ea2ee4dSMatthew Dillon 			pkg->pos_options = strdup_or_null(ptr);
10918e25f19bSMatthew Dillon 			break;
10921645cafeSMatthew Dillon 		case 14:	/* DESELECTED_OPTIONS */
10934ea2ee4dSMatthew Dillon 			pkg->neg_options = strdup_or_null(ptr);
10948e25f19bSMatthew Dillon 			break;
10951645cafeSMatthew Dillon 		case 15:	/* USE_LINUX */
10968e25f19bSMatthew Dillon 			if (ptr[0])
10978e25f19bSMatthew Dillon 				pkg->use_linux = 1;
10988e25f19bSMatthew Dillon 			break;
10991645cafeSMatthew Dillon 		case 16:	/* FLAVORS */
11008e25f19bSMatthew Dillon 			asprintf(&pkg->flavors, "%s", ptr);
11018e25f19bSMatthew Dillon 			break;
1102f4094b20SMatthew Dillon 		case 17:	/* USES */
1103f4094b20SMatthew Dillon 			asprintf(&pkg->uses, "%s", ptr);
1104f4094b20SMatthew Dillon 			if (strstr(pkg->uses, "metaport"))
1105f4094b20SMatthew Dillon 				pkg->flags |= PKGF_META;
1106f4094b20SMatthew Dillon 			break;
11078e25f19bSMatthew Dillon 		default:
11088e25f19bSMatthew Dillon 			printf("EXTRA LINE: %s\n", ptr);
11098e25f19bSMatthew Dillon 			break;
11108e25f19bSMatthew Dillon 		}
11118e25f19bSMatthew Dillon 		++line;
11128e25f19bSMatthew Dillon 	}
11138e25f19bSMatthew Dillon 	if (line == 1) {
11148e25f19bSMatthew Dillon 		printf("DPort not found: %s/%s\n", bulk->s1, bulk->s2);
11158e25f19bSMatthew Dillon 		pkg->flags |= PKGF_NOTFOUND;
1116f4094b20SMatthew Dillon 	} else if (line != 17 + 1) {
11178e25f19bSMatthew Dillon 		printf("DPort corrupt: %s/%s\n", bulk->s1, bulk->s2);
11188e25f19bSMatthew Dillon 		pkg->flags |= PKGF_CORRUPT;
11198e25f19bSMatthew Dillon 	}
11206fd67931SMatthew Dillon 	if (dexec_close(fp, pid)) {
11216fd67931SMatthew Dillon 		printf("make -V* command for %s/%s failed\n",
11226fd67931SMatthew Dillon 			bulk->s1, bulk->s2);
11236fd67931SMatthew Dillon 		pkg->flags |= PKGF_CORRUPT;
11246fd67931SMatthew Dillon 	}
11258e25f19bSMatthew Dillon 	ddassert(bulk->s1);
11268e25f19bSMatthew Dillon 
11278e25f19bSMatthew Dillon 	/*
1128710838f7SMatthew Dillon 	 * DEBUGSTOP mode
1129710838f7SMatthew Dillon 	 */
1130710838f7SMatthew Dillon 	if (bulk->s4 && bulk->s4[0] == 'd')
1131710838f7SMatthew Dillon 		pkg->flags |= PKGF_DEBUGSTOP;
1132710838f7SMatthew Dillon 
1133710838f7SMatthew Dillon 	/*
113477ac77e7SMatthew Dillon 	 * Mark as a dummy node, the front-end will iterate the flavors
113577ac77e7SMatthew Dillon 	 * and create sub-nodes for us.
11368e25f19bSMatthew Dillon 	 *
113777ac77e7SMatthew Dillon 	 * Get rid of elements returned that are for the first flavor.
113877ac77e7SMatthew Dillon 	 * We are creating a dummy node here, not the node for the first
113977ac77e7SMatthew Dillon 	 * flavor.
11408e25f19bSMatthew Dillon 	 */
114177ac77e7SMatthew Dillon 	if (flavor == NULL && pkg->flavors && pkg->flavors[0]) {
11428e25f19bSMatthew Dillon 		pkg->flags |= PKGF_DUMMY;
11438e25f19bSMatthew Dillon 		freestrp(&pkg->fetch_deps);
11448e25f19bSMatthew Dillon 		freestrp(&pkg->ext_deps);
11458e25f19bSMatthew Dillon 		freestrp(&pkg->patch_deps);
11468e25f19bSMatthew Dillon 		freestrp(&pkg->build_deps);
11478e25f19bSMatthew Dillon 		freestrp(&pkg->lib_deps);
11488e25f19bSMatthew Dillon 		freestrp(&pkg->run_deps);
11498e25f19bSMatthew Dillon 		freestrp(&pkg->pkgfile);
11508e25f19bSMatthew Dillon 	}
11518e25f19bSMatthew Dillon 
11528e25f19bSMatthew Dillon 	/*
1153b6bd007bSMatthew Dillon 	 * Checksum the port directory tree.  This just rollsup crcs of the
1154b6bd007bSMatthew Dillon 	 * path names and a few stat fields (mtime, size) in order to detect
1155b6bd007bSMatthew Dillon 	 * if any modification has been made to the port.
1156b6bd007bSMatthew Dillon 	 */
1157b6bd007bSMatthew Dillon 	pkg->crc32 = crcDirTree(portpath);
1158b6bd007bSMatthew Dillon 
1159b6bd007bSMatthew Dillon 	/*
116077ac77e7SMatthew Dillon 	 * Only one pkg is put on the return list now.  This code no
116177ac77e7SMatthew Dillon 	 * longer creates pseudo-nodes for flavors (the frontend requests
116277ac77e7SMatthew Dillon 	 * each flavor instead).
11638e25f19bSMatthew Dillon 	 */
116477ac77e7SMatthew Dillon 	bulk->list = pkg;
1165b6bd007bSMatthew Dillon 	free(portpath);
11668e25f19bSMatthew Dillon }
11678e25f19bSMatthew Dillon 
11688e25f19bSMatthew Dillon /*
11698e25f19bSMatthew Dillon  * Query the package (at least to make sure it hasn't been truncated)
11708e25f19bSMatthew Dillon  * and mark it as PACKAGED if found.
11718e25f19bSMatthew Dillon  *
1172753e4c44SMatthew Dillon  * This is a pre-req prior to doing builds, so we cannot assume that
1173753e4c44SMatthew Dillon  * the template has its pkg-static binary yet.
1174753e4c44SMatthew Dillon  *
11758e25f19bSMatthew Dillon  * Threaded function
11768e25f19bSMatthew Dillon  */
11778e25f19bSMatthew Dillon static void
childGetBinaryDistInfo(bulk_t * bulk)11788e25f19bSMatthew Dillon childGetBinaryDistInfo(bulk_t *bulk)
11798e25f19bSMatthew Dillon {
11808e25f19bSMatthew Dillon 	char *ptr;
11818e25f19bSMatthew Dillon 	FILE *fp;
11828e25f19bSMatthew Dillon 	size_t len;
11838e25f19bSMatthew Dillon 	pkg_t *pkg;
11846fd67931SMatthew Dillon 	const char *cav[MAXCAC];
11856fd67931SMatthew Dillon 	char *repopath;
11866fd67931SMatthew Dillon 	char buf[1024];
11876fd67931SMatthew Dillon 	pid_t pid;
11886fd67931SMatthew Dillon 	int cac;
1189dc46751bSMatthew Dillon 	int deleteme;
11908e25f19bSMatthew Dillon 
11916fd67931SMatthew Dillon 	asprintf(&repopath, "%s/%s", RepositoryPath, bulk->s1);
11926fd67931SMatthew Dillon 
11936fd67931SMatthew Dillon 	cac = 0;
11946fd67931SMatthew Dillon 	cav[cac++] = PKG_BINARY;
11956fd67931SMatthew Dillon 	cav[cac++] = "query";
11966fd67931SMatthew Dillon 	cav[cac++] = "-F";
11976fd67931SMatthew Dillon 	cav[cac++] = repopath;
11986fd67931SMatthew Dillon 	cav[cac++] = "%n-%v";
11996fd67931SMatthew Dillon 
1200f9d29536SMatthew Dillon 	fp = dexec_open(NULL, cav, cac, &pid, NULL, 1, 0);
1201dc46751bSMatthew Dillon 	deleteme = DeleteObsoletePkgs;
12026fd67931SMatthew Dillon 
12038e25f19bSMatthew Dillon 	while ((ptr = fgetln(fp, &len)) != NULL) {
12048e25f19bSMatthew Dillon 		if (len == 0 || ptr[len-1] != '\n')
12058e25f19bSMatthew Dillon 			continue;
12068e25f19bSMatthew Dillon 		ptr[len-1] = 0;
12078e25f19bSMatthew Dillon 
1208753e4c44SMatthew Dillon 		/*
1209753e4c44SMatthew Dillon 		 * As of pkg 1.17 the binary dist files use a .pkg suffix
1210753e4c44SMatthew Dillon 		 * regardless of the compression format, so always check
1211753e4c44SMatthew Dillon 		 * those.
1212753e4c44SMatthew Dillon 		 */
1213753e4c44SMatthew Dillon 		snprintf(buf, sizeof(buf), "%s%s", ptr, ".pkg");
12148e25f19bSMatthew Dillon 		pkg = pkg_find(buf);
1215753e4c44SMatthew Dillon 		if (pkg == NULL) {
1216753e4c44SMatthew Dillon 			snprintf(buf, sizeof(buf), "%s%s", ptr, UsePkgSufx);
1217753e4c44SMatthew Dillon 			pkg = pkg_find(buf);
1218753e4c44SMatthew Dillon 		}
12198d9409b8SMatthew Dillon 		if (pkg) {
1220325ef124SMatthew Dillon 			if (FetchOnlyOpt) {
1221325ef124SMatthew Dillon 			    ddprintf(0, "Note: Package is already packaged, ignore for -f: %s\n", ptr);
1222325ef124SMatthew Dillon 			    deleteme = 0;
1223325ef124SMatthew Dillon 			} else {
12248e25f19bSMatthew Dillon 			    pkg->flags |= PKGF_PACKAGED;
1225dc46751bSMatthew Dillon 			    deleteme = 0;
1226325ef124SMatthew Dillon 			}
12278d9409b8SMatthew Dillon 		} else {
12288e25f19bSMatthew Dillon 			ddprintf(0, "Note: package scan, not in list, "
1229753e4c44SMatthew Dillon 				    "skipping %s{.%s,.pkg}\n", ptr, UsePkgSufx);
12308e25f19bSMatthew Dillon 		}
12318d9409b8SMatthew Dillon 	}
12326fd67931SMatthew Dillon 	if (dexec_close(fp, pid)) {
12336fd67931SMatthew Dillon 		printf("pkg query command failed for %s\n", repopath);
12346fd67931SMatthew Dillon 	}
1235dc46751bSMatthew Dillon 	if (deleteme) {
1236dc46751bSMatthew Dillon 		dlog(DLOG_ALL | DLOG_STDOUT,
1237dc46751bSMatthew Dillon 		     "Deleting obsolete package %s\n", repopath);
1238dc46751bSMatthew Dillon 		remove(repopath);
1239dc46751bSMatthew Dillon 	}
12406fd67931SMatthew Dillon 	free(repopath);
12418e25f19bSMatthew Dillon }
12428e25f19bSMatthew Dillon 
1243a67bf8dbSMatthew Dillon static void
childOptimizeEnv(bulk_t * bulk)1244a67bf8dbSMatthew Dillon childOptimizeEnv(bulk_t *bulk)
1245a67bf8dbSMatthew Dillon {
1246a67bf8dbSMatthew Dillon 	char *portpath;
12475d0718a8SMatthew Dillon 	char *localbase;
1248a67bf8dbSMatthew Dillon 	char *ptr;
1249a67bf8dbSMatthew Dillon 	FILE *fp;
1250a67bf8dbSMatthew Dillon 	int line;
1251a67bf8dbSMatthew Dillon 	size_t len;
1252a67bf8dbSMatthew Dillon 	const char *cav[MAXCAC];
1253a67bf8dbSMatthew Dillon 	pid_t pid;
1254a67bf8dbSMatthew Dillon 	int cac;
1255a67bf8dbSMatthew Dillon 
1256a67bf8dbSMatthew Dillon 	asprintf(&portpath, "%s/%s/%s", DPortsPath, bulk->s1, bulk->s2);
1257a67bf8dbSMatthew Dillon 
12585d0718a8SMatthew Dillon 	/*
12595d0718a8SMatthew Dillon 	 * Prevent postgresql, mysql, and other package Makefile tests
12605d0718a8SMatthew Dillon 	 * from accessing the host system's /usr/local by setting LOCALBASE
12615d0718a8SMatthew Dillon 	 * to an empty directory.
12625d0718a8SMatthew Dillon 	 */
12635d0718a8SMatthew Dillon 	asprintf(&localbase, "LOCALBASE=%s/empty", BuildBase);
12645d0718a8SMatthew Dillon 
1265a67bf8dbSMatthew Dillon 	cac = 0;
1266a67bf8dbSMatthew Dillon 	cav[cac++] = MAKE_BINARY;
1267a67bf8dbSMatthew Dillon 	cav[cac++] = "-C";
1268a67bf8dbSMatthew Dillon 	cav[cac++] = portpath;
12695d0718a8SMatthew Dillon 	cav[cac++] = localbase;
1270a67bf8dbSMatthew Dillon 	cav[cac++] = "-V_PERL5_FROM_BIN";
1271a67bf8dbSMatthew Dillon 
1272f9d29536SMatthew Dillon 	fp = dexec_open(portpath + strlen(DPortsPath) + 1, cav, cac,
1273f9d29536SMatthew Dillon 			&pid, NULL, 1, 1);
12745d0718a8SMatthew Dillon 	free(localbase);
1275a67bf8dbSMatthew Dillon 	free(portpath);
1276a67bf8dbSMatthew Dillon 
1277a67bf8dbSMatthew Dillon 	line = 1;
1278a67bf8dbSMatthew Dillon 	while ((ptr = fgetln(fp, &len)) != NULL) {
1279a67bf8dbSMatthew Dillon 		if (len == 0 || ptr[len-1] != '\n') {
1280a67bf8dbSMatthew Dillon 			dfatal("Bad package info for %s/%s response line %d",
1281a67bf8dbSMatthew Dillon 			       bulk->s1, bulk->s2, line);
1282a67bf8dbSMatthew Dillon 		}
1283a67bf8dbSMatthew Dillon 		ptr[--len] = 0;
1284a67bf8dbSMatthew Dillon 
1285a67bf8dbSMatthew Dillon 		switch(line) {
1286a67bf8dbSMatthew Dillon 		case 1:		/* _PERL5_FROM_BIN */
1287a67bf8dbSMatthew Dillon 			addbuildenv("_PERL5_FROM_BIN", ptr, BENV_ENVIRONMENT);
1288a67bf8dbSMatthew Dillon 			break;
1289a67bf8dbSMatthew Dillon 		default:
1290a67bf8dbSMatthew Dillon 			printf("childOptimizeEnv: EXTRA LINE: %s\n", ptr);
1291a67bf8dbSMatthew Dillon 			break;
1292a67bf8dbSMatthew Dillon 		}
1293a67bf8dbSMatthew Dillon 		++line;
1294a67bf8dbSMatthew Dillon 	}
1295a67bf8dbSMatthew Dillon 	if (line == 1) {
1296a67bf8dbSMatthew Dillon 		printf("DPort not found: %s/%s\n", bulk->s1, bulk->s2);
1297a67bf8dbSMatthew Dillon 	} else if (line != 1 + 1) {
1298a67bf8dbSMatthew Dillon 		printf("DPort corrupt: %s/%s\n", bulk->s1, bulk->s2);
1299a67bf8dbSMatthew Dillon 	}
1300a67bf8dbSMatthew Dillon 	if (dexec_close(fp, pid)) {
1301a67bf8dbSMatthew Dillon 		printf("childOptimizeEnv() failed\n");
1302a67bf8dbSMatthew Dillon 	}
1303a67bf8dbSMatthew Dillon }
1304a67bf8dbSMatthew Dillon 
13058e25f19bSMatthew Dillon static int
scan_and_queue_dir(const char * path,const char * level1,int level)13068e25f19bSMatthew Dillon scan_and_queue_dir(const char *path, const char *level1, int level)
13078e25f19bSMatthew Dillon {
13088e25f19bSMatthew Dillon 	DIR *dir;
13098e25f19bSMatthew Dillon 	char *s1;
13108e25f19bSMatthew Dillon 	char *s2;
13118e25f19bSMatthew Dillon 	struct dirent *den;
13128e25f19bSMatthew Dillon 	struct stat st;
13138e25f19bSMatthew Dillon 	int count = 0;
13148e25f19bSMatthew Dillon 
13158e25f19bSMatthew Dillon 	dir = opendir(path);
13168e25f19bSMatthew Dillon 	dassert(dir, "Cannot open dports path \"%s\"", path);
13178e25f19bSMatthew Dillon 
13188e25f19bSMatthew Dillon 	while ((den = readdir(dir)) != NULL) {
13198e25f19bSMatthew Dillon 		if (den->d_namlen == 1 && den->d_name[0] == '.')
13208e25f19bSMatthew Dillon 			continue;
13218e25f19bSMatthew Dillon 		if (den->d_namlen == 2 &&
13228e25f19bSMatthew Dillon 		    den->d_name[0] == '.' && den->d_name[1] == '.')
13238e25f19bSMatthew Dillon 			continue;
13248e25f19bSMatthew Dillon 		asprintf(&s1, "%s/%s", path, den->d_name);
13258e25f19bSMatthew Dillon 		if (lstat(s1, &st) < 0 || !S_ISDIR(st.st_mode)) {
13268e25f19bSMatthew Dillon 			free(s1);
13278e25f19bSMatthew Dillon 			continue;
13288e25f19bSMatthew Dillon 		}
13298e25f19bSMatthew Dillon 		if (level == 1) {
13308e25f19bSMatthew Dillon 			count += scan_and_queue_dir(s1, den->d_name, 2);
13318e25f19bSMatthew Dillon 			free(s1);
13328e25f19bSMatthew Dillon 			continue;
13338e25f19bSMatthew Dillon 		}
13348e25f19bSMatthew Dillon 		asprintf(&s2, "%s/Makefile", s1);
13358e25f19bSMatthew Dillon 		if (lstat(s2, &st) == 0) {
13368e25f19bSMatthew Dillon 			queuebulk(level1, den->d_name, NULL, NULL);
13378e25f19bSMatthew Dillon 			++count;
13388e25f19bSMatthew Dillon 		}
13398e25f19bSMatthew Dillon 		free(s1);
13408e25f19bSMatthew Dillon 		free(s2);
13418e25f19bSMatthew Dillon 	}
13428e25f19bSMatthew Dillon 	closedir(dir);
13438e25f19bSMatthew Dillon 
13448e25f19bSMatthew Dillon 	return count;
13458e25f19bSMatthew Dillon }
13468e25f19bSMatthew Dillon 
13478e25f19bSMatthew Dillon static int
scan_binary_repo(const char * path)13488e25f19bSMatthew Dillon scan_binary_repo(const char *path)
13498e25f19bSMatthew Dillon {
13508e25f19bSMatthew Dillon 	DIR *dir;
13518e25f19bSMatthew Dillon 	struct dirent *den;
13528e25f19bSMatthew Dillon 	int count;
13538e25f19bSMatthew Dillon 
13548e25f19bSMatthew Dillon 	count = 0;
13558e25f19bSMatthew Dillon 	dir = opendir(path);
13568e25f19bSMatthew Dillon 	dassert(dir, "Cannot open repository path \"%s\"", path);
13578e25f19bSMatthew Dillon 
13588d9409b8SMatthew Dillon 	/*
13598d9409b8SMatthew Dillon 	 * NOTE: Test includes the '.' in the suffix.
13608d9409b8SMatthew Dillon 	 */
13618e25f19bSMatthew Dillon 	while ((den = readdir(dir)) != NULL) {
13628d6cd058SMatthew Dillon 		const char *suffix;
13638d6cd058SMatthew Dillon 
13648d6cd058SMatthew Dillon 		suffix = strrchr(den->d_name, '.');
13658d6cd058SMatthew Dillon 		if (suffix && suffix != den->d_name &&
1366753e4c44SMatthew Dillon 		    strcmp(suffix, UsePkgSufx) == 0)
1367753e4c44SMatthew Dillon 		{
1368753e4c44SMatthew Dillon 			queuebulk(den->d_name, NULL, NULL, NULL);
1369753e4c44SMatthew Dillon 			++count;
1370753e4c44SMatthew Dillon 		}
1371753e4c44SMatthew Dillon 
1372753e4c44SMatthew Dillon 		/*
1373753e4c44SMatthew Dillon 		 * As of 1.17, pkg generates .pkg files.
1374753e4c44SMatthew Dillon 		 */
1375753e4c44SMatthew Dillon 		if (suffix && suffix != den->d_name &&
1376753e4c44SMatthew Dillon 		    strcmp(suffix, ".pkg") == 0)
1377753e4c44SMatthew Dillon 		{
13788e25f19bSMatthew Dillon 			queuebulk(den->d_name, NULL, NULL, NULL);
13798e25f19bSMatthew Dillon 			++count;
13808e25f19bSMatthew Dillon 		}
13818e25f19bSMatthew Dillon 	}
13828e25f19bSMatthew Dillon 	closedir(dir);
13838e25f19bSMatthew Dillon 
13848e25f19bSMatthew Dillon 	return count;
13858e25f19bSMatthew Dillon }
13868e25f19bSMatthew Dillon 
13878e25f19bSMatthew Dillon #if 0
13888e25f19bSMatthew Dillon static void
13898e25f19bSMatthew Dillon pkgfree(pkg_t *pkg)
13908e25f19bSMatthew Dillon {
13918e25f19bSMatthew Dillon 	freestrp(&pkg->portdir);
13928e25f19bSMatthew Dillon 	freestrp(&pkg->version);
13938e25f19bSMatthew Dillon 	freestrp(&pkg->pkgfile);
13948e25f19bSMatthew Dillon 	freestrp(&pkg->ignore);
13958e25f19bSMatthew Dillon 	freestrp(&pkg->fetch_deps);
13968e25f19bSMatthew Dillon 	freestrp(&pkg->ext_deps);
13978e25f19bSMatthew Dillon 	freestrp(&pkg->patch_deps);
13988e25f19bSMatthew Dillon 	freestrp(&pkg->build_deps);
13998e25f19bSMatthew Dillon 	freestrp(&pkg->lib_deps);
14008e25f19bSMatthew Dillon 	freestrp(&pkg->run_deps);
14018e25f19bSMatthew Dillon 	freestrp(&pkg->pos_options);
14028e25f19bSMatthew Dillon 	freestrp(&pkg->neg_options);
14038e25f19bSMatthew Dillon 	freestrp(&pkg->flavors);
14048e25f19bSMatthew Dillon 	free(pkg);
14058e25f19bSMatthew Dillon }
14068e25f19bSMatthew Dillon #endif
1407