Project

General

Profile

Download (16 KB) Statistics
| Branch: | Tag: | Revision:
1
#!/bin/sh
2

    
3
# Copyright (c) 2004-2015 Electric Sheep Fencing, LLC. All rights reserved.
4
#
5
# Redistribution and use in source and binary forms, with or without
6
# modification, are permitted provided that the following conditions are met:
7
#
8
# 1. Redistributions of source code must retain the above copyright notice,
9
#    this list of conditions and the following disclaimer.
10
#
11
# 2. Redistributions in binary form must reproduce the above copyright
12
#    notice, this list of conditions and the following disclaimer in
13
#    the documentation and/or other materials provided with the
14
#    distribution.
15
#
16
# 3. All advertising materials mentioning features or use of this software
17
#    must display the following acknowledgment:
18
#    "This product includes software developed by the pfSense Project
19
#    for use in the pfSense® software distribution. (http://www.pfsense.org/).
20
#
21
# 4. The names "pfSense" and "pfSense Project" must not be used to
22
#    endorse or promote products derived from this software without
23
#    prior written permission. For written permission, please contact
24
#    coreteam@pfsense.org.
25
#
26
# 5. Products derived from this software may not be called "pfSense"
27
#    nor may "pfSense" appear in their names without prior written
28
#    permission of the Electric Sheep Fencing, LLC.
29
#
30
# 6. Redistributions of any form whatsoever must retain the following
31
#    acknowledgment:
32
#
33
# "This product includes software developed by the pfSense Project
34
# for use in the pfSense software distribution (http://www.pfsense.org/).
35
#
36
# THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
37
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
40
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47
# OF THE POSSIBILITY OF SUCH DAMAGE.
48

    
49
usage() {
50
	echo "Usage: $(basename ${0}) [-bdyf] [-u|-i PKG_NAME|-r PKG_NAME]" >&2
51
	echo "	-b          - Platform is booting" >&2
52
	echo "	-d          - Turn on debug" >&2
53
	echo "	-f          - Force package installation" >&2
54
	echo "	-h          - Show this usage help" >&2
55
	echo "	-l          - Logfile path (defaults to /cf/conf/upgrade_log.txt)" >&2
56
	echo "	-p FIFO     - Write pkg progress to FIFO"
57
	echo "	-y          - Consider yes as the answer for any possible interaction" >&2
58
	echo "" >&2
59
	echo "Following parameters are mutually exclusive:" >&2
60
	echo "	-i PKG_NAME - Install package PKG_NAME" >&2
61
	echo "	-r PKG_NAME - Remove package PKG_NAME" >&2
62
	echo "	-u          - Update repository information" >&2
63
}
64

    
65
_echo() {
66
	local _n=""
67
	if [ "${1}" = "-n" ]; then
68
		shift
69
		_n="-n"
70
	fi
71

    
72
	if [ -z "${logfile}" ]; then
73
		logfile=/dev/null
74
	fi
75

    
76
	echo ${_n} "${1}" | tee -a ${logfile}
77
}
78

    
79
_exec() {
80
	local _cmd="${1}"
81
	local _msg="${2}"
82
	local _mute="${3}"
83
	local _ignore_result="${4}"
84
	local _stdout="${stdout}"
85

    
86
	if [ -z "${_cmd}" -o -z "${_msg}" ]; then
87
		return 1
88
	fi
89

    
90
	if [ "${_mute}" != "mute" ]; then
91
		_stdout=''
92
	fi
93

    
94
	_echo -n ">>> ${_msg}... "
95
	if [ -z "${_stdout}" ]; then
96
		_echo ""
97
		${_cmd} 2>&1 | tee -a ${logfile}
98
	else
99
		${_cmd} >${_stdout} 2>&1 | tee -a ${logfile}
100
	fi
101
	local _result=$?
102

    
103
	if [ ${_result} -eq 0 -o -n "${_ignore_result}" ]; then
104
		[ -n "${_stdout}" ] \
105
			&& _echo "done."
106
		return 0
107
	else
108
		[ -n "${_stdout}" ] \
109
			&& _echo "failed."
110
		exit 1
111
	fi
112
}
113

    
114
_exit() {
115
	trap "-" 1 2 15 EXIT
116

    
117
	pkg_lock ${kernel_pkg}
118

    
119
	if [ -f "${pid_file}" ]; then
120
		rm -f ${pid_file}
121
	fi
122

    
123
	if [ -n "${chroot_dir}" ]; then
124
		umount -f ${chroot_dir} >/dev/null 2>&1
125
	fi
126

    
127
	if [ -z "${booting}" -o "${boot_stage}" != "2" ]; then
128
		/etc/rc.conf_mount_ro
129
	fi
130

    
131
	local _rc=${1:-"0"}
132

    
133
	# If EVENT_PIPE is defined, GUI is calling
134
	[ -n "${EVENT_PIPE}" ] \
135
		&& _echo "__RC=${_rc}"
136

    
137
	exit ${_rc}
138
}
139

    
140
fetch_upgrade_packages() {
141
	local _pkgs_to_fetch=""
142
	if [ "${platform}" = "nanobsd" ]; then
143
		local _pkg=""
144

    
145
		# Check if all non-auto packages installed on 2nd partition are
146
		# installed on current one, if not, mark them to be deleted by
147
		# pkg autoremove
148
		for _pkg in $(pkg ${pkg_chroot} query -e '%a == 0' %n); do
149
			if ! pkg info -e ${_pkg}; then
150
				_exec "pkg ${pkg_chroot} set -A 1 ${_pkg}" "Scheduling package ${_pkg} for removal"
151
			fi
152
		done
153

    
154
		# Check if all non-auto packages installed on current partition are
155
		# installed on 2nd one, if not, we need to fetch them
156
		for _pkg in $(pkg query -e '%a == 0' %n); do
157
			if ! pkg ${pkg_chroot} info -e ${_pkg}; then
158
				_pkgs_to_fetch="${_pkgs_to_fetch}${_pkgs_to_fetch:+ }${_pkg}"
159
			fi
160
		done
161

    
162
	fi
163

    
164
	_echo ">>> Downloading upgrade packages..."
165
	if ! pkg ${pkg_chroot} upgrade -F 2>&1 | tee -a ${logfile}; then
166
		_echo "ERROR: It was not possible to download packages"
167
		_exit 1
168
	fi
169

    
170
	if [ -n "${_pkgs_to_fetch}" ]; then
171
		_echo ">>> Fetching packages not present on upgrade partition..."
172
		if ! pkg ${pkg_chroot} fetch -d ${_pkgs_to_fetch} 2>&1 | tee -a ${logfile}; then
173
			_echo "ERROR: It was not possible to fetch packages"
174
			_exit 1
175
		fi
176
	fi
177
}
178

    
179
pkg_lock() {
180
	local _pkg="${1}"
181

    
182
	if [ -z "${_pkg}" ]; then
183
		return
184
	fi
185

    
186
	if [ "$(pkg ${pkg_chroot} query %k ${_pkg})" = "0" ]; then
187
		_exec "pkg ${pkg_chroot} lock ${_pkg}" "Locking package ${_pkg}" mute
188
	fi
189
}
190

    
191
pkg_unlock() {
192
	local _pkg="${1}"
193

    
194
	if [ -z "${_pkg}" ]; then
195
		return
196
	fi
197

    
198
	if [ "$(pkg ${pkg_chroot} query %k ${_pkg})" = "1" ]; then
199
		_exec "pkg ${pkg_chroot} unlock ${_pkg}" "Unlocking package ${_pkg}" mute
200
	fi
201
}
202

    
203
pkg_update() {
204
	local _run_update=1
205

    
206
	local _force=""
207
	if [ "${1}" = "force" ]; then
208
		local _force=1
209
	fi
210

    
211
	if [ -z "${_force}" -a -f ${last_update_file} ]; then
212
		local _last_update=$(head -n 1 ${last_update_file})
213
		# Verify if content contain only numbers
214
		if echo "${_last_update}" | grep -E -q '^[0-9]+$'; then
215
			local _now=$(date +%s)
216
			# Only run update hourly, and if last update is in the future
217
			[ ${_now} -gt ${_last_update} -a $((${_now} - ${_last_update})) -le $((60 * 60)) ] \
218
				&& unset _run_update
219
		fi
220
	fi
221

    
222
	[ -z "${_run_update}" ] \
223
		&& return 0
224

    
225
	_exec "pkg ${pkg_chroot} update" "Updating repositories" mute
226
	date +%s > ${last_update_file}
227
}
228

    
229
pkg_upgrade() {
230
	# figure out which kernel variant is running
231
	export kernel_pkg=$(pkg query %n $(pkg info ${product}-kernel-\*))
232

    
233
	if [ -z "${kernel_pkg}" ]; then
234
		_echo "ERROR: It was not possible to identify which ${product} kernel is installed"
235
		_exit 1
236
	fi
237

    
238
	export next_stage=$(pkg annotate -q -S ${kernel_pkg} next_stage)
239

    
240
	if [ -n "${next_stage}" -a -n "${booting}" -a -n "${boot_stage}" ]; then
241
		if [ ${boot_stage} != ${next_stage} ]; then
242
			_exit 0
243
		fi
244
	fi
245

    
246
	# If it's booting and first stage didn't run, just exit
247
	if [ -n "${booting}" -a -z "${next_stage}" ]; then
248
		_exit 0
249
	fi
250

    
251
	unset need_reboot
252
	# First upgrade stage
253
	if [ -z "${next_stage}" ]; then
254
		if [ -f "${logfile}" ]; then
255
			rm -f ${logfile}
256
		fi
257

    
258
		pkg_update
259

    
260
		if [ "$(compare_pkg_version pkg)" = "<" ]; then
261
			_exec "pkg upgrade pkg" "Upgrading pkg" mute
262
			pkg_update force
263
		fi
264

    
265
		if [ $(pkg upgrade -nq | wc -l) -le 1 ]; then
266
			_echo "Your packages are up to date"
267
			_exit 0
268
		fi
269

    
270
		if [ $(pkg upgrade -r ${product}-core -nq | wc -l) -gt 1 ]; then
271
			setup_nanobsd_env
272
			need_reboot=1
273
		fi
274

    
275
		pkg_unlock ${kernel_pkg}
276

    
277
		if [ "${platform}" = "nanobsd" ] && \
278
		   [ $(pkg ${pkg_chroot} upgrade -nq | wc -l) -le 1 ]; then
279
			_echo "**** WARNING ****"
280
			_echo "Reboot will be required!!"
281
			_echo "Secondary partition is up to date"
282
			if [ -z "${yes}" ]; then
283
				_echo -n "Proceed with upgrade? (y/N) "
284
				read answer
285
				if [ "${answer}" != "y" ]; then
286
					_echo "Aborting..."
287
					_exit 0
288
				fi
289
			fi
290
			switch_active_nanobsd_partition
291
			/etc/rc.reboot &
292
			_exit 0
293
		fi
294

    
295
		if [ -z "${yes}" ]; then
296
			# Show user which packages are going to be upgraded
297
			pkg ${pkg_chroot} upgrade -nq 2>&1 | tee -a ${logfile}
298

    
299
			_echo ""
300
			if [ -n "${need_reboot}" ]; then
301
				_echo "**** WARNING ****"
302
				_echo "Reboot will be required!!"
303
			fi
304
			_echo -n "Proceed with upgrade? (y/N) "
305
			read answer
306
			if [ "${answer}" != "y" ]; then
307
				_echo "Aborting..."
308
				_exit 0
309
			fi
310
		fi
311

    
312
		# Download all upgrade packages first
313
		fetch_upgrade_packages
314

    
315
		if [ $(pkg ${pkg_chroot} upgrade -nq ${kernel_pkg} | wc -l) -gt 1 ]; then
316
			_exec "pkg ${pkg_chroot} upgrade ${kernel_pkg}" "Upgrading ${product} kernel"
317
		fi
318

    
319
		pkg ${pkg_chroot} annotate -q -M ${kernel_pkg} next_stage 2
320
		next_stage=2
321

    
322
		if [ -n "${need_reboot}" -a "${platform}" != "nanobsd" ]; then
323
			_echo "Rebooting..."
324
			/etc/rc.reboot &
325
			_exit 0
326
		fi
327
	fi
328

    
329
	if [ "${next_stage}" = "2" ]; then
330
		pkg_lock "${pkg_prefix}*"
331

    
332
		if [ $(pkg ${pkg_chroot} upgrade -nq | wc -l) -gt 1 ]; then
333
			_echo "Upgrading necessary packages..."
334
			if ! pkg ${pkg_chroot} upgrade 2>&1 | tee -a ${logfile}; then
335
				pkg ${pkg_chroot} annotate -q -D ${kernel_pkg} next_stage
336
				pkg_unlock "${pkg_prefix}*"
337
				_echo "ERROR: An error occurred when upgrade was running..."
338
				_exit 1
339
			fi
340
		fi
341

    
342
		# XXX: workaround for #5300
343
		sort -u ${chroot_dir}/usr/local/etc/php/extensions.ini > /tmp/extensions.ini
344
		mv /tmp/extensions.ini ${chroot_dir}/usr/local/etc/php/extensions.ini
345

    
346
		pkg ${pkg_chroot} annotate -q -M ${kernel_pkg} next_stage 3
347
		next_stage=3
348

    
349
		pkg_unlock "${pkg_prefix}*"
350

    
351
		if [ -n "${need_reboot}" -a "${platform}" = "nanobsd" ]; then
352
			switch_active_nanobsd_partition
353
			_echo "Rebooting..."
354
			/etc/rc.reboot &
355
			_exit 0
356
		fi
357

    
358
		if [ -n "${booting}" ]; then
359
			_exit 0
360
		fi
361
	fi
362

    
363
	if [ "${next_stage}" = "3" ]; then
364
		if [ $(pkg upgrade -nq | wc -l) -gt 1 ]; then
365
			_echo "Upgrading necessary packages..."
366
			if ! pkg ${pkg_chroot} upgrade 2>&1 | tee -a ${logfile}; then
367
				pkg ${pkg_chroot} annotate -q -D ${kernel_pkg} next_stage
368
				_echo "ERROR: An error occurred when upgrade was running..."
369
				_exit 1
370
			fi
371
		fi
372

    
373
		pkg ${pkg_chroot} annotate -q -D ${kernel_pkg} next_stage
374

    
375
		# cleanup caches
376
		_exec "pkg ${pkg_chroot} autoremove" "Removing unnecessary packages" mute ignore_result
377
		_exec "pkg ${pkg_chroot} clean" "Cleanup pkg cache" mute ignore_result
378
	fi
379
}
380

    
381
setup_nanobsd_env() {
382
	if [ "${platform}" != "nanobsd" ]; then
383
		return;
384
	fi
385

    
386
	chroot_dir=/tmp/nanobsd_upgrade
387
	mkdir -p ${chroot_dir} 2>/dev/null
388
	local _cur_partition=$(mount -p / | cut -f1)
389
	local _update_partition=$(echo ${_cur_partition} | sed -e 's,0$,2,; s,1$,0,; s,2$,1,')
390

    
391
	if [ ! -e "${_update_partition}" ]; then
392
		_echo "Secondary partition (${_update_partition}), used for upgrade not found"
393
		_exit 1
394
	fi
395

    
396
	_exec "mount ${_update_partition} ${chroot_dir}" "Mounting second partition to run upgrade" mute
397

    
398
	pkg_chroot="-c ${chroot_dir}"
399

    
400
	pkg_update force
401

    
402
	if [ "$(compare_pkg_version pkg)" = "<" ]; then
403
		_exec "pkg ${pkg_chroot} upgrade pkg" "Upgrading pkg" mute
404
		pkg_update force
405
	fi
406

    
407
}
408

    
409
switch_active_nanobsd_partition() {
410
	if [ "${platform}" != "nanobsd" ]; then
411
		return;
412
	fi
413

    
414
	local _cur_partition=$(mount -p / | cut -f1 | sed 's,^/dev/,,')
415
	local _disk=$(glabel status -s | \
416
		awk "\$1 == \"${_cur_partition}\" { print substr(\$3, 0, length(\$3)-3)}")
417
	local _i=$(echo ${_cur_partition} | cut -c ${#_cur_partition})
418

    
419
	if ! echo "${_i}" | egrep -q '^[0-9]$'; then
420
		_echo "Invalid partition label ${_cur_partition}"
421
		_exit 1
422
	fi
423

    
424
	# pfsense0 == part 1 / pfsense1 == part 2
425
	if [ ${_i} -eq 0 ]; then
426
		_i=2
427
	else
428
		_i=1
429
	fi
430

    
431
	_exec "gpart set -a active -i ${_i} ${_disk}" "Setting secondary partition as active" mute
432
}
433

    
434
is_pkg_installed() {
435
	local _pkg_name="${1}"
436
	shift
437
	local _pkg_chroot="$@"
438

    
439
	pkg ${_pkg_chroot} info -e ${_pkg_name}
440
	return $?
441
}
442

    
443
compare_pkg_version() {
444
	local _pkg_name="${1}"
445

    
446
	if ! is_pkg_installed ${_pkg_name} ${pkg_chroot}; then
447
		echo '!'
448
		return -1
449
	fi
450

    
451
	local _lver=$(pkg ${pkg_chroot} query %v ${_pkg_name})
452

    
453
	if [ -z "${_lver}" ]; then
454
		_echo "ERROR: It was not possible to determine ${_pkg_name} local version"
455
		_exit 1
456
	fi
457

    
458
	local _rver=$(pkg ${pkg_chroot} rquery %v ${_pkg_name})
459

    
460
	if [ -z "${_rver}" ]; then
461
		_echo "ERROR: It was not possible to determine ${_pkg_name} remote version"
462
		_exit 1
463
	fi
464

    
465
	local _version=$(pkg version -t ${_lver} ${_rver})
466

    
467
	if [ $? -ne 0 ]; then
468
		_echo "ERROR: Error comparing ${_pkg_name} local and remote versions"
469
		_exit 1
470
	fi
471

    
472
	echo ${_version}
473
	return 0
474
}
475

    
476
pkg_install() {
477
	local _pkg_name="${1}"
478

    
479
	local _force=""
480
	if [ -n "${2}" ]; then
481
		_force="-f"
482
	fi
483

    
484
	if [ -z "${_pkg_name}" ]; then
485
		_echo "ERROR: Blank package name"
486
		_exit 1
487
	fi
488

    
489
	pkg_update
490

    
491
	if is_pkg_installed ${_pkg_name}; then
492
		local _cversion=$(compare_pkg_version ${_pkg_name})
493

    
494
		if [ -z "${_force}" ]; then
495
			if [ "${_cversion}" = "=" ]; then
496
				_echo "Package ${_pkg_name} is up to date"
497
				_exit 0
498
			elif [ "${_cversion}" = ">" ]; then
499
				_echo "Installed ${_pkg_name} version is newer than remote"
500
				_exit 0
501
			fi
502
		fi
503
		local _cmd="upgrade ${_force}"
504
		local _msg="Upgrading"
505
	else
506
		local _cmd="install"
507
		local _msg="Installing"
508
	fi
509

    
510
	_exec "pkg ${_cmd} ${_pkg_name}" "${_msg} ${_pkg_name}"
511
	_exec "pkg clean" "Cleaning up cache" mute ignore_result
512
}
513

    
514
pkg_delete() {
515
	local _pkg_name="${1}"
516

    
517
	if [ -z "${_pkg_name}" ]; then
518
		_echo "ERROR: Blank package name"
519
		_exit 1
520
	fi
521

    
522
	if ! is_pkg_installed ${_pkg_name}; then
523
		_echo "ERROR: Package ${_pkg_name} is not installed"
524
		_exit 1
525
	fi
526

    
527
	_exec "pkg delete ${_pkg_name}" "Removing ${_pkg_name}"
528
	_exec "pkg autoremove" "Removing stale packages" mute ignore_result
529
}
530

    
531
pid_file="/var/run/$(basename $0).pid"
532
last_update_file="/var/run/$(basename $0)-last-update"
533
logfile="/cf/conf/upgrade_log.txt"
534
stdout='/dev/null'
535

    
536
# pkg should not ask for confirmations
537
export ASSUME_ALWAYS_YES=true
538

    
539
# Disable automatic update
540
export REPO_AUTOUPDATE=false
541

    
542
export product=$(/usr/local/bin/php -n /usr/local/sbin/read_global_var product_name pfSense)
543
export pkg_prefix=$(/usr/local/bin/php -n /usr/local/sbin/read_global_var pkg_prefix pfSense-pkg-)
544
export platform=$(cat /etc/platform)
545

    
546
USE_MFS_TMPVAR=$(/usr/local/sbin/read_xml_tag.sh boolean system/use_mfs_tmpvar)
547
if [ "${platform}" = "nanobsd" ] || [ "${USE_MFS_TMPVAR}" = "true" ]; then
548
	export PKG_DBDIR=/root/var/db/pkg
549
	export PKG_CACHEDIR=/root/var/cache/pkg
550
fi
551

    
552
# Upgrade process on nanobsd will happen in chroot
553
export pkg_chroot=""
554
export chroot_dir=""
555

    
556
unset booting
557
unset boot_stage
558
unset force
559
unset yes
560
unset progress_fifo
561
unset action
562
unset action_pkg
563
while getopts b:dfi:hp:l:r:uy opt; do
564
	case ${opt} in
565
		b)
566
			booting=1
567
			boot_stage="${OPTARG}"
568
			;;
569
		d)
