2019-02-08 04:38:12 +05:30
|
|
|
#!@SHELL@
|
2015-04-27 00:01:49 +05:30
|
|
|
# Shell wrapper for openrc-run
|
2007-11-14 20:52:04 +05:30
|
|
|
|
2015-12-05 04:22:19 +05:30
|
|
|
# Copyright (c) 2007-2015 The OpenRC Authors.
|
|
|
|
# See the Authors file at the top-level directory of this distribution and
|
|
|
|
# https://github.com/OpenRC/openrc/blob/master/AUTHORS
|
|
|
|
#
|
|
|
|
# This file is part of OpenRC. It is subject to the license terms in
|
|
|
|
# the LICENSE file found in the top-level directory of this
|
|
|
|
# distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
|
|
|
|
# This file may not be copied, modified, propagated, or distributed
|
|
|
|
# except according to the terms contained in the LICENSE file.
|
2007-11-14 20:52:04 +05:30
|
|
|
|
2012-03-03 20:46:27 +05:30
|
|
|
verify_boot()
|
|
|
|
{
|
|
|
|
if [ ! -e ${RC_SVCDIR}/softlevel ]; then
|
|
|
|
eerror "You are attempting to run an openrc service on a"
|
|
|
|
eerror "system which openrc did not boot."
|
|
|
|
eerror "You may be inside a chroot or you may have used"
|
|
|
|
eerror "another initialization system to boot this system."
|
|
|
|
eerror "In this situation, you will get unpredictable results!"
|
|
|
|
eerror
|
|
|
|
eerror "If you really want to do this, issue the following command:"
|
|
|
|
eerror "touch ${RC_SVCDIR}/softlevel"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2011-01-09 01:55:32 +05:30
|
|
|
sourcex()
|
|
|
|
{
|
|
|
|
if [ "$1" = "-e" ]; then
|
|
|
|
shift
|
|
|
|
[ -e "$1" ] || return 1
|
|
|
|
fi
|
|
|
|
if ! . "$1"; then
|
|
|
|
eerror "$RC_SVCNAME: error loading $1"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2012-04-26 23:26:44 +05:30
|
|
|
sourcex "@LIBEXECDIR@/sh/functions.sh"
|
2011-11-02 18:46:52 +05:30
|
|
|
sourcex "@LIBEXECDIR@/sh/rc-functions.sh"
|
2015-04-29 01:37:21 +05:30
|
|
|
case $RC_SYS in
|
|
|
|
PREFIX|SYSTEMD-NSPAWN) ;;
|
|
|
|
*) sourcex -e "@LIBEXECDIR@/sh/rc-cgroup.sh";;
|
|
|
|
esac
|
2011-11-02 18:46:52 +05:30
|
|
|
|
|
|
|
# Support LiveCD foo
|
|
|
|
if sourcex -e "/sbin/livecd-functions.sh"; then
|
|
|
|
livecd_read_commandline
|
|
|
|
fi
|
|
|
|
|
2007-11-20 15:54:40 +05:30
|
|
|
if [ -z "$1" -o -z "$2" ]; then
|
2009-04-27 02:43:26 +05:30
|
|
|
eerror "$RC_SVCNAME: not enough arguments"
|
2007-04-05 16:48:42 +05:30
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2008-03-11 20:30:16 +05:30
|
|
|
# So daemons know where to recall us if needed
|
2012-11-07 05:52:33 +05:30
|
|
|
RC_SERVICE="$1" ; export RC_SERVICE
|
2008-04-27 01:02:28 +05:30
|
|
|
shift
|
2008-03-11 20:30:16 +05:30
|
|
|
|
2008-03-20 01:27:24 +05:30
|
|
|
# Compat
|
2012-11-07 05:52:33 +05:30
|
|
|
SVCNAME=$RC_SVCNAME ; export SVCNAME
|
2008-03-20 01:27:24 +05:30
|
|
|
|
2009-09-04 20:30:08 +05:30
|
|
|
# Dependency function
|
|
|
|
config() {
|
|
|
|
[ -n "$*" ] && echo "config $*"
|
|
|
|
}
|
|
|
|
need() {
|
|
|
|
[ -n "$*" ] && echo "need $*"
|
|
|
|
}
|
|
|
|
use() {
|
|
|
|
[ -n "$*" ] && echo "use $*"
|
|
|
|
}
|
2015-10-27 00:50:58 +05:30
|
|
|
want() {
|
|
|
|
[ -n "$*" ] && echo "want $*"
|
|
|
|
}
|
2009-09-04 20:30:08 +05:30
|
|
|
before() {
|
|
|
|
[ -n "$*" ] && echo "before $*"
|
|
|
|
}
|
|
|
|
after() {
|
|
|
|
[ -n "$*" ] && echo "after $*"
|
|
|
|
}
|
|
|
|
provide() {
|
|
|
|
[ -n "$*" ] && echo "provide $*"
|
|
|
|
}
|
|
|
|
keyword() {
|
2015-12-04 01:39:38 +05:30
|
|
|
local c x
|
|
|
|
set -- $*
|
|
|
|
while [ -n "$*" ]; do
|
|
|
|
case "$1" in
|
|
|
|
-containers) x="$(_get_containers)" ;;
|
|
|
|
!-containers) x="$(_get_containers_remove)" ;;
|
|
|
|
*) x=$1 ;;
|
|
|
|
esac
|
|
|
|
c="${c}${x} "
|
|
|
|
shift
|
|
|
|
done
|
|
|
|
[ -n "$c" ] && echo "keyword $c"
|
2009-09-04 20:30:08 +05:30
|
|
|
}
|
|
|
|
|
2011-10-17 04:32:21 +05:30
|
|
|
# Describe the init script to the user
|
2008-01-11 17:43:46 +05:30
|
|
|
describe()
|
|
|
|
{
|
2009-04-27 02:43:26 +05:30
|
|
|
if [ -n "$description" ]; then
|
|
|
|
einfo "$description"
|
2007-07-11 00:39:41 +05:30
|
|
|
else
|
2009-04-27 02:43:26 +05:30
|
|
|
ewarn "No description for $RC_SVCNAME"
|
2007-07-11 00:39:41 +05:30
|
|
|
fi
|
|
|
|
|
|
|
|
local svc= desc=
|
2011-10-18 00:17:45 +05:30
|
|
|
for svc in ${extra_commands:-$opts} $extra_started_commands \
|
|
|
|
$extra_stopped_commands; do
|
2009-04-27 02:43:26 +05:30
|
|
|
eval desc=\$description_$svc
|
|
|
|
if [ -n "$desc" ]; then
|
|
|
|
einfo "$HILITE$svc$NORMAL: $desc"
|
2007-07-11 00:39:41 +05:30
|
|
|
else
|
2009-04-27 02:43:26 +05:30
|
|
|
ewarn "$HILITE$svc$NORMAL: no description"
|
2007-07-11 00:39:41 +05:30
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2009-04-18 05:39:03 +05:30
|
|
|
# Report status
|
2009-04-18 16:09:53 +05:30
|
|
|
_status()
|
2009-04-18 05:39:03 +05:30
|
|
|
{
|
|
|
|
if service_stopping; then
|
|
|
|
ewarn "status: stopping"
|
|
|
|
return 4
|
|
|
|
elif service_starting; then
|
|
|
|
ewarn "status: starting"
|
|
|
|
return 8
|
|
|
|
elif service_inactive; then
|
|
|
|
ewarn "status: inactive"
|
|
|
|
return 16
|
2018-05-22 21:42:12 +05:30
|
|
|
elif service_crashed; then
|
|
|
|
eerror "status: crashed"
|
|
|
|
return 32
|
2009-04-18 05:39:03 +05:30
|
|
|
elif service_started; then
|
|
|
|
einfo "status: started"
|
|
|
|
return 0
|
|
|
|
else
|
|
|
|
einfo "status: stopped"
|
2011-01-13 07:16:11 +05:30
|
|
|
return 3
|
2009-04-18 05:39:03 +05:30
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2015-05-10 04:26:45 +05:30
|
|
|
# These functions select the appropriate function to call from the
|
|
|
|
# supervisor modules
|
2016-12-16 04:13:34 +05:30
|
|
|
default_start()
|
2015-05-10 04:26:45 +05:30
|
|
|
{
|
|
|
|
local func=ssd_start
|
|
|
|
case "$supervisor" in
|
2016-07-28 02:56:26 +05:30
|
|
|
runit) func=runit_start ;;
|
2015-05-12 04:37:28 +05:30
|
|
|
s6) func=s6_start ;;
|
2016-02-02 00:12:58 +05:30
|
|
|
supervise-daemon) func=supervise_start ;;
|
2015-05-10 04:26:45 +05:30
|
|
|
?*)
|
|
|
|
ewarn "Invalid supervisor, \"$supervisor\", using start-stop-daemon"
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
$func
|
|
|
|
}
|
|
|
|
|
2016-12-16 04:13:34 +05:30
|
|
|
default_stop()
|
2015-05-10 04:26:45 +05:30
|
|
|
{
|
|
|
|
local func=ssd_stop
|
|
|
|
case "$supervisor" in
|
2016-07-28 02:56:26 +05:30
|
|
|
runit) func=runit_stop ;;
|
2015-05-12 04:37:28 +05:30
|
|
|
s6) func=s6_stop ;;
|
2016-02-02 00:12:58 +05:30
|
|
|
supervise-daemon) func=supervise_stop ;;
|
2015-05-10 04:26:45 +05:30
|
|
|
?*)
|
|
|
|
ewarn "Invalid supervisor, \"$supervisor\", using start-stop-daemon"
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
$func
|
|
|
|
}
|
|
|
|
|
2016-12-16 04:13:34 +05:30
|
|
|
default_status()
|
2015-05-10 04:26:45 +05:30
|
|
|
{
|
|
|
|
local func=ssd_status
|
|
|
|
case "$supervisor" in
|
2016-07-28 02:56:26 +05:30
|
|
|
runit) func=runit_status ;;
|
2015-05-12 04:37:28 +05:30
|
|
|
s6) func=s6_status ;;
|
2016-02-02 00:12:58 +05:30
|
|
|
supervise-daemon) func=supervise_status ;;
|
2015-05-10 04:26:45 +05:30
|
|
|
?*)
|
|
|
|
ewarn "Invalid supervisor, \"$supervisor\", using start-stop-daemon"
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
$func
|
|
|
|
}
|
|
|
|
|
2016-12-16 04:13:34 +05:30
|
|
|
# Template start / stop / status functions
|
|
|
|
# package init scripts may override these, but the bodies are as minimal as
|
|
|
|
# possible, so that the init scripts can creatively wrap default_*
|
|
|
|
# functions.
|
|
|
|
start()
|
|
|
|
{
|
|
|
|
default_start
|
|
|
|
}
|
|
|
|
|
|
|
|
stop()
|
|
|
|
{
|
|
|
|
default_stop
|
|
|
|
}
|
|
|
|
|
|
|
|
status()
|
|
|
|
{
|
|
|
|
default_status
|
|
|
|
}
|
|
|
|
|
|
|
|
# Start debug output
|
2009-04-27 02:43:26 +05:30
|
|
|
yesno $RC_DEBUG && set -x
|
2007-04-05 16:48:42 +05:30
|
|
|
|
2016-09-05 21:50:03 +05:30
|
|
|
# Load configuration settings. First the global ones, then any
|
|
|
|
# service-specific settings.
|
|
|
|
sourcex -e "@SYSCONFDIR@/rc.conf"
|
|
|
|
if [ -d "@SYSCONFDIR@/rc.conf.d" ]; then
|
|
|
|
for _f in "@SYSCONFDIR@"/rc.conf.d/*.conf; do
|
|
|
|
sourcex -e "$_f"
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
|
2011-12-11 12:48:08 +05:30
|
|
|
_conf_d=${RC_SERVICE%/*}/../conf.d
|
|
|
|
# If we're net.eth0 or openvpn.work then load net or openvpn config
|
|
|
|
_c=${RC_SVCNAME%%.*}
|
|
|
|
if [ -n "$_c" -a "$_c" != "$RC_SVCNAME" ]; then
|
|
|
|
if ! sourcex -e "$_conf_d/$_c.$RC_RUNLEVEL"; then
|
|
|
|
sourcex -e "$_conf_d/$_c"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
unset _c
|
|
|
|
|
|
|
|
# Overlay with our specific config
|
|
|
|
if ! sourcex -e "$_conf_d/$RC_SVCNAME.$RC_RUNLEVEL"; then
|
|
|
|
sourcex -e "$_conf_d/$RC_SVCNAME"
|
2007-04-05 16:48:42 +05:30
|
|
|
fi
|
2011-12-11 12:48:08 +05:30
|
|
|
unset _conf_d
|
2007-04-05 16:48:42 +05:30
|
|
|
|
2015-05-10 04:26:45 +05:30
|
|
|
# load service supervisor functions
|
2016-07-28 02:56:26 +05:30
|
|
|
sourcex "@LIBEXECDIR@/sh/runit.sh"
|
2015-05-12 04:37:28 +05:30
|
|
|
sourcex "@LIBEXECDIR@/sh/s6.sh"
|
2015-05-08 21:59:49 +05:30
|
|
|
sourcex "@LIBEXECDIR@/sh/start-stop-daemon.sh"
|
2016-02-02 00:12:58 +05:30
|
|
|
sourcex "@LIBEXECDIR@/sh/supervise-daemon.sh"
|
2015-05-08 21:59:49 +05:30
|
|
|
|
2017-08-16 03:45:14 +05:30
|
|
|
# Load our script
|
|
|
|
sourcex "$RC_SERVICE"
|
|
|
|
|
2015-03-30 01:50:52 +05:30
|
|
|
# Set verbose mode
|
|
|
|
if yesno "${rc_verbose:-$RC_VERBOSE}"; then
|
|
|
|
EINFO_VERBOSE=yes
|
|
|
|
export EINFO_VERBOSE
|
|
|
|
fi
|
|
|
|
|
2014-09-11 23:56:58 +05:30
|
|
|
for _cmd; do
|
|
|
|
if [ "$_cmd" != status -a "$_cmd" != describe ]; then
|
|
|
|
# Apply any ulimit defined
|
2021-01-06 04:32:30 +05:30
|
|
|
if [ -n "${rc_ulimit:-$RC_ULIMIT}" ]; then
|
|
|
|
if ! ulimit ${rc_ulimit:-$RC_ULIMIT}; then
|
2021-01-06 04:41:01 +05:30
|
|
|
eerror "${RC_SVCNAME}: unable to apply RC_ULIMIT settings"
|
2021-01-06 04:32:30 +05:30
|
|
|
fi
|
|
|
|
fi
|
2014-09-11 23:56:58 +05:30
|
|
|
# Apply cgroups settings if defined
|
2017-09-14 21:08:10 +05:30
|
|
|
if [ "$(command -v cgroup_add_service)" = "cgroup_add_service" ]
|
2014-09-11 23:56:58 +05:30
|
|
|
then
|
2018-02-12 18:02:01 +05:30
|
|
|
if grep -qs /sys/fs/cgroup /proc/1/mountinfo
|
|
|
|
then
|
|
|
|
if [ -d /sys/fs/cgroup -a ! -w /sys/fs/cgroup ]; then
|
|
|
|
eerror "No permission to apply cgroup settings"
|
|
|
|
break
|
|
|
|
fi
|
2014-09-11 23:56:58 +05:30
|
|
|
fi
|
2017-12-02 03:13:09 +05:30
|
|
|
cgroup_add_service
|
2014-09-11 23:56:58 +05:30
|
|
|
fi
|
2017-09-14 21:08:10 +05:30
|
|
|
[ "$(command -v cgroup_set_limits)" = "cgroup_set_limits" ] &&
|
|
|
|
cgroup_set_limits
|
|
|
|
[ "$(command -v cgroup2_set_limits)" = "cgroup2_set_limits" ] &&
|
|
|
|
[ "$_cmd" = start ] &&
|
|
|
|
cgroup2_set_limits
|
2014-09-11 23:56:58 +05:30
|
|
|
break
|
2014-07-10 15:48:00 +05:30
|
|
|
fi
|
2014-09-11 23:56:58 +05:30
|
|
|
done
|
2016-01-22 23:24:16 +05:30
|
|
|
|
2015-10-13 18:29:50 +05:30
|
|
|
eval "printf '%s\n' $required_dirs" | while read _d; do
|
2015-10-14 02:20:59 +05:30
|
|
|
if [ -n "$_d" ] && [ ! -d "$_d" ]; then
|
2009-04-27 02:43:26 +05:30
|
|
|
eerror "$RC_SVCNAME: \`$_d' is not a directory"
|
2007-11-28 18:38:25 +05:30
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
done
|
2015-10-14 04:12:46 +05:30
|
|
|
[ $? -ne 0 ] && exit 1
|
2007-11-28 18:38:25 +05:30
|
|
|
unset _d
|
|
|
|
|
2015-10-13 18:29:50 +05:30
|
|
|
eval "printf '%s\n' $required_files" | while read _f; do
|
2015-10-14 02:20:59 +05:30
|
|
|
if [ -n "$_f" ] && [ ! -r "$_f" ]; then
|
2009-04-27 02:43:26 +05:30
|
|
|
eerror "$RC_SVCNAME: \`$_f' is not readable"
|
2007-11-28 18:38:25 +05:30
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
done
|
2015-10-14 04:12:46 +05:30
|
|
|
[ $? -ne 0 ] && exit 1
|
2007-11-28 18:38:25 +05:30
|
|
|
unset _f
|
|
|
|
|
2011-07-26 22:49:59 +05:30
|
|
|
if [ -n "$opts" ]; then
|
|
|
|
ewarn "Use of the opts variable is deprecated and will be"
|
|
|
|
ewarn "removed in the future."
|
2011-10-18 00:17:45 +05:30
|
|
|
ewarn "Please use extra_commands, extra_started_commands or extra_stopped_commands."
|
2011-07-26 22:49:59 +05:30
|
|
|
fi
|
|
|
|
|
2007-11-20 15:54:40 +05:30
|
|
|
while [ -n "$1" ]; do
|
2011-10-17 04:32:21 +05:30
|
|
|
# Special case depend
|
2010-02-21 03:18:06 +05:30
|
|
|
if [ "$1" = depend ]; then
|
|
|
|
shift
|
2012-04-26 22:49:42 +05:30
|
|
|
|
|
|
|
# Enter the dir of the init script to fix the globbing
|
|
|
|
# bug 412677
|
|
|
|
cd ${RC_SERVICE%/*}
|
2010-02-21 03:18:06 +05:30
|
|
|
_depend
|
2012-04-26 22:49:42 +05:30
|
|
|
cd /
|
2010-02-21 03:18:06 +05:30
|
|
|
continue
|
|
|
|
fi
|
2007-04-05 16:48:42 +05:30
|
|
|
# See if we have the required function and run it
|
2010-02-21 03:18:06 +05:30
|
|
|
for _cmd in describe start stop status ${extra_commands:-$opts} \
|
2011-10-18 00:17:45 +05:30
|
|
|
$extra_started_commands $extra_stopped_commands
|
2009-04-27 02:43:26 +05:30
|
|
|
do
|
|
|
|
if [ "$_cmd" = "$1" ]; then
|
2008-04-21 23:02:17 +05:30
|
|
|
if [ "$(command -v "$1")" = "$1" ]; then
|
2008-01-11 17:43:46 +05:30
|
|
|
# If we're in the background, we may wish to
|
|
|
|
# fake some commands. We do this so we can
|
|
|
|
# "start" ourselves from inactive which then
|
2009-04-27 02:43:26 +05:30
|
|
|
# triggers other services to start which
|
|
|
|
# depend on us.
|
|
|
|
# A good example of this is openvpn.
|
|
|
|
if yesno $IN_BACKGROUND; then
|
|
|
|
for _cmd in $in_background_fake; do
|
|
|
|
if [ "$_cmd" = "$1" ]; then
|
2007-11-28 18:38:25 +05:30
|
|
|
shift
|
|
|
|
continue 3
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
fi
|
2008-01-11 17:43:46 +05:30
|
|
|
# Check to see if we need to be started before
|
|
|
|
# we can run this command
|
2009-04-27 02:43:26 +05:30
|
|
|
for _cmd in $extra_started_commands; do
|
|
|
|
if [ "$_cmd" = "$1" ]; then
|
2012-03-03 20:46:27 +05:30
|
|
|
if verify_boot && ! service_started; then
|
2009-04-27 02:43:26 +05:30
|
|
|
eerror "$RC_SVCNAME: cannot \`$1' as it has not been started"
|
2007-11-29 21:53:59 +05:30
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
done
|
2011-10-18 00:17:45 +05:30
|
|
|
# Check to see if we need to be stopped before
|
|
|
|
# we can run this command
|
|
|
|
for _cmd in $extra_stopped_commands; do
|
|
|
|
if [ "$_cmd" = "$1" ]; then
|
2012-03-03 20:46:27 +05:30
|
|
|
if verify_boot && ! service_stopped; then
|
2011-10-18 00:17:45 +05:30
|
|
|
eerror "$RC_SVCNAME: cannot \`$1' as it has not been stopped"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
done
|
2007-11-28 18:38:25 +05:30
|
|
|
unset _cmd
|
2012-03-03 20:46:27 +05:30
|
|
|
case $1 in
|
|
|
|
start|stop|status) verify_boot;;
|
|
|
|
esac
|
2009-04-27 02:43:26 +05:30
|
|
|
if [ "$(command -v "$1_pre")" = "$1_pre" ]
|
|
|
|
then
|
2007-11-20 15:54:40 +05:30
|
|
|
"$1"_pre || exit $?
|
|
|
|
fi
|
2007-04-05 16:48:42 +05:30
|
|
|
"$1" || exit $?
|
2009-04-27 02:43:26 +05:30
|
|
|
if [ "$(command -v "$1_post")" = "$1_post" ]
|
|
|
|
then
|
2007-11-20 15:54:40 +05:30
|
|
|
"$1"_post || exit $?
|
|
|
|
fi
|
2017-09-14 21:25:06 +05:30
|
|
|
[ "$(command -v cgroup_cleanup)" = "cgroup_cleanup" ] &&
|
|
|
|
[ "$1" = "stop" ] &&
|
|
|
|
yesno "${rc_cgroup_cleanup}" && \
|
2013-04-16 11:22:33 +05:30
|
|
|
cgroup_cleanup
|
2017-09-14 21:08:10 +05:30
|
|
|
if [ "$(command -v cgroup2_remove)" = "cgroup2_remove" ]; then
|
|
|
|
[ "$1" = stop ] || [ -z "${command}" ] &&
|
|
|
|
cgroup2_remove
|
|
|
|
fi
|
2007-04-05 16:48:42 +05:30
|
|
|
shift
|
|
|
|
continue 2
|
|
|
|
else
|
2009-04-27 02:43:26 +05:30
|
|
|
if [ "$_cmd" = "start" -o "$_cmd" = "stop" ]
|
|
|
|
then
|
2008-01-26 22:16:53 +05:30
|
|
|
shift
|
|
|
|
continue 2
|
2007-04-05 16:48:42 +05:30
|
|
|
else
|
2009-04-27 02:43:26 +05:30
|
|
|
eerror "$RC_SVCNAME: function \`$1' defined but does not exist"
|
2007-04-05 16:48:42 +05:30
|
|
|
exit 1
|
|
|
|
fi
|
2011-01-17 15:19:07 +05:30
|
|
|
fi
|
2007-04-05 16:48:42 +05:30
|
|
|
fi
|
|
|
|
done
|
2009-04-27 02:43:26 +05:30
|
|
|
eerror "$RC_SVCNAME: unknown function \`$1'"
|
2007-04-05 16:48:42 +05:30
|
|
|
exit 1
|
|
|
|
done
|
2011-11-13 02:49:55 +05:30
|
|
|
|
|
|
|
exit 0
|