xref: /dflybsd-src/usr.bin/dsynth/dsynth.c (revision ab4c55c707dde5384d8a233485cc87b3ea249687)
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 
40c819d181SMatthew Dillon static int CheckAddReExec(int lkfd);
41c819d181SMatthew Dillon static void DoAddReExec(int lkfd, int ac, char **oldav);
428ec23ca1SMatthew Dillon static void DoInit(void);
438e25f19bSMatthew Dillon static void usage(int ecode) __dead2;
448e25f19bSMatthew Dillon 
452c5f241eSMatthew Dillon int ForceOpt;
46b6bd007bSMatthew Dillon int OverridePkgDeleteOpt;
47325ef124SMatthew Dillon int FetchOnlyOpt;
481645cafeSMatthew Dillon int YesOpt;
498e25f19bSMatthew Dillon int DebugOpt;
50927e4e3eSMatthew Dillon int MaskProbeAbort;
51a574cbf0SMatthew Dillon int ColorOpt = 1;
529c4c701fSMatthew Dillon int NullStdinOpt = 1;
53b8ab713eSMatthew Dillon int SlowStartOpt = -1;
542b3f93eaSMatthew Dillon int CapabilityRestrictions;
557f0eca56SMatthew Dillon long PkgDepMemoryTarget;
564ad2f7b8SMatthew Dillon long PkgDepScaleTarget = 100;	/* 1.00 */
578e25f19bSMatthew Dillon char *DSynthExecPath;
589e1d0b12SMatthew Dillon char *ProfileOverrideOpt;
596d1478d9SMatthew Dillon int NiceOpt = 10;
608e25f19bSMatthew Dillon 
618e25f19bSMatthew Dillon int
main(int ac,char ** av)628e25f19bSMatthew Dillon main(int ac, char **av)
638e25f19bSMatthew Dillon {
64c819d181SMatthew Dillon 	char *lkpath;
658e25f19bSMatthew Dillon 	pkg_t *pkgs;
66c819d181SMatthew Dillon 	int lkfd;
678e25f19bSMatthew Dillon 	int isworker;
688e25f19bSMatthew Dillon 	int c;
69a574cbf0SMatthew Dillon 	int sopt;
70c819d181SMatthew Dillon 	int doadds;
718e25f19bSMatthew Dillon 
722b3f93eaSMatthew Dillon #if defined(__DragonFly__)
732b3f93eaSMatthew Dillon 	/*
742b3f93eaSMatthew Dillon 	 * The system is expected to have capabilities
752b3f93eaSMatthew Dillon 	 */
762b3f93eaSMatthew Dillon 	{
772b3f93eaSMatthew Dillon 		size_t len = sizeof(CapabilityRestrictions);
782b3f93eaSMatthew Dillon 		sysctlbyname("kern.caps_available",
792b3f93eaSMatthew Dillon 			     &CapabilityRestrictions, &len, NULL, 0);
802b3f93eaSMatthew Dillon 		if (CapabilityRestrictions == 0)
812b3f93eaSMatthew Dillon 			fprintf(stderr, "caps restrictions unavailable\n");
822b3f93eaSMatthew Dillon 	}
832b3f93eaSMatthew Dillon #endif
842b3f93eaSMatthew Dillon 
858e25f19bSMatthew Dillon 	/*
868e25f19bSMatthew Dillon 	 * Get our exec path so we can self-exec clean WORKER
878e25f19bSMatthew Dillon 	 * processes.
888e25f19bSMatthew Dillon 	 */
898e25f19bSMatthew Dillon 	{
908e25f19bSMatthew Dillon 		size_t len;
918e25f19bSMatthew Dillon 		const int name[] = {
928e25f19bSMatthew Dillon 			CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1,
938e25f19bSMatthew Dillon 		};
948e25f19bSMatthew Dillon 		if (sysctl(name, 4, NULL, &len, NULL, 0) < 0)
958e25f19bSMatthew Dillon 			dfatal_errno("Cannot get binary path");
968e25f19bSMatthew Dillon 		DSynthExecPath = malloc(len + 1);
978e25f19bSMatthew Dillon 		if (sysctl(name, 4, DSynthExecPath, &len, NULL, 0) < 0)
988e25f19bSMatthew Dillon 			dfatal_errno("Cannot get binary path");
998e25f19bSMatthew Dillon 		DSynthExecPath[len] = 0;
1008e25f19bSMatthew Dillon 	}
1018e25f19bSMatthew Dillon 
1028e25f19bSMatthew Dillon 	/*
1039e1d0b12SMatthew Dillon 	 * Override profile in dsynth.ini (can be further overridden
1049e1d0b12SMatthew Dillon 	 * with the -p profile option).
1059e1d0b12SMatthew Dillon 	 */
1069e1d0b12SMatthew Dillon 	ProfileOverrideOpt = getenv("DSYNTH_PROFILE");
1079e1d0b12SMatthew Dillon 
1089e1d0b12SMatthew Dillon 	/*
1098e25f19bSMatthew Dillon 	 * Process options and make sure the directive is present
1108e25f19bSMatthew Dillon 	 */
111a574cbf0SMatthew Dillon 	sopt = 0;
112a361ab31SMatthew Dillon 	while ((c = getopt(ac, av, "dfhm:p:vxys:C:DPM:NS")) != -1) {
1138e25f19bSMatthew Dillon 		switch(c) {
1142c5f241eSMatthew Dillon 		case 'f':
1152c5f241eSMatthew Dillon 			++ForceOpt;
1162c5f241eSMatthew Dillon 			break;
117b6bd007bSMatthew Dillon 		case 'x':
118b6bd007bSMatthew Dillon 			++OverridePkgDeleteOpt;
119b6bd007bSMatthew Dillon 			break;
1201645cafeSMatthew Dillon 		case 'y':
1211645cafeSMatthew Dillon 			++YesOpt;
1221645cafeSMatthew Dillon 			break;
123a361ab31SMatthew Dillon 		case 'C':
124a361ab31SMatthew Dillon 			ConfigBase1 = optarg;
125a361ab31SMatthew Dillon 			ConfigBase2 = NULL;
126a361ab31SMatthew Dillon 			break;
127a67bf8dbSMatthew Dillon 		case 'D':
128a67bf8dbSMatthew Dillon 			WorkerProcFlags |= WORKER_PROC_DEVELOPER;
129a67bf8dbSMatthew Dillon 			break;
13032f62172SMatthew Dillon 		case 'P':
13132f62172SMatthew Dillon 			WorkerProcFlags |= WORKER_PROC_CHECK_PLIST;
13232f62172SMatthew Dillon 			break;
13354f2fefcSMatthew Dillon 		case 'S':
13454f2fefcSMatthew Dillon 			UseNCurses = 0;
135a574cbf0SMatthew Dillon 			if (++sopt == 2)
136a574cbf0SMatthew Dillon 				ColorOpt = 0;
13754f2fefcSMatthew Dillon 			break;
1386d1478d9SMatthew Dillon 		case 'N':
1396d1478d9SMatthew Dillon 			NiceOpt = 0;
1406d1478d9SMatthew Dillon 			break;
1418e25f19bSMatthew Dillon 		case 'd':
1428e25f19bSMatthew Dillon 			++DebugOpt;
14354f2fefcSMatthew Dillon 			if (DebugOpt >= 2)
1448e25f19bSMatthew Dillon 				UseNCurses = 0;
1458e25f19bSMatthew Dillon 			break;
1468e25f19bSMatthew Dillon 		case 'h':
1478e25f19bSMatthew Dillon 			usage(0);
1488e25f19bSMatthew Dillon 			/* NOT REACHED */
1498e25f19bSMatthew Dillon 			exit(0);
1508e25f19bSMatthew Dillon 		case 'v':
1518e25f19bSMatthew Dillon 			printf("dsynth %s\n", DSYNTH_VERSION);
1528e25f19bSMatthew Dillon 			exit(0);
153f7f25838SMatthew Dillon 		case 's':
154b8ab713eSMatthew Dillon 			/*
155b8ab713eSMatthew Dillon 			 * Start with N jobs, increasing to the configured
156b8ab713eSMatthew Dillon 			 * maximum slowly.  0 to disable (starts with the
157b8ab713eSMatthew Dillon 			 * full count).
158b8ab713eSMatthew Dillon 			 */
159f7f25838SMatthew Dillon 			SlowStartOpt = strtol(optarg, NULL, 0);
160f7f25838SMatthew Dillon 			break;
1617f0eca56SMatthew Dillon 		case 'm':
1627f0eca56SMatthew Dillon 			PkgDepMemoryTarget = strtoul(optarg, NULL, 0);
1637f0eca56SMatthew Dillon 			PkgDepMemoryTarget *= ONEGB;
1647f0eca56SMatthew Dillon 			break;
1654ad2f7b8SMatthew Dillon 		case 'M':
1664ad2f7b8SMatthew Dillon 			PkgDepScaleTarget = strtod(optarg, NULL) * 100;
1674ad2f7b8SMatthew Dillon 			if (PkgDepScaleTarget < 1)
1684ad2f7b8SMatthew Dillon 				PkgDepScaleTarget = 1;
1694ad2f7b8SMatthew Dillon 			if (PkgDepScaleTarget > 9900)
1704ad2f7b8SMatthew Dillon 				PkgDepScaleTarget = 9900;
1714ad2f7b8SMatthew Dillon 			break;
1729e1d0b12SMatthew Dillon 		case 'p':
1739e1d0b12SMatthew Dillon 			ProfileOverrideOpt = optarg;
1749e1d0b12SMatthew Dillon 			break;
1758e25f19bSMatthew Dillon 		default:
1768e25f19bSMatthew Dillon 			fprintf(stderr, "Unknown option: %c\n", c);
1778e25f19bSMatthew Dillon 			usage(2);
1788e25f19bSMatthew Dillon 			/* NOT REACHED */
1798e25f19bSMatthew Dillon 			break;
1808e25f19bSMatthew Dillon 		}
1818e25f19bSMatthew Dillon 	}
1828e25f19bSMatthew Dillon 	ac -= optind;
1838e25f19bSMatthew Dillon 	av += optind;
1848e25f19bSMatthew Dillon 	pkgs = NULL;
1858e25f19bSMatthew Dillon 	if (ac < 1) {
1868e25f19bSMatthew Dillon 		fprintf(stderr, "Missing directive\n");
1878e25f19bSMatthew Dillon 		usage(2);
1888e25f19bSMatthew Dillon 		/* NOT REACHED */
1898e25f19bSMatthew Dillon 	}
1908e25f19bSMatthew Dillon 
191b1224b54SMatthew Dillon 	/*
192b1224b54SMatthew Dillon 	 * Directives which do not require a working configuration
193b1224b54SMatthew Dillon 	 */
1948ec23ca1SMatthew Dillon 	if (strcmp(av[0], "init") == 0) {
1958ec23ca1SMatthew Dillon 		DoInit();
1968ec23ca1SMatthew Dillon 		exit(0);
19753c9b6f3SMatthew Dillon 		/* NOT REACHED */
19853c9b6f3SMatthew Dillon 	}
19953c9b6f3SMatthew Dillon 	if (strcmp(av[0], "help") == 0) {
20053c9b6f3SMatthew Dillon 		usage(0);
20153c9b6f3SMatthew Dillon 		exit(0);
20253c9b6f3SMatthew Dillon 		/* NOT REACHED */
2038ec23ca1SMatthew Dillon 	}
204b1224b54SMatthew Dillon 	if (strcmp(av[0], "version") == 0) {
205b1224b54SMatthew Dillon 		printf("dsynth %s\n", DSYNTH_VERSION);
206b1224b54SMatthew Dillon 		exit(0);
207b1224b54SMatthew Dillon 		/* NOT REACHED */
208b1224b54SMatthew Dillon 	}
2098ec23ca1SMatthew Dillon 
210b1224b54SMatthew Dillon 	/*
211b1224b54SMatthew Dillon 	 * Preconfiguration.
212b1224b54SMatthew Dillon 	 */
2138e25f19bSMatthew Dillon 	if (strcmp(av[0], "WORKER") == 0) {
2148e25f19bSMatthew Dillon 		isworker = 1;
2158e25f19bSMatthew Dillon 	} else {
2168e25f19bSMatthew Dillon 		isworker = 0;
2178e25f19bSMatthew Dillon 	}
2188e25f19bSMatthew Dillon 
2198e25f19bSMatthew Dillon 	signal(SIGPIPE, SIG_IGN);
2208e25f19bSMatthew Dillon 	ParseConfiguration(isworker);
2218e25f19bSMatthew Dillon 
2228e25f19bSMatthew Dillon 	/*
223c819d181SMatthew Dillon 	 * Lock file path (also contains any 'add' directives thrown in
224c819d181SMatthew Dillon 	 * during a build).
225c819d181SMatthew Dillon 	 */
226c819d181SMatthew Dillon 	asprintf(&lkpath, "%s/.lock", BuildBase);
227c819d181SMatthew Dillon 
228c819d181SMatthew Dillon 	/*
2294e6f51fcSMatthew Dillon 	 * Setup some environment for bulk operations (pkglist scan).
23031f2ea22SMatthew Dillon 	 * These are not used by the builder (the builder will replicate
23131f2ea22SMatthew Dillon 	 * all of these).
232bd73b895SMatthew Dillon 	 *
233bd73b895SMatthew Dillon 	 * NOTE: PKG_SUFX - pkg versions older than 1.17
234bd73b895SMatthew Dillon 	 *	 PKG_COMPRESSION_FORMAT - pkg versions >= 1.17
2354e6f51fcSMatthew Dillon 	 */
23631f2ea22SMatthew Dillon 	addbuildenv("PORTSDIR", DPortsPath,
23731f2ea22SMatthew Dillon 		    BENV_ENVIRONMENT | BENV_PKGLIST);
23831f2ea22SMatthew Dillon 	addbuildenv("BATCH", "yes",
23931f2ea22SMatthew Dillon 		    BENV_ENVIRONMENT | BENV_PKGLIST);
240bd73b895SMatthew Dillon 	addbuildenv("PKG_COMPRESSION_FORMAT", UsePkgSufx,
241bd73b895SMatthew Dillon 		    BENV_ENVIRONMENT | BENV_PKGLIST);
242483dbac9SMatthew Dillon 	addbuildenv("PKG_SUFX", UsePkgSufx,
24331f2ea22SMatthew Dillon 		    BENV_ENVIRONMENT | BENV_PKGLIST);
24431f2ea22SMatthew Dillon 	addbuildenv("PACKAGE_BUILDING", "yes",
24531f2ea22SMatthew Dillon 		    BENV_ENVIRONMENT | BENV_PKGLIST);
2462478c21aSMatthew Dillon 	addbuildenv("ARCH", ArchitectureName,
2472478c21aSMatthew Dillon 		    BENV_ENVIRONMENT | BENV_PKGLIST);
2484e6f51fcSMatthew Dillon 
249a67bf8dbSMatthew Dillon #if 0
250a67bf8dbSMatthew Dillon 	/*
251a67bf8dbSMatthew Dillon 	 *
252a67bf8dbSMatthew Dillon 	 */
25331f2ea22SMatthew Dillon 	addbuildenv("OSTYPE", OperatingSystemName,
25431f2ea22SMatthew Dillon 		    BENV_ENVIRONMENT | BENV_PKGLIST);
25531f2ea22SMatthew Dillon 	addbuildenv("MACHTYPE", MachineName,
25631f2ea22SMatthew Dillon 		    BENV_ENVIRONMENT | BENV_PKGLIST);
257a67bf8dbSMatthew Dillon #endif
258b8ab713eSMatthew Dillon 	/*
259b8ab713eSMatthew Dillon 	 * SlowStart auto adjust.  We nominally start with 1 job and increase
260b8ab713eSMatthew Dillon 	 * it to the maximum every 5 seconds to give various dynamic management
261b8ab713eSMatthew Dillon 	 * parameters time to stabilize.
262b8ab713eSMatthew Dillon 	 *
263b8ab713eSMatthew Dillon 	 * This can take a while on a many-core box with a high jobs setting,
264b8ab713eSMatthew Dillon 	 * so increase the initial jobs in such cases.
265b8ab713eSMatthew Dillon 	 */
266b8ab713eSMatthew Dillon 	if (SlowStartOpt > MaxWorkers)
267b8ab713eSMatthew Dillon 		SlowStartOpt = MaxWorkers;
268b8ab713eSMatthew Dillon 	if (SlowStartOpt < 0) {
269b8ab713eSMatthew Dillon 		if (MaxWorkers < 16)
270b8ab713eSMatthew Dillon 			SlowStartOpt = 1;
271b8ab713eSMatthew Dillon 		else
272b8ab713eSMatthew Dillon 			SlowStartOpt = MaxWorkers / 4;
273b8ab713eSMatthew Dillon 	}
274a67bf8dbSMatthew Dillon 
2754e6f51fcSMatthew Dillon 	/*
2768e25f19bSMatthew Dillon 	 * Special directive for when dsynth execs itself to manage
2778e25f19bSMatthew Dillon 	 * a worker chroot.
2788e25f19bSMatthew Dillon 	 */
2798e25f19bSMatthew Dillon 	if (isworker) {
2808e25f19bSMatthew Dillon 		WorkerProcess(ac, av);
2818e25f19bSMatthew Dillon 		exit(0);
2828e25f19bSMatthew Dillon 	}
2838e25f19bSMatthew Dillon 
2849e1d0b12SMatthew Dillon 	/*
285b1224b54SMatthew Dillon 	 * Build initialization and directive handling
286b1224b54SMatthew Dillon 	 */
287b1224b54SMatthew Dillon 	DoInitBuild(-1);
288b1224b54SMatthew Dillon 
289b1224b54SMatthew Dillon 	/*
290b1224b54SMatthew Dillon 	 * Directives that use the configuration but are not interlocked
291b1224b54SMatthew Dillon 	 * against a running dsynth.
292b1224b54SMatthew Dillon 	 */
293b1224b54SMatthew Dillon 	if (strcmp(av[0], "monitor") == 0) {
294b1224b54SMatthew Dillon 		char *spath;
295b1224b54SMatthew Dillon 		char *lpath;
296b1224b54SMatthew Dillon 
297b1224b54SMatthew Dillon 		if (ac == 1) {
298b1224b54SMatthew Dillon 			asprintf(&spath, "%s/%s", StatsBase, STATS_FILE);
299b1224b54SMatthew Dillon 			asprintf(&lpath, "%s/%s", StatsBase, STATS_LOCKFILE);
300b1224b54SMatthew Dillon 			MonitorDirective(spath, lpath);
301b1224b54SMatthew Dillon 			free(spath);
302b1224b54SMatthew Dillon 			free(lpath);
303b1224b54SMatthew Dillon 		} else {
304b1224b54SMatthew Dillon 			MonitorDirective(av[1], NULL);
305b1224b54SMatthew Dillon 		}
306b1224b54SMatthew Dillon 		exit(0);
307b1224b54SMatthew Dillon 		/* NOT REACHED */
308c819d181SMatthew Dillon 	} else if (strcmp(av[0], "add") == 0) {
309c819d181SMatthew Dillon 		char *buf;
310c819d181SMatthew Dillon 		int fd;
311c819d181SMatthew Dillon 		int i;
312c819d181SMatthew Dillon 
313c819d181SMatthew Dillon 		/*
314c819d181SMatthew Dillon 		 * The lock check is a bit racey XXX
315c819d181SMatthew Dillon 		 */
316c819d181SMatthew Dillon 		fd = open(lkpath, O_RDWR | O_CREAT | O_APPEND, 0644);
317c819d181SMatthew Dillon 		if (flock(fd, LOCK_EX | LOCK_NB) == 0) {
318c819d181SMatthew Dillon 			dfatal("No dsynth running to add ports to");
319c819d181SMatthew Dillon 			flock(fd, LOCK_UN);
320c819d181SMatthew Dillon 		}
321c819d181SMatthew Dillon 		for (i = 1; i < ac; ++i) {
322c819d181SMatthew Dillon 			asprintf(&buf, "%s\n", av[i]);
323c819d181SMatthew Dillon 			write(fd, buf, strlen(buf));
324c819d181SMatthew Dillon 			printf("added to run: %s\n", av[i]);
325c819d181SMatthew Dillon 		}
326c819d181SMatthew Dillon 		close(fd);
327c819d181SMatthew Dillon 		exit(0);
328b1224b54SMatthew Dillon 	}
329b1224b54SMatthew Dillon 
330b1224b54SMatthew Dillon 	/*
3319e1d0b12SMatthew Dillon 	 * Front-end exec (not a WORKER exec), normal startup.  We have
3329e1d0b12SMatthew Dillon 	 * the configuration so the first thing we need to do is check
3339e1d0b12SMatthew Dillon 	 * the lock file.
3349e1d0b12SMatthew Dillon 	 */
335c819d181SMatthew Dillon 	lkfd = open(lkpath, O_RDWR | O_CREAT | O_CLOEXEC, 0644);
336c819d181SMatthew Dillon 	if (lkfd < 0)
3379e1d0b12SMatthew Dillon 		dfatal_errno("Unable to create %s", lkpath);
338c819d181SMatthew Dillon 	if (flock(lkfd, LOCK_EX | LOCK_NB) < 0) {
3399e1d0b12SMatthew Dillon 		dfatal("Another dsynth is using %s, exiting",
3409e1d0b12SMatthew Dillon 		       BuildBase);
3419e1d0b12SMatthew Dillon 	}
342c819d181SMatthew Dillon 
343c819d181SMatthew Dillon 	/*
344c819d181SMatthew Dillon 	 * Starting a new run cleans out any prior add directives
345c819d181SMatthew Dillon 	 * that may have been pending.
346c819d181SMatthew Dillon 	 */
347c819d181SMatthew Dillon 	ftruncate(lkfd, 0);
3489e1d0b12SMatthew Dillon 	/* leave descriptor open */
349c819d181SMatthew Dillon 
350c819d181SMatthew Dillon 	doadds = 0;
3519e1d0b12SMatthew Dillon 
3528e25f19bSMatthew Dillon 	if (strcmp(av[0], "debug") == 0) {
35387017ac4SMatthew Dillon 		DoCleanBuild(1);
354a67bf8dbSMatthew Dillon 		OptimizeEnv();
355710838f7SMatthew Dillon 		pkgs = ParsePackageList(ac - 1, av + 1, 1);
3569bb2c592SMatthew Dillon 		RemovePackages(pkgs);
3578ec23ca1SMatthew Dillon 		DoBuild(pkgs);
358c819d181SMatthew Dillon 		doadds = 1;
3598ec23ca1SMatthew Dillon 	} else if (strcmp(av[0], "status") == 0) {
360a67bf8dbSMatthew Dillon 		OptimizeEnv();
3618e25f19bSMatthew Dillon 		if (ac - 1)
362710838f7SMatthew Dillon 			pkgs = ParsePackageList(ac - 1, av + 1, 0);
3638e25f19bSMatthew Dillon 		else
3648e25f19bSMatthew Dillon 			pkgs = GetLocalPackageList();
3651645cafeSMatthew Dillon 		DoStatus(pkgs);
3668e25f19bSMatthew Dillon 	} else if (strcmp(av[0], "cleanup") == 0) {
36787017ac4SMatthew Dillon 		DoCleanBuild(0);
3688e25f19bSMatthew Dillon 	} else if (strcmp(av[0], "configure") == 0) {
36987017ac4SMatthew Dillon 		DoCleanBuild(0);
3708e25f19bSMatthew Dillon 		DoConfigure();
371325ef124SMatthew Dillon 	} else if (strcmp(av[0], "fetch-only") == 0) {
372325ef124SMatthew Dillon 		if (SlowStartOpt == -1)
373325ef124SMatthew Dillon 			SlowStartOpt = 999;
374325ef124SMatthew Dillon 		if (PkgDepScaleTarget == 100)
375325ef124SMatthew Dillon 			PkgDepScaleTarget = 999;
376325ef124SMatthew Dillon 		++FetchOnlyOpt;
377325ef124SMatthew Dillon 		++YesOpt;
378325ef124SMatthew Dillon 		WorkerProcFlags |= WORKER_PROC_FETCHONLY;
379325ef124SMatthew Dillon 		DoCleanBuild(1);
380325ef124SMatthew Dillon 		OptimizeEnv();
381325ef124SMatthew Dillon 		if (ac == 2 && strcmp(av[1], "everything") == 0) {
382325ef124SMatthew Dillon 			MaskProbeAbort = 1;
383325ef124SMatthew Dillon 			pkgs = GetFullPackageList();
384325ef124SMatthew Dillon 		} else {
385325ef124SMatthew Dillon 			pkgs = ParsePackageList(ac - 1, av + 1, 0);
386325ef124SMatthew Dillon 		}
387325ef124SMatthew Dillon 		DoBuild(pkgs);
388c819d181SMatthew Dillon 		doadds = 1;
3891644605eSMatthew Dillon 	} else if (strcmp(av[0], "list-system") == 0) {
3901644605eSMatthew Dillon 		FILE *fp;
3911644605eSMatthew Dillon 
3921644605eSMatthew Dillon 		DoCleanBuild(1);
3931644605eSMatthew Dillon 		OptimizeEnv();
3941644605eSMatthew Dillon 		pkgs = GetLocalPackageList();
3951644605eSMatthew Dillon 		if ((fp = fopen("build.txt", "w")) != NULL) {
3961644605eSMatthew Dillon 			while (pkgs) {
3971644605eSMatthew Dillon 				fprintf(fp, "%s\n", pkgs->portdir);
3981644605eSMatthew Dillon 				pkgs = pkgs->bnext;
3991644605eSMatthew Dillon 			}
4001644605eSMatthew Dillon 			fclose(fp);
4011644605eSMatthew Dillon 			printf("list written to build.txt\n");
4021644605eSMatthew Dillon 		} else {
4031644605eSMatthew Dillon 			fprintf(stderr, "Cannot create 'build.txt'\n");
4041644605eSMatthew Dillon 			exit(1);
4051644605eSMatthew Dillon 		}
4068e25f19bSMatthew Dillon 	} else if (strcmp(av[0], "upgrade-system") == 0) {
40787017ac4SMatthew Dillon 		DoCleanBuild(1);
408a67bf8dbSMatthew Dillon 		OptimizeEnv();
4098e25f19bSMatthew Dillon 		pkgs = GetLocalPackageList();
4108e25f19bSMatthew Dillon 		DoBuild(pkgs);
4118e25f19bSMatthew Dillon 		DoRebuildRepo(0);
4128e25f19bSMatthew Dillon 		DoUpgradePkgs(pkgs, 0);
413c819d181SMatthew Dillon 		dfatal("NOTE: you have to pkg upgrade manually");
4148e25f19bSMatthew Dillon 	} else if (strcmp(av[0], "prepare-system") == 0) {
415a3dccc55SAntonio Huete Jimenez 		DeleteObsoletePkgs = 1;
41687017ac4SMatthew Dillon 		DoCleanBuild(1);
417a67bf8dbSMatthew Dillon 		OptimizeEnv();
4188e25f19bSMatthew Dillon 		pkgs = GetLocalPackageList();
4198e25f19bSMatthew Dillon 		DoBuild(pkgs);
4208e25f19bSMatthew Dillon 		DoRebuildRepo(0);
4218e25f19bSMatthew Dillon 	} else if (strcmp(av[0], "rebuild-repository") == 0) {
422a67bf8dbSMatthew Dillon 		OptimizeEnv();
4238e25f19bSMatthew Dillon 		DoRebuildRepo(0);
4248e25f19bSMatthew Dillon 	} else if (strcmp(av[0], "purge-distfiles") == 0) {
425a67bf8dbSMatthew Dillon 		OptimizeEnv();
4268e25f19bSMatthew Dillon 		pkgs = GetFullPackageList();
4278e25f19bSMatthew Dillon 		PurgeDistfiles(pkgs);
428b6bd007bSMatthew Dillon 	} else if (strcmp(av[0], "reset-db") == 0) {
429b6bd007bSMatthew Dillon 		char *dbmpath;
430b6bd007bSMatthew Dillon 
431b6bd007bSMatthew Dillon 		asprintf(&dbmpath, "%s/ports_crc.db", BuildBase);
432b6bd007bSMatthew Dillon 		remove(dbmpath);
433b6bd007bSMatthew Dillon 		printf("%s reset, will be regenerated on next build\n",
434b6bd007bSMatthew Dillon 		       dbmpath);
435b6bd007bSMatthew Dillon 		free(dbmpath);
4368e25f19bSMatthew Dillon 	} else if (strcmp(av[0], "status-everything") == 0) {
437a67bf8dbSMatthew Dillon 		OptimizeEnv();
4388e25f19bSMatthew Dillon 		pkgs = GetFullPackageList();
4391645cafeSMatthew Dillon 		DoStatus(pkgs);
4408e25f19bSMatthew Dillon 	} else if (strcmp(av[0], "everything") == 0) {
44132f62172SMatthew Dillon 		if (WorkerProcFlags & WORKER_PROC_DEVELOPER)
44232f62172SMatthew Dillon 			WorkerProcFlags |= WORKER_PROC_CHECK_PLIST;
443927e4e3eSMatthew Dillon 		MaskProbeAbort = 1;
444dc46751bSMatthew Dillon 		DeleteObsoletePkgs = 1;
44587017ac4SMatthew Dillon 		DoCleanBuild(1);
446a67bf8dbSMatthew Dillon 		OptimizeEnv();
4478e25f19bSMatthew Dillon 		pkgs = GetFullPackageList();
4488e25f19bSMatthew Dillon 		DoBuild(pkgs);
449c819d181SMatthew Dillon 		DoRebuildRepo(!CheckAddReExec(lkfd));
4508e25f19bSMatthew Dillon 	} else if (strcmp(av[0], "build") == 0) {
45187017ac4SMatthew Dillon 		DoCleanBuild(1);
452a67bf8dbSMatthew Dillon 		OptimizeEnv();
453710838f7SMatthew Dillon 		pkgs = ParsePackageList(ac - 1, av + 1, 0);
4548e25f19bSMatthew Dillon 		DoBuild(pkgs);
455c819d181SMatthew Dillon 		DoRebuildRepo(!CheckAddReExec(lkfd));
4568e25f19bSMatthew Dillon 		DoUpgradePkgs(pkgs, 1);
457c819d181SMatthew Dillon 		doadds = 1;
4588e25f19bSMatthew Dillon 	} else if (strcmp(av[0], "just-build") == 0) {
45987017ac4SMatthew Dillon 		DoCleanBuild(1);
460a67bf8dbSMatthew Dillon 		OptimizeEnv();
461710838f7SMatthew Dillon 		pkgs = ParsePackageList(ac - 1, av + 1, 0);
4628e25f19bSMatthew Dillon 		DoBuild(pkgs);
463c819d181SMatthew Dillon 		doadds = 1;
4648e25f19bSMatthew Dillon 	} else if (strcmp(av[0], "install") == 0) {
46587017ac4SMatthew Dillon 		DoCleanBuild(1);
466a67bf8dbSMatthew Dillon 		OptimizeEnv();
467710838f7SMatthew Dillon 		pkgs = ParsePackageList(ac - 1, av + 1, 0);
4688e25f19bSMatthew Dillon 		DoBuild(pkgs);
4698e25f19bSMatthew Dillon 		DoRebuildRepo(0);
4708e25f19bSMatthew Dillon 		DoUpgradePkgs(pkgs, 0);
471c819d181SMatthew Dillon 		doadds = 1;
4728e25f19bSMatthew Dillon 	} else if (strcmp(av[0], "force") == 0) {
47387017ac4SMatthew Dillon 		DoCleanBuild(1);
474a67bf8dbSMatthew Dillon 		OptimizeEnv();
475710838f7SMatthew Dillon 		pkgs = ParsePackageList(ac - 1, av + 1, 0);
4768e25f19bSMatthew Dillon 		RemovePackages(pkgs);
4778e25f19bSMatthew Dillon 		DoBuild(pkgs);
478c819d181SMatthew Dillon 		DoRebuildRepo(!CheckAddReExec(lkfd));
4798e25f19bSMatthew Dillon 		DoUpgradePkgs(pkgs, 1);
480c819d181SMatthew Dillon 		doadds = 1;
4818e25f19bSMatthew Dillon 	} else if (strcmp(av[0], "test") == 0) {
482c819d181SMatthew Dillon 		WorkerProcFlags |= WORKER_PROC_CHECK_PLIST |
483c819d181SMatthew Dillon 				   WORKER_PROC_INSTALL |
484c819d181SMatthew Dillon 				   WORKER_PROC_DEINSTALL;
48587017ac4SMatthew Dillon 		DoCleanBuild(1);
486a67bf8dbSMatthew Dillon 		OptimizeEnv();
487710838f7SMatthew Dillon 		pkgs = ParsePackageList(ac - 1, av + 1, 0);
4888e25f19bSMatthew Dillon 		RemovePackages(pkgs);
4896fd67931SMatthew Dillon 		WorkerProcFlags |= WORKER_PROC_DEVELOPER;
4908e25f19bSMatthew Dillon 		DoBuild(pkgs);
491c819d181SMatthew Dillon 		doadds = 1;
4928e25f19bSMatthew Dillon 	} else {
4938e25f19bSMatthew Dillon 		fprintf(stderr, "Unknown directive '%s'\n", av[0]);
4948e25f19bSMatthew Dillon 		usage(2);
4958e25f19bSMatthew Dillon 	}
496c819d181SMatthew Dillon 
497c819d181SMatthew Dillon 	/*
498c819d181SMatthew Dillon 	 * For directives that support the 'add' directive, check for
499c819d181SMatthew Dillon 	 * additions and re-exec.
500c819d181SMatthew Dillon 	 *
501c819d181SMatthew Dillon 	 * Note that the lockfile is O_CLOEXEC and will be remade on exec.
502c819d181SMatthew Dillon 	 *
503c819d181SMatthew Dillon 	 * XXX a bit racey vs adds done just as we are finishing
504c819d181SMatthew Dillon 	 */
505c819d181SMatthew Dillon 	if (doadds && CheckAddReExec(lkfd))
506c819d181SMatthew Dillon 		DoAddReExec(lkfd, optind + 1, av - optind);
507c819d181SMatthew Dillon 
5088e25f19bSMatthew Dillon 	return 0;
5098e25f19bSMatthew Dillon }
5108e25f19bSMatthew Dillon 
511c819d181SMatthew Dillon /*
512c819d181SMatthew Dillon  * If the 'add' directive was issued while a dsynth build was in
513c819d181SMatthew Dillon  * progress, we re-exec dsynth with its original options and
514c819d181SMatthew Dillon  * directive along with the added ports.
515c819d181SMatthew Dillon  */
516c819d181SMatthew Dillon static int
CheckAddReExec(int lkfd)517c819d181SMatthew Dillon CheckAddReExec(int lkfd)
518c819d181SMatthew Dillon {
519c819d181SMatthew Dillon 	struct stat st;
520c819d181SMatthew Dillon 
521c819d181SMatthew Dillon 	if (fstat(lkfd, &st) < 0 || st.st_size == 0)
522c819d181SMatthew Dillon 		return 0;
523c819d181SMatthew Dillon 	return 1;
524c819d181SMatthew Dillon }
525c819d181SMatthew Dillon 
526c819d181SMatthew Dillon static void
DoAddReExec(int lkfd,int ac,char ** oldav)527c819d181SMatthew Dillon DoAddReExec(int lkfd, int ac, char **oldav)
528c819d181SMatthew Dillon {
529c819d181SMatthew Dillon 	struct stat st;
530c819d181SMatthew Dillon 	char *buf;
531c819d181SMatthew Dillon 	char **av;
532c819d181SMatthew Dillon 	size_t bi;
533c819d181SMatthew Dillon 	size_t i;
534c819d181SMatthew Dillon 	int nadd;
535c819d181SMatthew Dillon 	int n;
536c819d181SMatthew Dillon 
537c819d181SMatthew Dillon 	if (fstat(lkfd, &st) < 0 || st.st_size == 0)
538c819d181SMatthew Dillon 		return;
539c819d181SMatthew Dillon 	buf = malloc(st.st_size + 1);
540c819d181SMatthew Dillon 	if (read(lkfd, buf, st.st_size) != st.st_size) {
541c819d181SMatthew Dillon 		free(buf);
542c819d181SMatthew Dillon 		return;
543c819d181SMatthew Dillon 	}
544c819d181SMatthew Dillon 	buf[st.st_size] = 0;
545c819d181SMatthew Dillon 
546c819d181SMatthew Dillon 	nadd = 0;
547c819d181SMatthew Dillon 	for (i = 0; i < (size_t)st.st_size; ++i) {
548c819d181SMatthew Dillon 		if (buf[i] == '\n' || buf[i] == 0) {
549c819d181SMatthew Dillon 			buf[i] = 0;
550c819d181SMatthew Dillon 			++nadd;
551c819d181SMatthew Dillon 		}
552c819d181SMatthew Dillon 	}
553c819d181SMatthew Dillon 
554c819d181SMatthew Dillon 	av = calloc(ac + nadd + 1, sizeof(char *));
555c819d181SMatthew Dillon 
556c819d181SMatthew Dillon 	for (n = 0; n < ac; ++n)
557c819d181SMatthew Dillon 		av[n] = oldav[n];
558c819d181SMatthew Dillon 
559c819d181SMatthew Dillon 	nadd = 0;
560c819d181SMatthew Dillon 	bi = 0;
561c819d181SMatthew Dillon 	for (i = 0; i < (size_t)st.st_size; ++i) {
562c819d181SMatthew Dillon 		if (buf[i] == 0) {
563c819d181SMatthew Dillon 			av[ac + nadd] = buf + bi;
564c819d181SMatthew Dillon 			bi = i + 1;
565c819d181SMatthew Dillon 			++nadd;
566c819d181SMatthew Dillon 		}
567c819d181SMatthew Dillon 	}
568c819d181SMatthew Dillon 
569c819d181SMatthew Dillon 	printf("dsynth re-exec'ing additionally added packages\n");
570c819d181SMatthew Dillon 	for (n = 0; n < ac + nadd; ++n)
571c819d181SMatthew Dillon 		printf(" %s", av[n]);
572c819d181SMatthew Dillon 	printf("\n");
573c819d181SMatthew Dillon 	fflush(stdout);
574c819d181SMatthew Dillon 	sleep(2);
575c819d181SMatthew Dillon 	execv(DSynthExecPath, av);
576c819d181SMatthew Dillon }
577c819d181SMatthew Dillon 
5788ec23ca1SMatthew Dillon static void
DoInit(void)5798ec23ca1SMatthew Dillon DoInit(void)
5808ec23ca1SMatthew Dillon {
5818ec23ca1SMatthew Dillon 	struct stat st;
5828ec23ca1SMatthew Dillon 	char *path;
5838ec23ca1SMatthew Dillon 	FILE *fp;
5848ec23ca1SMatthew Dillon 
58568dc2eeaSMatthew Dillon 	if (stat(ConfigBase1, &st) == 0) {
58668dc2eeaSMatthew Dillon 		dfatal("init will not overwrite %s", ConfigBase1);
5878ec23ca1SMatthew Dillon 	}
588a361ab31SMatthew Dillon 	if (ConfigBase2 && stat(ConfigBase2, &st) == 0) {
5898ec23ca1SMatthew Dillon 		dfatal("init will not create %s if %s exists",
59068dc2eeaSMatthew Dillon 		       ConfigBase2, ConfigBase1);
5918ec23ca1SMatthew Dillon 	}
59268dc2eeaSMatthew Dillon 	if (mkdir(ConfigBase1, 0755) < 0)
59368dc2eeaSMatthew Dillon 		dfatal_errno("Unable to mkdir %s", ConfigBase1);
5948ec23ca1SMatthew Dillon 
59568dc2eeaSMatthew Dillon 	asprintf(&path, "%s/dsynth.ini", ConfigBase1);
5968ec23ca1SMatthew Dillon 	fp = fopen(path, "w");
5978ec23ca1SMatthew Dillon 	dassert_errno(fp, "Unable to create %s", path);
5988ec23ca1SMatthew Dillon 	fprintf(fp, "%s",
5998ec23ca1SMatthew Dillon 	    "; This Synth configuration file is automatically generated\n"
6008ec23ca1SMatthew Dillon 	    "; Take care when hand editing!\n"
6018ec23ca1SMatthew Dillon 	    "\n"
6028ec23ca1SMatthew Dillon 	    "[Global Configuration]\n"
6038ec23ca1SMatthew Dillon 	    "profile_selected= LiveSystem\n"
6048ec23ca1SMatthew Dillon 	    "\n"
6058ec23ca1SMatthew Dillon 	    "[LiveSystem]\n"
6068ec23ca1SMatthew Dillon 	    "Operating_system= DragonFly\n"
6078ec23ca1SMatthew Dillon 	    "Directory_packages= /build/synth/live_packages\n"
6088ec23ca1SMatthew Dillon 	    "Directory_repository= /build/synth/live_packages/All\n"
6098ec23ca1SMatthew Dillon 	    "Directory_portsdir= /build/synth/dports\n"
6108ec23ca1SMatthew Dillon 	    "Directory_options= /build/synth/options\n"
6118ec23ca1SMatthew Dillon 	    "Directory_distfiles= /build/synth/distfiles\n"
6128ec23ca1SMatthew Dillon 	    "Directory_buildbase= /build/synth/build\n"
6138ec23ca1SMatthew Dillon 	    "Directory_logs= /build/synth/logs\n"
6148ec23ca1SMatthew Dillon 	    "Directory_ccache= disabled\n"
6158ec23ca1SMatthew Dillon 	    "Directory_system= /\n"
616483dbac9SMatthew Dillon 	    "Package_suffix= .txz\n"
6178ec23ca1SMatthew Dillon 	    "Number_of_builders= 0\n"
6188ec23ca1SMatthew Dillon 	    "Max_jobs_per_builder= 0\n"
6198ec23ca1SMatthew Dillon 	    "Tmpfs_workdir= true\n"
6208ec23ca1SMatthew Dillon 	    "Tmpfs_localbase= true\n"
6218ec23ca1SMatthew Dillon 	    "Display_with_ncurses= true\n"
6228ec23ca1SMatthew Dillon 	    "leverage_prebuilt= false\n"
6239cb4fab1SMatthew Dillon 	    "; Meta_version= 2\n"
6249cb4fab1SMatthew Dillon 	    "; Check_plist= false\n"
6253bd7e0a7SMatthew Dillon 	    "; Numa_setsize= 2\n"
6268ec23ca1SMatthew Dillon 	    "\n");
6278ec23ca1SMatthew Dillon 	if (fclose(fp))
62868dc2eeaSMatthew Dillon 		dfatal_errno("Unable to write to %s\n", ConfigBase1);
6298ec23ca1SMatthew Dillon 	free(path);
6308ec23ca1SMatthew Dillon 
63168dc2eeaSMatthew Dillon 	asprintf(&path, "%s/LiveSystem-make.conf", ConfigBase1);
6328ec23ca1SMatthew Dillon 	fp = fopen(path, "w");
6338ec23ca1SMatthew Dillon 	dassert_errno(fp, "Unable to create %s", path);
6348ec23ca1SMatthew Dillon 	fprintf(fp, "%s",
6358ec23ca1SMatthew Dillon 	    "#\n"
6368ec23ca1SMatthew Dillon 	    "# Various dports options that might be of interest\n"
6378ec23ca1SMatthew Dillon 	    "#\n"
6388ec23ca1SMatthew Dillon 	    "#LICENSES_ACCEPTED=      NONE\n"
6398ec23ca1SMatthew Dillon 	    "#DISABLE_LICENSES=       yes\n"
6408ec23ca1SMatthew Dillon 	    "#DEFAULT_VERSIONS=       ssl=openssl\n"
6418ec23ca1SMatthew Dillon 	    "#FORCE_PACKAGE=          yes\n"
6428ec23ca1SMatthew Dillon 	    "#DPORTS_BUILDER=         yes\n"
6438ec23ca1SMatthew Dillon 	    "#\n"
6448ec23ca1SMatthew Dillon 	    "# Turn these on to generate debug binaries.  However, these\n"
6458ec23ca1SMatthew Dillon 	    "# options will seriously bloat memory use and storage use,\n"
6468ec23ca1SMatthew Dillon 	    "# do not use lightly\n"
6478ec23ca1SMatthew Dillon 	    "#\n"
6488ec23ca1SMatthew Dillon 	    "#STRIP=\n"
6498ec23ca1SMatthew Dillon 	    "#WITH_DEBUG=yes\n"
6508ec23ca1SMatthew Dillon 	);
6518ec23ca1SMatthew Dillon 	if (fclose(fp))
65268dc2eeaSMatthew Dillon 		dfatal_errno("Unable to write to %s\n", ConfigBase1);
6538ec23ca1SMatthew Dillon 	free(path);
6548ec23ca1SMatthew Dillon }
6558ec23ca1SMatthew Dillon 
6568e25f19bSMatthew Dillon __dead2 static void
usage(int ecode)6578e25f19bSMatthew Dillon usage(int ecode)
6588e25f19bSMatthew Dillon {
6598e25f19bSMatthew Dillon 	if (ecode == 2) {
6608e25f19bSMatthew Dillon 		fprintf(stderr, "Run 'dsynth help' for usage\n");
6618e25f19bSMatthew Dillon 		exit(1);
6628e25f19bSMatthew Dillon 	}
6638e25f19bSMatthew Dillon 
6648e25f19bSMatthew Dillon 	fprintf(stderr,
6658e25f19bSMatthew Dillon     "dsynth [options] directive\n"
6667f0eca56SMatthew Dillon     "    -d                   - Debug verbosity (-dd disables ncurses)\n"
6672c5f241eSMatthew Dillon     "    -f                   - Force (for purge-distfiles)\n"
6687f0eca56SMatthew Dillon     "    -h                   - Display this screen and exit\n"
6697f0eca56SMatthew Dillon     "    -m gb                - Load management based on pkgdep memory\n"
6709e1d0b12SMatthew Dillon     "    -p profile           - Override profile selected in dsynth.ini\n"
6719e1d0b12SMatthew Dillon     "    -s n                 - Set initial DynamicMaxWorkers\n"
6727f0eca56SMatthew Dillon     "    -v                   - Print version info and exit\n"
673b6bd007bSMatthew Dillon     "    -x                   - Do not rebuild packages with dependencies\n"
674b6bd007bSMatthew Dillon     "                           which require rebuilding\n"
675b6bd007bSMatthew Dillon     "    -xx                  - Do not rebuild packages whos dports trees\n"
676b6bd007bSMatthew Dillon     "                           change\n"
6777f0eca56SMatthew Dillon     "    -y                   - Automatically answer yes to dsynth questions\n"
678a361ab31SMatthew Dillon     "    -C configbase        - Config base directory (replaces /etc/dsynth)\n"
679a67bf8dbSMatthew Dillon     "    -D                   - Enable DEVELOPER mode\n"
6802478c21aSMatthew Dillon     "    -P                   - Include the check-plist stage\n"
6817f0eca56SMatthew Dillon     "    -S                   - Disable ncurses\n"
6826d1478d9SMatthew Dillon     "    -N                   - Do not nice-up sub-processes (else nice +10)\n"
6837f0eca56SMatthew Dillon     "\n"
6848ec23ca1SMatthew Dillon     "    init                 - Initialize /etc/dsynth\n"
6858e25f19bSMatthew Dillon     "    status               - Dry-run of 'upgrade-system'\n"
6868e25f19bSMatthew Dillon     "    cleanup              - Clean-up mounts\n"
6878e25f19bSMatthew Dillon     "    configure            - Bring up configuration menu\n"
6881644605eSMatthew Dillon     "    list-system          - Just generate the build list to build.txt\n"
6898e25f19bSMatthew Dillon     "    upgrade-system       - Incremental build and upgrade using pkg list\n"
6908e25f19bSMatthew Dillon     "                           from local system, then upgrade the local\n"
6918e25f19bSMatthew Dillon     "                           system.\n"
6928e25f19bSMatthew Dillon     "    prepare-system       - 'upgrade-system' but stops after building\n"
6938e25f19bSMatthew Dillon     "    rebuild-repository   - Rebuild database files for current repository\n"
6948e25f19bSMatthew Dillon     "    purge-distfiles      - Delete obsolete source distribution files\n"
695b6bd007bSMatthew Dillon     "    reset-db             - Delete ports_crc.db, regenerate next build\n"
6968e25f19bSMatthew Dillon     "    status-everything    - Dry-run of 'everything'\n"
6978e25f19bSMatthew Dillon     "    everything           - Build entire dports tree and repo database\n"
6982478c21aSMatthew Dillon     "				(-D everything infers -P)\n"
6997f0eca56SMatthew Dillon     "    version              - Print version info and exit\n"
7007f0eca56SMatthew Dillon     "    help                 - Display this screen and exit\n"
7018e25f19bSMatthew Dillon     "    status     [ports]   - Dry-run of 'build' with given list\n"
702*ab4c55c7SMatthew Dillon     "    add        [ports]   - Add listed dports to a new build queue that\n"
703*ab4c55c7SMatthew Dillon     "                           will be built after the current run finishes.\n"
7048e25f19bSMatthew Dillon     "    build      [ports]   - Incrementally build dports based on the given\n"
7058e25f19bSMatthew Dillon     "                           list, but asks before updating the repo\n"
7068e25f19bSMatthew Dillon     "                           database and system\n"
7078e25f19bSMatthew Dillon     "    just-build [ports]   - 'build' but skips post-build steps\n"
7088e25f19bSMatthew Dillon     "    install    [ports]   - 'build' but upgrades system without asking\n"
7098e25f19bSMatthew Dillon     "    force      [ports]   - 'build' but deletes existing packages first\n"
7108e25f19bSMatthew Dillon     "    test       [ports]   - 'build' w/DEVELOPER=yes and pre-deletes pkgs\n"
7112478c21aSMatthew Dillon     "				(also infers -P)\n"
7129bb2c592SMatthew Dillon     "    debug      [ports]   - like 'test' but leaves mounts intact\n"
713d1fffddaSMatthew Dillon     "    fetch-only [ports]   - Fetch src dists only ('everything' ok)\n"
714aac7a6d9SMatthew Dillon     "    monitor    [datfile] - Monitor a running dsynth\n"
7158e25f19bSMatthew Dillon     "\n"
7168e25f19bSMatthew Dillon     "    [ports] is a space-delimited list of origins, e.g. editors/joe.  It\n"
7178e25f19bSMatthew Dillon     "            may also be a path to a file containing one origin per line.\n"
7188e25f19bSMatthew Dillon 	);
7198e25f19bSMatthew Dillon 
7208e25f19bSMatthew Dillon 	exit(ecode);
7218e25f19bSMatthew Dillon }
722