570
			stdout=''
571
			;;
572
		f)
573
			force=1
574
			;;
575
		i)
576
			if [ -n "${action}" ]; then
577
				usage
578
				_exit 1
579
			fi
580
			action="install"
581
			action_pkg="${OPTARG}"
582
			;;
583
		h)
584
			usage
585
			_exit 0
586
			;;
587
		l)
588
			logfile="${OPTARG}"
589
			if [ -z "${logfile}" ]; then
590
				usage
591
				_exit 1
592
			fi
593
			;;
594
		p)
595
			progress_fifo="${OPTARG}"
596
			;;
597
		r)
598
			if [ -n "${action}" ]; then
599
				usage
600
				_exit 1
601
			fi
602
			action="delete"
603
			action_pkg="${OPTARG}"
604
			;;
605
		u)
606
			if [ -n "${action}" ]; then
607
				usage
608
				_exit 1
609
			fi
610
			action="update"
611
			;;
612
		y)
613
			yes=1
614
			;;
615
		*)
616
			usage
617
			_exit 1
618
			;;
619
	esac
620
done
621

    
622
# Set default action when no parameter is set
623
: ${action:="upgrade"}
624

    
625
if pgrep -qF ${pid_file} >/dev/null 2>&1; then
626
	echo "Another instance is already running... Aborting!"
