Projet

Général

Profil

Télécharger (19,5 ko) Statistiques
| Branche: | Révision:

univnautes-tools / builder_scripts / rebuild_package_binaries_pbi.php @ 4ab3b90b

1
#!/usr/local/bin/php-cli -q
2
<?php
3
/*
4
 *  rebuild_package_binaries.sh
5
 *  Copyright (C) 2010, 2011 Scott Ullrich <sullrich@gmail.com>
6
 *  Copyright (C) 2010, 2011 Jim Pingle <jim@pingle.org>
7
 *  All rights reserved.
8
 *
9
 *  Redistribution and use in source and binary forms, with or without
10
 *  modification, are permitted provided that the following conditions are met:
11
 *
12
 *  1. Redistributions of source code must retain the above copyright notice,
13
 *     this list of conditions and the following disclaimer.
14
 *
15
 *  2. Redistributions in binary form must reproduce the above copyright
16
 *     notice, this list of conditions and the following disclaimer in the
17
 *     documentation and/or other materials provided with the distribution.
18
 *
19
 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20
 *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21
 *  AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22
 *  AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
23
 *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
 *  POSSIBILITY OF SUCH DAMAGE.
29
 */
30

    
31
/* TODO:
32
	* Add prefetch_distfiles so we can grab source from wherever we want before building, in case ports can't get it
33
	* Add pbi_autobuild support
34
	* Add support for more PBI variables such as the build key, exclude list, and so on.
35
*/
36

    
37
$opts  = "x:"; // Path to XML file
38
$opts .= "p:"; // Package name to build (optional)
39
$opts .= "s:"; // pfSense version to pass to set_version.sh
40
$opts .= "P";  // Skip applying kernel patches before the run
41
$opts .= "I";  // Skip make includes
42
$opts .= "u";  // Upload after every port, not just at the end.
43
$opts .= "U";  // Skip uploading compiled binaries
44
$opts .= "v";  // Verbose, show PBI build output
45
$opts .= "S:"; // Key used to sign PBIs
46
$opts .= "a:"; // Arch
47
$opts .= "r";  // Force re-create chroot (buildworld/installworld)
48

    
49
$options = getopt($opts);
50

    
51
if(!isset($options['x']))
52
	usage();
53

    
54
// Safety check
55
if(!is_dir("/usr/ports")) {
56
	echo "!!! /usr/ports/ not found.   Please run portsnap fetch extract\n";
57
	exit;
58
}
59

    
60
// Set the XML filename that we are processing
61
$xml_filename = $options['x'];
62

    
63
if (!file_exists($xml_filename))
64
	die("Package XML file not found");
65

    
66
echo "PBI Build run started at " . date(DATE_RFC822) . "\n";
67
$full_start_time = time();
68

    
69
if(!empty($options['s']) && !isset($options['P'])) {
70
	echo ">>> [" . date("H:i:s") . "] Running set_version.sh {$options['s']}...\n";
71
	exec("cd /home/pfsense/tools/builder_scripts && ./set_version.sh {$options['s']}");
72
}
73

    
74
echo ">>> [" . date("H:i:s") . "] Checking out pfSense sources...\n";
75
if(file_exists("/home/pfsense/tools/builder_scripts/build.sh"))
76
	exec("cd /home/pfsense/tools/builder_scripts && /home/pfsense/tools/builder_scripts/build.sh --update-sources && /home/pfsense/tools/builder_scripts/build.sh --builder-required-ports");
