summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Heim <phreak@gentoo.org>2006-01-10 16:48:26 +0000
committerChristian Heim <phreak@gentoo.org>2006-01-10 16:48:26 +0000
commit8785624e7d87434e65a11cad4d161fba517f09dd (patch)
tree92e8020076af9b0c49b2f6633c373c459fed5bc8
parentFixing the ChangeLog.vserver (again) (diff)
downloadbaselayout-vserver-8785624e7d87434e65a11cad4d161fba517f09dd.tar.gz
baselayout-vserver-8785624e7d87434e65a11cad4d161fba517f09dd.tar.bz2
baselayout-vserver-8785624e7d87434e65a11cad4d161fba517f09dd.zip
Merging r1799
svn path=/baselayout-vserver/branches/baselayout-1_12/; revision=201
-rw-r--r--ChangeLog17
-rw-r--r--ChangeLog.vserver27
-rwxr-xr-xbin/rc-status8
-rwxr-xr-xsbin/depscan.sh4
-rwxr-xr-xsbin/rc-services.sh50
-rwxr-xr-xsbin/runscript.sh241
6 files changed, 175 insertions, 172 deletions
diff --git a/ChangeLog b/ChangeLog
index 2112d53..24b12bb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,23 @@
# ChangeLog for Gentoo System Intialization ("rc") scripts
# Copyright 1999-2006 Gentoo Foundation; Distributed under the GPLv2
+ 10 Jan 2006; Roy Marples <uberlord@gentoo.org>:
+
+ Removed runlevel dependancies from runscript.sh as they're now in rc.
+
+ runscript.sh now has much better locking, #118418.
+
+ We now store services to restart when we end up as inactive from a restart
+ or we were stopped with IN_BACKGROUND=true, #112088.
+
+ We no longer stop and start services already running on runlevel change if
+ they're in the runlevel we're changing too.
+
+ We can now wait_sevice on services started outside of rc.
+
+ rc-status now reports "Could not locate" instead of "Could not local",
+ thanks to Christian Heim.
+
09 Jan 2006; Roy Marples <uberlord@gentoo.org>:
Ensure that specific configuration is loaded after net, #118368.
diff --git a/ChangeLog.vserver b/ChangeLog.vserver
index 3c7ed77..940cc68 100644
--- a/ChangeLog.vserver
+++ b/ChangeLog.vserver
@@ -3,19 +3,22 @@
10 Jan 2006; Christian Heim <phreak@gentoo.org>:
Merging latest changes to the baselayout-1_12 branch. This merge is based
- upon revision 1798.
+ upon revision 1799.
- ChangeLog | 23 ++++++++
- ChangeLog.vserver | 16 ++++++
- net-scripts/conf.d/wireless.example | 15 ++++-
- net-scripts/net.modules.d/bonding | 8 +--
- net-scripts/net.modules.d/helpers.d/module-loader | 4 +
- net-scripts/net.modules.d/iwconfig | 48 ++++++++++--------
- net-scripts/net.modules.d/wpa_supplicant | 4 -
- sbin/functions.sh | 8 +--
- sbin/rc | 21 +++++--
- sbin/runscript.sh | 35 +++++++------
- 10 files changed, 126 insertions(+), 56 deletions(-)
+ ChangeLog | 40 ++
+ ChangeLog.vserver | 19 +
+ bin/rc-status | 8
+ net-scripts/conf.d/wireless.example | 15
+ net-scripts/net.modules.d/bonding | 8
+ net-scripts/net.modules.d/helpers.d/module-loader | 4
+ net-scripts/net.modules.d/iwconfig | 48 +--
+ net-scripts/net.modules.d/wpa_supplicant | 4
+ sbin/depscan.sh | 4
+ sbin/functions.sh | 8
+ sbin/rc | 21 -
+ sbin/rc-services.sh | 50 +--
+ sbin/runscript.sh | 274 ++++++++----------
+ 13 files changed, 285 insertions(+), 215 deletions(-)
06 Jan 2006; Christian Heim <phreak@gentoo.org>:
Merging latest changes to the baselayout-1_12 branch. This merge is based
diff --git a/bin/rc-status b/bin/rc-status
index 299383c..05254fc 100755
--- a/bin/rc-status
+++ b/bin/rc-status
@@ -214,14 +214,14 @@ for level in ${runlevelidxs} ; do
|| " ${boot_crit} " != *" ${service} "* ]]; then
print_msg "${service}" "${BAD}" 'broken '
broken="${broken} ${service}"
+ elif [[ -n ${stopping} && $(in_list "${stopping}" "${service}") -eq 1 ]] ; then
+ print_msg "${service}" "${BAD}" 'stopping'
+ elif [[ -n ${starting} && $(in_list "${starting}" "${service}") -eq 1 ]] ; then
+ print_msg "${service}" "${GOOD}" 'starting'
elif [[ -n ${inactive} && $(in_list "${inactive}" "${service}") -eq 1 ]] ; then
print_msg "${service}" "${WARN}" 'inactive'
elif [[ $(in_list "${started}" "${service}") -eq 1 ]] ; then
print_msg "${service}" "${GOOD}" 'started '
- elif [[ -n ${starting} && $(in_list "${starting}" "${service}") -eq 1 ]] ; then
- print_msg "${service}" "${GOOD}" 'starting'
- elif [[ -n ${stopping} && $(in_list "${stopping}" "${service}") -eq 1 ]] ; then
- print_msg "${service}" "${BAD}" 'stopping'
else
print_msg "${service}" "${BAD}" 'stopped '
fi
diff --git a/sbin/depscan.sh b/sbin/depscan.sh
index 1fbf0ef..10590d0 100755
--- a/sbin/depscan.sh
+++ b/sbin/depscan.sh
@@ -9,7 +9,7 @@ if [[ $1 == "--debug" ]] ; then
set -x
fi
-if [[ ! -d ${svcdir} ]]; then
+if [[ ! -d ${svcdir} ]] ; then
if ! mkdir -p -m 0755 "${svcdir}" 2>/dev/null ; then
eerror "Could not create needed directory '${svcdir}'!"
fi
@@ -17,7 +17,7 @@ fi
for x in softscripts snapshot options daemons \
started starting inactive stopping failed \
- exclusive exitcodes ; do
+ exclusive exitcodes restart ; do
if [[ ! -d "${svcdir}/${x}" ]] ; then
if ! mkdir -p -m 0755 "${svcdir}/${x}" 2>/dev/null ; then
eerror "Could not create needed directory '${svcdir}/${x}'!"
diff --git a/sbin/rc-services.sh b/sbin/rc-services.sh
index 795a78c..d47482a 100755
--- a/sbin/rc-services.sh
+++ b/sbin/rc-services.sh
@@ -244,10 +244,7 @@ in_runlevel() {
# starting services.
#
is_runlevel_start() {
- [[ -d "${svcdir}/softscripts.old" && \
- ${SOFTLEVEL} != "${OLDSOFTLEVEL}" ]] && return 0
-
- return 1
+ [[ -d "${svcdir}/softscripts.old" ]]
}
# bool is_runlevel_stop()
@@ -256,10 +253,7 @@ is_runlevel_start() {
# stopping services.
#
is_runlevel_stop() {
- [[ -d "${svcdir}/softscripts.new" && \
- ${SOFTLEVEL} != "${OLDSOFTLEVEL}" ]] && return 0
-
- return 1
+ [[ -d "${svcdir}/softscripts.new" ]]
}
# void sevice_message([char *type] char *message)
@@ -290,10 +284,12 @@ service_message() {
# end_service service
# fi
begin_service() {
- [[ {$START_CRITICAL} == "yes" ]] && return 0
+ local service="$1"
+ [[ -z ${service} ]] && return 1
+
+ [[ ${START_CRITICAL} == "yes" ]] && return 0
mkfifo "${svcdir}/exclusive/${service}" 2> /dev/null
- return $?
}
# void end_service(service, exitcode)
@@ -303,6 +299,7 @@ begin_service() {
#
end_service() {
local service="$1" exitstatus="$2"
+ [[ -z ${service} ]] && return
# if we are doing critical services, there is no fifo
[[ ${START_CRITICAL} == "yes" ]] && return
@@ -357,7 +354,7 @@ start_service() {
mark_service_stopped "${service}"
return 1
fi
-
+
service_starting "${service}" && return 0
service_started "${service}" && return 0
service_inactive "${service}" && return 1
@@ -439,14 +436,11 @@ stop_service() {
mark_service_starting() {
[[ -z $1 ]] && return 1
- ln -snf "/etc/init.d/$1" "${svcdir}/starting/$1"
- local retval=$?
-
- [[ -f "${svcdir}/started/$1" ]] && rm -f "${svcdir}/started/$1"
+ ln -sn "/etc/init.d/$1" "${svcdir}/starting/$1" 2>/dev/null || return 1
+
[[ -f "${svcdir}/inactive/$1" ]] && rm -f "${svcdir}/inactive/$1"
- [[ -f "${svcdir}/stopping/$1" ]] && rm -f "${svcdir}/stopping/$1"
-
- return "${retval}"
+ [[ -f "${svcdir}/started/$1" ]] && rm -f "${svcdir}/started/$1"
+ return 0
}
# bool mark_service_started(service)
@@ -457,13 +451,12 @@ mark_service_started() {
[[ -z $1 ]] && return 1
ln -snf "/etc/init.d/$1" "${svcdir}/started/$1"
- local retval=$?
[[ -f "${svcdir}/starting/$1" ]] && rm -f "${svcdir}/starting/$1"
[[ -f "${svcdir}/inactive/$1" ]] && rm -f "${svcdir}/inactive/$1"
[[ -f "${svcdir}/stopping/$1" ]] && rm -f "${svcdir}/stopping/$1"
- return "${retval}"
+ return 0
}
# bool mark_service_inactive(service)
@@ -474,12 +467,12 @@ mark_service_inactive() {
[[ -z $1 ]] && return 1
ln -snf "/etc/init.d/$1" "${svcdir}/inactive/$1"
- local retval=$?
+
[[ -f "${svcdir}/started/$1" ]] && rm -f "${svcdir}/started/$1"
[[ -f "${svcdir}/starting/$1" ]] && rm -f "${svcdir}/starting/$1"
[[ -f "${svcdir}/stopping/$1" ]] && rm -f "${svcdir}/stopping/$1"
- return "${retval}"
+ return 0
}
# bool mark_service_stopping(service)
@@ -489,14 +482,11 @@ mark_service_inactive() {
mark_service_stopping() {
[[ -z $1 ]] && return 1
- ln -snf "/etc/init.d/$1" "${svcdir}/stopping/$1"
- local retval=$?
-
- [[ -f "${svcdir}/starting/$1" ]] && rm -f "${svcdir}/starting/$1"
- [[ -f "${svcdir}/started/$1" ]] && rm -f "${svcdir}/started/$1"
- [[ -f "${svcdir}/inactive/$1" ]] && rm -f "${svcdir}/inactive/$1"
+ ln -sn "/etc/init.d/$1" "${svcdir}/stopping/$1" 2>/dev/null || return 1
- return "${retval}"
+ [[ -f "${svcdir}/inactive/$1" ]] && rm -f "${svcdir}/inactive/$1"
+ [[ -f "${svcdir}/started/$1" ]] && rm -f "${svcdir}/started/$1"
+ return 0
}
# bool mark_service_stopped(service)
@@ -512,7 +502,7 @@ mark_service_stopped() {
[[ -f "${svcdir}/inactive/$1" ]] && rm -f "${svcdir}/inactive/$1"
[[ -f "${svcdir}/stopping/$1" ]] && rm -f "${svcdir}/stopping/$1"
- return $?
+ return 0
}
# bool test_service_state(char *service, char *state)
diff --git a/sbin/runscript.sh b/sbin/runscript.sh
index 49814b7..8ac20fb 100755
--- a/sbin/runscript.sh
+++ b/sbin/runscript.sh
@@ -84,31 +84,29 @@ status() {
}
svc_stop() {
- local x=
- local mydep=
- local mydeps=
- local retval=0
- local ordservice=
- local was_inactive=false
-
- if service_stopping "${myservice}" ; then
- eerror "ERROR: \"${myservice}\" is already stopping."
- return 0
- elif service_stopped "${myservice}" ; then
- eerror "ERROR: \"${myservice}\" has not yet been started."
- return 0
- fi
-
+ local x= mydep= mydeps= retval=0 was_inactive=false
+ local -a servicelist=()
+
# Do not try to stop if it had already failed to do so on runlevel change
if is_runlevel_stop && service_failed "${myservice}" ; then
return 1
fi
+
+ if service_stopped "${myservice}" ; then
+ ewarn "WARNING: \"${myservice}\" has not yet been started."
+ return 0
+ fi
service_inactive "${myservice}" && was_inactive=true
-
- # Remove symlink to prevent recursion
- mark_service_stopping "${myservice}"
-
+ if ! mark_service_stopping "${myservice}" ; then
+ ewarn "WARNING: \"${myservice}\" is already stopping."
+ return 0
+ fi
+ # Lock service starting too ...
+ mark_service_starting "${myservice}"
+ begin_service "${myservice}"
+ local begun=$?
+
service_message "Stopping service ${myservice}"
if in_runlevel "${myservice}" "${BOOTLEVEL}" && \
@@ -137,95 +135,51 @@ svc_stop() {
# Save the IN_BACKGROUND var as we need to clear it for stopping depends
local ib_save="${IN_BACKGROUND}"
unset IN_BACKGROUND
- local -a servicelist=() index=0
for mydep in ${mydeps} ; do
- # If some service 'need' $mydep, stop it first; or if it is a runlevel change,
- # first stop all services that is started 'after' $mydep.
- if needsme "${mydep}" >/dev/null || \
- (is_runlevel_stop && ibefore "${mydep}" >/dev/null) ; then
- local -a sl=( $(needsme "${mydep}") )
-
- # On runlevel change, stop all services "after $mydep" first ...
- if is_runlevel_stop ; then
- sl=( "${sl[@]}" $(ibefore "${mydep}") )
+ for x in $(needsme "${mydep}") ; do
+ # Service not currently running, continue
+ if service_started "${x}" ; then
+ stop_service "${x}"
+ service_list=( "${service_list[@]}" "${x}" )
fi
-
- local z="${#sl[@]}"
- for (( x=0; x<z; x++ )); do
- # Service not currently running, continue
- if ! service_started "${sl[x]}" ; then
- unset sl[x]
- continue
- fi
-
- if ibefore -t "${mydep}" "${x}" >/dev/null && \
- [[ -L ${svcdir}/softscripts.new/${x} ]] ; then
- # Service do not 'need' $mydep, and is still present in
- # new runlevel ...
- unset sl[x]
- continue
- fi
-
- stop_service "${sl[x]}"
- done
- fi
- servicelist[index]="${sl[index]}"
- (( index++ ))
+ done
done
- index=0
- for mydep in ${mydeps} ; do
- for x in ${servicelist[index]} ; do
- service_stopped "${x}" && continue
-
- if ibefore -t "${mydep}" "${x}" >/dev/null && \
- [[ -L ${svcdir}/softscripts.new/${x} ]] ; then
- # Service do not 'need' $mydep, and is still present in
- # new runlevel ...
- continue
- fi
-
- wait_service "${x}"
-
- if ! service_stopped "${x}" ; then
- # If we are halting the system, try and get it down as
- # clean as possible, else do not stop our service if
- # a dependent service did not stop.
- if needsme -t "${mydep}" "${x}" >/dev/null && \
- [[ ${SOFTLEVEL} != "reboot" && \
- ${SOFTLEVEL} != "shutdown" ]] ; then
- retval=1
- fi
- break
- fi
- done
- (( index++ ))
+ for x in "${service_list[@]}" ; do
+ service_stopped "${x}" && continue
+ wait_service "${x}"
+ if ! service_stopped "${x}" ; then
+ retval=1
+ break
+ fi
done
IN_BACKGROUND="${ib_save}"
- if [[ ${retval} -ne 0 ]] ; then
+ if [[ ${retval} != 0 ]] ; then
eerror "ERROR: problems stopping dependent services."
eerror " \"${myservice}\" is still up."
else
# Stop einfo/ebegin/eend from working as parallel messes us up
[[ ${RC_PARALLEL_STARTUP} == "yes" ]] && RC_QUIET_STDOUT="yes"
+
# Now that deps are stopped, stop our service
( stop )
retval=$?
# If a service has been marked inactive, exit now as something
# may attempt to start it again later
- service_inactive "${myservice}" && return 0
+ if service_inactive "${myservice}" ; then
+ [[ ${begun} == 0 ]] && end_service "${myservice}" 0
+ return 0
+ fi
fi
- if [[ ${retval} -ne 0 ]] ; then
+ if [[ ${retval} != 0 ]] ; then
# Did we fail to stop? create symlink to stop multible attempts at
# runlevel change. Note this is only used at runlevel change ...
- if is_runlevel_stop ; then
- mark_service_failed "${myservice}"
- fi
+ is_runlevel_stop && mark_service_failed "${myservice}"
# If we are halting the system, do it as cleanly as possible
if [[ ${SOFTLEVEL} != "reboot" && ${SOFTLEVEL} != "shutdown" ]] ; then
@@ -248,54 +202,47 @@ svc_stop() {
service_message "Stopped service ${myservice}"
fi
+ [[ ${begun} == 0 ]] && end_service "${myservice}" "${retval}"
return "${retval}"
}
svc_start() {
- local retval=0
- local startfail="no"
- local x=
- local y=
- local myserv=
- local ordservice=
-
- if service_starting "${myservice}" ; then
- ewarn "WARNING: \"${myservice}\" is already starting."
+ local x= y= retval=0 was_inactive=false startfail="no"
+
+ # Do not try to start if i have done so already on runlevel change
+ if is_runlevel_start && service_failed "${myservice}" ; then
+ return 1
+ fi
+
+ if service_started "${myservice}" ; then
+ ewarn "WARNING: \"${myservice}\" has already been started."
return 0
elif service_stopping "${myservice}" ; then
- ewarn "WARNING: please wait for \"${myservice}\" to stop first."
- return 0
+ eerror "ERROR: please wait for \"${myservice}\" to stop first."
+ return 1
elif service_inactive "${myservice}" ; then
if [[ ${IN_BACKGROUND} != "true" ]] ; then
ewarn "WARNING: \"${myservice}\" has already been started."
return 0
fi
- elif service_started "${myservice}" ; then
- ewarn "WARNING: \"${myservice}\" has already been started."
- return 0
fi
- # Do not try to start if i have done so already on runlevel change
- if is_runlevel_start && service_failed "${myservice}" ; then
- return 1
+ service_inactive "${myservice}" && was_inactive=true
+ if ! mark_service_starting "${myservice}" ; then
+ ewarn "WARNING: \"${myservice}\" is already starting."
+ return 0
fi
+ begin_service "${myservice}"
+ local begun=$?
- mark_service_starting "${myservice}"
service_message "Starting service ${myservice}"
-
- # On rc change, start all services "before $myservice" first
- if is_runlevel_start ; then
- startupservices="$(ineed "${myservice}") \
- $(valid_iuse "${myservice}") \
- $(valid_iafter "${myservice}")"
- else
- startupservices="$(ineed "${myservice}") \
- $(valid_iuse "${myservice}")"
- fi
+
+ local startupservices="$(trace_dependencies $(ineed "${myservice}") \
+ $(valid_iuse ${myservice}))"
# Start dependencies, if any
for x in ${startupservices} ; do
- if [[ ${x} == "net" ]] && [[ ${NETSERVICE} != "yes" ]] && ! is_net_up ; then
+ if [[ ${x} == "net" && ${NETSERVICE} != "yes" ]] && ! is_net_up ; then
local netservices="$(dolisting "/etc/runlevels/${BOOTLEVEL}/net.*") \
$(dolisting "/etc/runlevels/${mylevel}/net.*")"
@@ -315,9 +262,6 @@ svc_start() {
# wait for dependencies to finish
for x in ${startupservices} ; do
if [ "${x}" = "net" -a "${NETSERVICE}" != "yes" ] ; then
- local netservices="$(dolisting "/etc/runlevels/${BOOTLEVEL}/net.*") \
- $(dolisting "/etc/runlevels/${mylevel}/net.*")"
-
for y in ${netservices} ; do
mynetservice="${y##*/}"
@@ -372,7 +316,10 @@ svc_start() {
# If a service has been marked inactive, exit now as something
# may attempt to start it again later
- service_inactive "${myservice}" && return 1
+ if service_inactive "${myservice}" ; then
+ [[ ${begun} == 0 ]] && end_service "${myservice}" 1
+ return 1
+ fi
fi
if [[ ${retval} != 0 ]] ; then
@@ -382,7 +329,11 @@ svc_start() {
# If we're booting, we need to continue and do our best to get the
# system up.
if [[ ${SOFTLEVEL} != "${BOOTLEVEL}" ]]; then
- mark_service_stopped "${myservice}"
+ if ${was_inactive} ; then
+ mark_service_inactive "${myservice}"
+ else
+ mark_service_stopped "${myservice}"
+ fi
fi
service_message "eerror" "FAILED to start service ${myservice}!"
@@ -392,6 +343,7 @@ svc_start() {
service_message "Service ${myservice} started OK"
fi
+ [[ ${begun} == 0 ]] && end_service "${myservice}" "${retval}"
return "${retval}"
}
@@ -414,7 +366,10 @@ svc_status() {
# and update our status accordingly
[[ ${EUID} == 0 ]] && update_service_status "${myservice}"
- if service_starting "${myservice}" ; then
+ if service_stopping "${myservice}" ; then
+ efunc="eerror"
+ state="stopping"
+ elif service_starting "${myservice}" ; then
efunc="einfo"
state="starting"
elif service_inactive "${myservice}" ; then
@@ -423,9 +378,6 @@ svc_status() {
elif service_started "${myservice}" ; then
efunc="einfo"
state="started"
- elif service_stopping "${myservice}" ; then
- efunc="eerror"
- state="stopping"
else
efunc="eerror"
state="stopped"
@@ -502,10 +454,40 @@ done
for arg in $* ; do
case "${arg}" in
stop)
+ if [[ -e "${svcdir}/restart/${myservice}" ]]; then
+ rm -f "${svcdir}/restart/${myservice}"
+ fi
+
+ # Stoped from the background - treat this as a restart so that
+ # stopped services come back up again when started.
+ if [[ ${IN_BACKGROUND} == "true" ]]; then
+ rm -rf "${svcdir}/snapshot/$$"
+ mkdir -p "${svcdir}/snapshot/$$"
+ cp -a "${svcdir}"/started/* "${svcdir}/snapshot/$$/"
+ fi
+
svc_stop
+
+ if [[ ${IN_BACKGROUND} == "true" ]]; then
+ res=
+ for x in $(dolisting "${svcdir}/snapshot/$$/") ; do
+ if service_stopped "${x##*/}" ; then
+ res="${res}${x##*/} "
+ fi
+ done
+ echo "${res}" > "${svcdir}/restart/${myservice}"
+ fi
;;
start)
svc_start
+ retval=$?
+ if [[ -e "${svcdir}/restart/${myservice}" ]]; then
+ for x in $(trace_dependencies $(< "${svcdir}/restart/${myservice}")) ; do
+ service_stopped "${x}" && start_service "${x}"
+ done
+ rm -f "${svcdir}/restart/${myservice}"
+ fi
+ exit ${retval}
;;
needsme|ineed|usesme|iuse|broken)
trace_dependencies "-${arg}"
@@ -514,9 +496,13 @@ for arg in $* ; do
svc_status
;;
zap)
+ if [[ -e "${svcdir}/restart/${myservice}" ]]; then
+ rm -f "${svcdir}/restart/${myservice}"
+ fi
if ! service_stopped "${myservice}" ; then
einfo "Manually resetting ${myservice} to stopped state."
mark_service_stopped "${myservice}"
+ end_service "${myservice}"
fi
;;
restart)
@@ -539,7 +525,7 @@ for arg in $* ; do
echo
ewarn "Please use 'svc_stop; svc_start' and not 'stop; start' to"
ewarn "restart the service in its custom 'restart()' function."
- ewarn "Run ${myservice} without arguments for more info."
+/var/lib/init.d/exclusive/net.lan ewarn "Run ${myservice} without arguments for more info."
echo
svc_restart
else
@@ -557,6 +543,14 @@ for arg in $* ; do
start_service "${x##*/}"
fi
done
+ elif service_inactive "${myservice}" ; then
+ res=
+ for x in $(dolisting "${svcdir}/snapshot/$$/") ; do
+ if service_stopped "${x##*/}" ; then
+ res="${res}${x##*/} "
+ fi
+ done
+ echo "${res}" > "${svcdir}/restart/${myservice}"
fi
# Wait for any services that may still be running ...
@@ -582,5 +576,4 @@ for arg in $* ; do
esac
done
-
# vim:ts=4