627
	exit 1
628
fi
629

    
630
if [ -z "${booting}" -o "${boot_stage}" != "2" ]; then
631
	/etc/rc.conf_mount_rw
632
fi
633

    
634
echo $$ > ${pid_file}
635

    
636
trap _exit 1 2 15 EXIT
637

    
638
if [ -n "${progress_fifo}" ]; then
639
	if [ ! -e "${progress_fifo}" ]; then
640
		mkfifo ${progress_fifo}
641
	fi
642
	if [ ! -p "${progress_fifo}" ]; then
643
		_echo "ERROR: ${progress_fifo} is not a FIFO"
644
		_exit 1
645
	fi
646
	if [ -e "${progress_fifo}.json" ]; then
647
		rm -f ${progress_fifo}.json
648
	fi
649
	# Read fifo and save content to a file in background
650
	# GUI will read progress from file
651
	tail -f ${progress_fifo} > ${progress_fifo}.json &
652
	export EVENT_PIPE="${progress_fifo}"
653
fi
654

    
655
case "${action}" in
656
	upgrade)
657
		pkg_upgrade
658
		;;
659
	update)
660
		pkg_update force
661
		;;
662
	install)
663
		pkg_install ${action_pkg} ${force}
664
		;;
665
	delete)
666
		pkg_delete ${action_pkg}
667
		;;
668
	*)
669
		_echo "ERROR: Invalid action!"
670
		_exit 1
671
esac
672

    
673
_exit 0
(10-10/23)