77

    
78
if(file_exists("/etc/inc/")) {
79
	require_once("/etc/inc/util.inc");
80
	require_once("/etc/inc/xmlparse.inc");
81
} else if(file_exists("/home/pfsense/pfSense/etc/inc")) {
82
	require_once("/home/pfsense/pfSense/etc/inc/util.inc");
83
	require_once("/home/pfsense/pfSense/etc/inc/xmlparse.inc");
84
} else if(file_exists("/home/pfsense/pfSenseGITREPO/pfSenseGITREPO/etc/inc")) {
85
	require_once("/home/pfsense/pfSenseGITREPO/pfSenseGITREPO/etc/inc/util.inc");
86
	require_once("/home/pfsense/pfSenseGITREPO/pfSenseGITREPO/etc/inc/xmlparse.inc");
87
} else {
88
	die("Missing include directories");
89
}
90

    
91
$pkg = parse_xml_config_pkg($xml_filename, "pfsensepkgs");
92
if(!$pkg) {
93
	echo "!!! An error occurred while trying to process {$xml_filename}.  Exiting.\n";
94
	exit;
95
}
96

    
97
$freebsd_version = explode(".", php_uname("r"));
98
$freebsd_version = $freebsd_version[0];
99
$host_arch = php_uname("m");
100

    
101
if (empty($options['a'])) {
102
	if ($host_arch == "amd64") {
103
		if ($freebsd_version < 10)
104
			$options['a'] = 'amd64';
105
		else
106
			$options['a'] = 'all';
107
	} else
108
		$options['a'] = 'i386';
109
}
110

    
111
if ($host_arch == "i386" && $options['a'] == "amd64") {
112
	echo "!!! You cannot build an amd64 binary on i386 host.  Exiting.\n";
113
	exit;
114
}
115

    
116
if(!empty($options['S']) && !file_exists($options['S'])) {
117
	echo "!!! Sign key file does not exist";
118
	exit;
119
}
120

    
121
// pcbsd-utils bootstrap for 8.x systems
122
if(!file_exists("/usr/local/sbin/pbi_makeport") && $freebsd_version < 10) {
123
	echo ">>> [" . date("H:i:s") . "] Bootstrapping PBI...\n";
124
	exec("cd /home/pfsense/tools/builder_scripts/scripts && ./install_old_pcbsd_tools.sh");
125
	if (!file_exists("/usr/local/bin/svn"))
126
		die("Could not find subversion");
127
	if(!file_exists("/usr/local/sbin/pbi_makeport"))
128
		die("Could not find pbi_makeport");
129
}
130

    
131
// Bootstrap
132
echo ">>> [" . date("H:i:s") . "] Installing builder required ports...\n";
133
exec("cd /home/pfsense/tools/builder_scripts && ./build.sh --builder-required-ports");
134

    
135
// Set and ouput initial flags
136
if (!isset($options['U']) && $pkg['copy_packages_to_host_ssh_port'] &&
137
    $pkg['copy_packages_to_host_ssh'] && $pkg['copy_packages_to_folder_ssh']) {
138
	$copy_packages_to_folder_ssh = $pkg['copy_packages_to_folder_ssh'];
139
	$copy_packages_to_host_ssh = $pkg['copy_packages_to_host_ssh'];
140
	$copy_packages_to_host_ssh_port = $pkg['copy_packages_to_host_ssh_port'];
141
	echo ">>> [" . date("H:i:s") . "] Setting the following RSYNC/SSH parameters: \n";
142
	echo "    copy_packages_to_folder_ssh:    $copy_packages_to_folder_ssh\n";
143
	echo "    copy_packages_to_host_ssh:      $copy_packages_to_host_ssh\n";
144
	echo "    copy_packages_to_host_ssh_port: $copy_packages_to_host_ssh_port\n";
145
}
146

    
147
if (isset($options['r'])) {
148
	if ($host_arch == "amd64" && $options['a'] != 'i386')
149
		@exec("rm -rf /usr/pbi/.pbi-world-amd64");
150
	if ($host_arch == "i386" || $options['a'] != 'amd64')
151
		@exec("rm -rf /usr/pbi/.pbi-world-i386");
152
}
153

    
154
if ($host_arch == "amd64" && $options['a'] != 'i386' && !file_exists('/usr/pbi/.pbi-world-amd64/COPYRIGHT')) {
155
	// Remove -I to force includes
156
	unset($options['I']);
157
	create_chroot("amd64");
158
}
159

    
160
if (($host_arch == "i386" || $options['a'] != 'amd64') && !file_exists('/usr/pbi/.pbi-world-i386/COPYRIGHT')) {
161
	// Remove -I to force includes
162
	unset($options['I']);
163
	create_chroot("i386");
164
}
165

    
166
if (!isset($options['P'])) {
167
	echo ">>> [" . date("H:i:s") . "] Applying kernel patches...\n";
168
	exec("cd /home/pfsense/tools/builder_scripts && ./build.sh --apply-patches");
169
}
170

    
171
if (!isset($options['I'])) {
172
	echo ">>> [" . date("H:i:s") . "] Running make includes...\n";
173
	$src_conf="/home/pfsense/tools/builder_scripts/conf/src/src.conf.{$freebsd_version}";
174
	if ($host_arch == "amd64" && $options['a'] != 'i386')
175
		exec("cd /usr/pfSensesrc/src && make SRCCONF={$src_conf} TARGET=amd64 includes DESTDIR=/usr/pbi/.pbi-world-amd64 2>&1");
176
	if ($host_arch == "i386" || $options['a'] != 'amd64')
177
		exec("cd /usr/pfSensesrc/src && make SRCCONF={$src_conf} TARGET=i386 includes DESTDIR=/usr/pbi/.pbi-world-i386 2>&1");
178
}
179
echo ">>> [" . date("H:i:s") . "] pfSense package binary builder is starting.\n";
180

    
181
// Ensure that the All directory exists in packages staging area
182
if(!is_dir("/usr/ports/packages/All"))
183
	system("mkdir -p /usr/ports/packages/All");
184

    
185
// Loop through all packages and build pacakge with
186
// build_options if the port/package has this defined.
187
echo ">>> [" . date("H:i:s") . "] Creating port build list...\n";
188
$skipped=0;
189
$build_list = array();
190
foreach($pkg['packages']['package'] as $pkg) {
191
	if (isset($options['p'])) {
192
		if (is_string($options['p']) && (strtolower($options['p']) != strtolower($pkg['name'])))
193
				continue;
194
		else if (is_array($options['p']) && !in_array(strtolower($pkg['name']), array_map('strtolower', $options['p'])))
195
				continue;
196
	}
197
	if ($pkg['build_pbi']) {
198
		if (empty($pkg['build_pbi']['port']))
199
			continue;
200
		$build = $pkg['build_pbi']['port'];
201
		if (array_key_exists($build, $build_list)) {
202
			echo ">>> [" . date("H:i:s") . "] Skipping {$build} - already in build list.\n";
203
			$skipped++;
204
			continue;
205
		}
206

    
207
		if (isset($pkg['build_pbi']['build_options']))
208
			$build_list[$build]['build_options'] = $pkg['build_pbi']['build_options'];
209
		elseif (isset($pkg['build_options']))
210
			$build_list[$build]['build_options'] = $pkg['build_options'];
211
		else
212
			$build_list[$build]['build_options'] = "";
213

    
214
		$build_list[$build]['custom_name']    = isset($pkg['build_pbi']['custom_name']) ? $pkg['build_pbi']['custom_name'] : "";
215
		$build_list[$build]['ports_before']   = isset($pkg['build_pbi']['ports_before']) ? $pkg['build_pbi']['ports_before'] : "";
216
		$build_list[$build]['ports_after']    = isset($pkg['build_pbi']['ports_after']) ? $pkg['build_pbi']['ports_after'] :  "";
217
		$build_list[$build]['only_for_archs'] = isset($pkg['only_for_archs']) ? preg_split("/\s+/", trim($pkg['only_for_archs'])) : array();
218
	} elseif ($pkg['build_port_path']) {
219
		foreach($pkg['build_port_path'] as $build) {
220
			if (!is_dir($build) && !is_dir("/home/pfsense/tools/pfPorts/" . basename($build))) {
221
				echo ">>> [" . date("H:i:s") . "] Skipping {$build} - port does not exist and no pfPort to use instead.\n";
222
				continue;
223
			}
224
			if (array_key_exists($build, $build_list)) {
225
				echo ">>> [" . date("H:i:s") . "] Skipping {$build} - already in build list.\n";
226
				$skipped++;
227
				continue;
228
			}
229
			$build_list[$build]['build_options']  = isset($pkg['build_options']) ? $pkg['build_options'] : "";
230
			$build_list[$build]['only_for_archs'] = isset($pkg['only_for_archs']) ? preg_split("/\s+/", trim($pkg['only_for_archs'])) : array();
231
		}
232
	}
233
}
234

    
235
$total_to_build = count($build_list);
236
$skipped = ($skipped > 0) ? " (skipped {$skipped})" : "";
237
$plur = ($total_to_build == 1) ? "" : "s";
238
echo ">>> [" . date("H:i:s") . "] Found {$total_to_build} unique port{$plur} to build{$skipped}.\n";
239
$j = 0;
240
foreach ($build_list as $build => $pbi_options) {
241
	$j++;
242
	overlay_pfPort($build);
243
	if (!empty($pbi_options['ports_before'])) {
244
		$overlay_list = explode(" ", $pbi_options['ports_before']);
245
		foreach ($overlay_list as $ol) {
246
			overlay_pfPort($ol);
247
		}
248
	}
249
	if (!empty($pbi_options['ports_after'])) {
250
		$overlay_list = explode(" ", $pbi_options['ports_after']);
251
		foreach ($overlay_list as $ol) {
252
			overlay_pfPort($ol);
253
		}
254
	}
255
	$buildname = basename($build);
256

    
257
	$port_start_time = time();
258

    
259
	if ($host_arch == "amd64" && $options['a'] == "i386") {
260
		$build_32 = "-32 ";
261
		$message_32 = "32-bit ";
262
		$main_build_arch = "i386";
263
	} else {
264
		$build_32 = "";
265
		$message_32 = "";
266
		$main_build_arch = $host_arch;
267
	}
268

    
269
	// Kill /usr/ports/ if it's there
270
	$build = str_replace("/usr/ports/", "", $build);
271
	list($category, $port) = explode('/', $build);
272
	if($pbi_options['build_options'])
273
		if(!isset($options['q']))
274
			echo ">>> [" . date("H:i:s") . "] BUILD_OPTIONS: {$pbi_options['build_options']}\n";
275
	$pbi_conf = create_pbi_conf("{$category}/{$port}",$pbi_options['custom_name'],$pbi_options['build_options'],$pbi_options['ports_before'],$pbi_options['ports_after']);
276
	if(!is_dir("/pbi-build/modules/{$category}/{$port}"))
277
		exec("mkdir -p /pbi-build/modules/{$category}/{$port}");
278
	$pbi_confdir = "/pbi-build/modules/{$category}/{$port}";
279
	file_put_contents("{$pbi_confdir}/pbi.conf", $pbi_conf);
280
	$sign = "";
281
	if (!empty($options['S']))
282
		$sign = "--sign {$options['S']} ";
283
	$redirbg = isset($options['v']) ? "": " > {$pbi_confdir}/pbi.log 2>&1 &";
284

    
285
	if (empty($pbi_options['only_for_archs']) || in_array($main_build_arch, $pbi_options['only_for_archs'])) {
286
		echo ">>> [" . date("H:i:s") . "] Processing {$build} {$message_32}({$j}/{$total_to_build})\n";
287
		echo ">>> [" . date("H:i:s") . "] Executing /usr/local/sbin/pbi_makeport -o /usr/ports/packages/All/ -c {$pbi_confdir} {$build_32}{$sign}{$category}/{$port}\n";
288
		system("/usr/local/sbin/pbi_makeport -o /usr/ports/packages/All/ -c {$pbi_confdir} {$build_32}{$sign}{$category}/{$port}{$redirbg}");
289
		if (!isset($options['v'])) {
290
			$processes = 0;
291
			$counter = 0;
292
			wait_for_procs_finish();
293
		}
294
		echo ">>> [" . date("H:i:s") . "] Finished building {$build} {$message_32}- Elapsed time: " . format_elapsed_time(time() - $port_start_time) . "\n";
295
	} else {
296
		echo ">>> [" . date("H:i:s") . "] Skipping {$build} for {$main_build_arch}\n";
297
	}
298

    
299
	if ($host_arch == "amd64" && $options['a'] == 'all') {
300
		if (empty($pbi_options['only_for_archs']) || in_array("i386", $pbi_options['only_for_archs'])) {
301
			echo ">>> [" . date("H:i:s") . "] Processing {$build} 32-bit ({$j}/{$total_to_build})\n";
302
			echo ">>> [" . date("H:i:s") . "] Executing /usr/local/sbin/pbi_makeport -o /usr/ports/packages/All/ -c {$pbi_confdir} -32 {$sign}{$category}/{$port}\n";
303
			system("/usr/local/sbin/pbi_makeport -o /usr/ports/packages/All/ -c {$pbi_confdir} -32 {$sign}{$category}/{$port}{$redirbg}");
304
			if (!isset($options['v'])) {
305
				$processes = 0;
306
				$counter = 0;
307
				wait_for_procs_finish();
308
			}
309
			echo ">>> [" . date("H:i:s") . "] Finished building {$build} 32-bit - Elapsed time: " . format_elapsed_time(time() - $port_start_time) . "\n";
310
		} else {
311
			echo ">>> [" . date("H:i:s") . "] Skipping {$build} for i386\n";
312
		}
313
	}
314

    
315
	if($copy_packages_to_folder_ssh && isset($options['u']) && !isset($options['U'])) {
316
		copy_packages($copy_packages_to_host_ssh, $copy_packages_to_host_ssh_port, $copy_packages_to_folder_ssh);
317
	}
318
}
319

    
320
// Copy created packages to the package server via rsync
321
if($copy_packages_to_folder_ssh && !isset($options['U'])) {
322
	copy_packages($copy_packages_to_host_ssh, $copy_packages_to_host_ssh_port, $copy_packages_to_folder_ssh);
323
}
324

    
325
echo ">>> Package binary build run ended at " . date(DATE_RFC822) . ".\n";
326
echo ">>> Total time: " . format_elapsed_time(time() - $port_start_time) . "\n";
327

    
328
function create_chroot($arch) {
329
	if (empty($arch))
330
		return;
331

    
332
	if (!file_exists("/usr/src/COPYRIGHT"))
333
		die("FreeBSD sources cannot be found at /usr/src");
334

    
335
	$DCPUS=trim(`sysctl -n kern.smp.cpus`);
336
	$CPUS=$DCPUS * 2;
337

    
338
	echo ">>> [" . date("H:i:s") . "] Creating chroot ({$arch})...\n";
339
	exec("make -C /usr/src -j{$CPUS} TARGET={$arch} DESTDIR=/usr/pbi/.pbi-world-{$arch} buildworld installworld >/usr/pbi/.world-{$arch}.log 2>&1", $gb, $rc);
340

    
341
	if ($rc != 0)
342
		die("Error buildiing chroot ({$arch}) - check errors on /usr/pbi/.world-{$arch}.log");
343

    
344
	@unlink("/usr/pbi/.world-{$arch}.log");
345
}
346

    
347
function create_pbi_conf($port_path,$custom_name="",$MAKEOPTS="",$portsbefore="",$portsafter="") {
348

    
349
	if (!empty($custom_name)) {
350
		$PROGNAME = $custom_name;
351
	} else {
352
		$PROGNAME=trim(`make -C /usr/ports/$port_path -V PORTNAME`);
353
		// $port_path Format should be, e.g. www/squid so we can grab the port name there if the makefile is empty.
354
		$PROGNAME = empty($PROGNAME) ? substr($port_path, strpos($port_path, '/')+1) : $PROGNAME;
355
		// If it's still empty, comment it out
356
		$usepn = empty($PROGNAME) ? "#" : "";
357
	}
358

    
359
	$MAINTAINER=trim(`make -C /usr/ports/$port_path -V MAINTAINER`);
360

    
361
	$MAKEOPTS = str_replace(";", "\n", $MAKEOPTS);
362

    
363
	$portsbefore = empty($portsbefore) ? "" : "PBI_MKPORTBEFORE=\"$portsbefore\"";
364
	$portsafter  = empty($portsafter) ? "" : "PBI_MKPORTAFTER=\"$portsafter\"";
365

    
366
	$PBI_CONF = <<<EOF
367
# Format of this file changed, new example: http://wiki.pcbsd.org/index.php/PBI_Module_Builder_Guide
368
# Program Name
369
{$usepn}PBI_PROGNAME="$PROGNAME"
370

    
371
# Program Website
372
# PBI_PROGWEB="$PROGWEB"
373

    
374
# Program Author / Vendor
375
PBI_PROGAUTHOR="$MAINTAINER"
376

    
377
# The target port we are building
378
PBI_MAKEPORT="$port_path"
379

    
380
# Enter your custom make options here
381
# Options that will be put into the make.conf for the build of this port
382
# Options get inserted into the build's /etc/make.conf file and effect all the ports built for that PBI
383
PBI_MAKEOPTS="OPTIONS_UNSET=X11 GTK DOCS EXAMPLES MAN INFO
384
NO_WARNING_PKG_INSTALL_EOL=yes
385
$MAKEOPTS"
386

    
387
# Ports to build before / after
388
{$portsbefore}
389
{$portsafter}
390

    
391
# Exclude List
392
PBI_EXCLUDELIST="./share/doc ./man ./*/man ./*/*/man ./*/*/*/man ./*/*/*/*/man"
393

    
394
# Increment to trigger rebuild of PBI on build servers
395
PBI_BUILDKEY="01"
396

    
397
# This app needs to install as root
398
PBI_REQUIRESROOT="YES"
399

    
400
# Set the priority of this build
401
PBI_AB_PRIORITY="10"
402

    
403
# Set the files we want to exclude from the shared hashdir
404
# PBI_HASH_EXCLUDES="lib/firefox/firefox"
405

    
406
# Do not use system fonts
407
PBI_USESYSFONTS="NO"
408

    
409
# Keep the world around after building in case we need to check on it
410
PBI_DELETE_BUILD=0
411

    
412
export PBI_PROGNAME PBI_PROGWEB PBI_PROGAUTHOR PBI_PROGICON PBI_MAKEPORT PBI_MAKEOPTS PBI_MKPORTBEFORE PBI_MKPORTAFTER PBI_BUILDKEY PBI_REQUIRESROOT PBI_EXCLUDELIST PBI_USESYSFONTS PBI_DELETE_BUILD
413

    
414
# Format of this file changed, these don't seem to be used any longer. Still needed?
415
PBIAUTOPOPULATE="YES" ; export PBIAUTOPOPULATE
416
PBIAUTOPOPULATE_OTHERPORT="" ; export PBIAUTOPOPULATE_OTHERPORT
417

    
418
EOF;
419
	return($PBI_CONF);
420
}
421

    
422
function usage() {
423
	global $argv;
424
	echo "Usage: {$argv[0]} -x <path to pkg xml> [-p <package name>] [-d]\n";
425
	echo "  Flags:\n";
426
	echo "    -p Package name to build a single package and its dependencies.\n";
427
	echo "    -s pfSense version to pass to set_version.sh during chroot build\n";
428
	echo "    -x XML file containing package data.\n";
429
	echo "    -P Skip applying kernel patches before build run.\n";
430
	echo "    -I Skip 'make includes' operation.\n";
431
	echo "    -u Upload after each port is built rather than at the end.\n";
432
	echo "    -U Skip uploading of packages.\n";
433
	echo "    -v Show PBI build output.\n";
434
	echo "    -S Sign PBI using this key.\n";
435
	echo "    -a Choose arch (amd64|i386|all).\n";
436
	echo "    -r Force re-create chroot (buildworld/installworld).\n";
437
	echo "  Examples:\n";
438
	echo "     {$argv[0]} -x /home/pfsense/packages/pkg_info.8.xml\n";
439
	echo "     {$argv[0]} -x /home/pfsense/packages/pkg_info.8.xml -p squid -p snort\n";
440
	exit;
441
}
442

    
443
function overlay_pfPort($port_path) {
444
	if (empty($port_path))
445
		return;
446
	$pfports = "/home/pfsense/tools/pfPorts";
447
	// If a pfport exists, overlay that folder onto $port_path
448
	$port_name = basename($port_path);
449
	$port_path = "/usr/ports/" . $port_path;
450
	if (file_exists("{$pfports}/{$port_name}") && is_dir("{$pfports}/{$port_name}") && is_file("{$pfports}/{$port_name}/Makefile")) {
451
		echo ">>> [" . date("H:i:s") . "] Overelaying pfPort {$port_name} onto {$port_path} ... ";
452
		if (file_exists($port_path) && is_dir($port_path)) {
453
			system("/bin/rm -rf {$port_path}.orig");
454
			system("/bin/mv {$port_path} {$port_path}.orig");
455
		}
456
		system("/bin/cp -R {$pfports}/{$port_name} {$port_path}");
457
		echo "Done.\n";
458
	}
459
}
460

    
461
function get_procs_count() {
462
	$processes = intval(trim(`pgrep -f pbi_makeport | wc -l`));
463
	return($processes);
464
}
465

    
466
function wait_for_procs_finish() {
467
	global $counter;
468
	$processes = get_procs_count();
469
	if($counter == 0)
470
		echo ">>> [" . date("H:i:s") . "] Waiting for previous build processes to finish...";
471
	while($processes >= 1) {
472
		$processes = get_procs_count();
473
		$counter++;
474
		if($counter > 120) {
475
			$counter = 0;
476
			echo ".";
477
		}
478
		sleep(1);
479
	}
480
	echo "\n";
481
}
482

    
483
function copy_packages($copy_packages_to_host_ssh, $copy_packages_to_host_ssh_port, $copy_packages_to_folder_ssh) {
484
	echo ">>> [" . date("H:i:s") . "] Copying packages to {$copy_packages_to_host_ssh}\n";
485
	system("/usr/local/bin/rsync -ave ssh --timeout=60 --rsh='ssh -p{$copy_packages_to_host_ssh_port}' /usr/ports/packages/All/*.pbi {$copy_packages_to_host_ssh}:{$copy_packages_to_folder_ssh}/");
486
}
487

    
488
function format_elapsed_time($seconds) {
489
	$days = (int)($seconds / 86400);
490
	$seconds %= 86400;
491
	$hours = (int)($seconds / 3600);
492
	$seconds %= 3600;
493
	$mins = (int)($seconds / 60);
494
	$seconds %= 60;
495
	$secs = (int)($seconds);
496

    
497
	$timestr = "";
498
	if ($days > 1)
499
		$timestr .= "{$days} Days ";
500
	else if ($days > 0)
501
		$timestr .= "1 Day ";
502

    
503
	$hourspl = ($hours != 1) ? "s" : "";
504
	$minspl = ($mins != 1) ? "s" : "";
505
	$secspl = ($mins != 1) ? "s" : "";
506

    
507
	$timestr .= "{$days}{$hours} Hour{$hourspl} {$mins} Minute$minspl {$secs} Second{$secspl}";
508
	return $timestr;
509
}
510

    
511
?>
(6-6/7)