You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

244 lines
9.8 KiB

  1. #!/bin/sh
  2. ###########################################################################
  3. # /usr/bin/service
  4. #
  5. # A convenient wrapper for the /etc/init.d init scripts.
  6. #
  7. # This script is a modified version of the /sbin/service utility found on
  8. # Red Hat/Fedora systems (licensed GPLv2+).
  9. #
  10. # Copyright (C) 2006 Red Hat, Inc. All rights reserved.
  11. # Copyright (C) 2008 Canonical Ltd.
  12. # * August 2008 - Dustin Kirkland <kirkland@canonical.com>
  13. # Copyright (C) 2013 Michael Stapelberg <stapelberg@debian.org>
  14. #
  15. # This program is free software; you can redistribute it and/or modify
  16. # it under the terms of the GNU General Public License as published by
  17. # the Free Software Foundation; either version 2 of the License, or
  18. # (at your option) any later version.
  19. #
  20. # This program is distributed in the hope that it will be useful,
  21. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. # GNU General Public License for more details.
  24. #
  25. # You should have received a copy of the GNU General Public License
  26. # along with this program; if not, write to the Free Software
  27. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  28. #
  29. # On Debian GNU/Linux systems, the complete text of the GNU General
  30. # Public License can be found in `/usr/share/common-licenses/GPL-2'.
  31. ###########################################################################
  32. is_ignored_file() {
  33. case "$1" in
  34. skeleton | README | *.dpkg-dist | *.dpkg-old | rc | rcS | single | reboot | bootclean.sh)
  35. return 0
  36. ;;
  37. esac
  38. return 1
  39. }
  40. VERSION="`basename $0` ver. __VERSION__"
  41. USAGE="Usage: `basename $0` < option > | --status-all | \
  42. [ service_name [ command | --full-restart ] ]"
  43. SERVICE=
  44. ACTION=
  45. SERVICEDIR="/etc/init.d"
  46. OPTIONS=
  47. is_systemd=
  48. if [ $# -eq 0 ]; then
  49. echo "${USAGE}" >&2
  50. exit 1
  51. fi
  52. if [ -d /run/systemd/system ]; then
  53. is_systemd=1
  54. fi
  55. cd /
  56. while [ $# -gt 0 ]; do
  57. case "${1}" in
  58. --help | -h | --h* )
  59. echo "${USAGE}" >&2
  60. exit 0
  61. ;;
  62. --version | -V )
  63. echo "${VERSION}" >&2
  64. exit 0
  65. ;;
  66. *)
  67. if [ -z "${SERVICE}" -a $# -eq 1 -a "${1}" = "--status-all" ]; then
  68. cd ${SERVICEDIR}
  69. for SERVICE in * ; do
  70. case "${SERVICE}" in
  71. functions | halt | killall | single| linuxconf| kudzu)
  72. ;;
  73. *)
  74. if ! is_ignored_file "${SERVICE}" \
  75. && [ -x "${SERVICEDIR}/${SERVICE}" ]; then
  76. out=$(env -i LANG="$LANG" LANGUAGE="$LANGUAGE" LC_CTYPE="$LC_CTYPE" LC_NUMERIC="$LC_NUMERIC" LC_TIME="$LC_TIME" LC_COLLATE="$LC_COLLATE" LC_MONETARY="$LC_MONETARY" LC_MESSAGES="$LC_MESSAGES" LC_PAPER="$LC_PAPER" LC_NAME="$LC_NAME" LC_ADDRESS="$LC_ADDRESS" LC_TELEPHONE="$LC_TELEPHONE" LC_MEASUREMENT="$LC_MEASUREMENT" LC_IDENTIFICATION="$LC_IDENTIFICATION" LC_ALL="$LC_ALL" PATH="$PATH" TERM="$TERM" "$SERVICEDIR/$SERVICE" status 2>&1)
  77. retval=$?
  78. if echo "$out" | egrep -iq "usage:"; then
  79. #printf " %s %-60s %s\n" "[?]" "$SERVICE:" "unknown" 1>&2
  80. echo " [ ? ] $SERVICE" 1>&2
  81. continue
  82. else
  83. if [ "$retval" = "0" -a -n "$out" ]; then
  84. #printf " %s %-60s %s\n" "[+]" "$SERVICE:" "running"
  85. echo " [ + ] $SERVICE"
  86. continue
  87. else
  88. #printf " %s %-60s %s\n" "[-]" "$SERVICE:" "NOT running"
  89. echo " [ - ] $SERVICE"
  90. continue
  91. fi
  92. fi
  93. #env -i LANG="$LANG" LANGUAGE="$LANGUAGE" LC_CTYPE="$LC_CTYPE" LC_NUMERIC="$LC_NUMERIC" LC_TIME="$LC_TIME" LC_COLLATE="$LC_COLLATE" LC_MONETARY="$LC_MONETARY" LC_MESSAGES="$LC_MESSAGES" LC_PAPER="$LC_PAPER" LC_NAME="$LC_NAME" LC_ADDRESS="$LC_ADDRESS" LC_TELEPHONE="$LC_TELEPHONE" LC_MEASUREMENT="$LC_MEASUREMENT" LC_IDENTIFICATION="$LC_IDENTIFICATION" LC_ALL="$LC_ALL" PATH="$PATH" TERM="$TERM" "$SERVICEDIR/$SERVICE" status
  94. fi
  95. ;;
  96. esac
  97. done
  98. exit 0
  99. elif [ $# -eq 2 -a "${2}" = "--full-restart" ]; then
  100. SERVICE="${1}"
  101. # On systems using systemd, we just perform a normal restart:
  102. # A restart with systemd is already a full restart.
  103. if [ -n "$is_systemd" ]; then
  104. ACTION="restart"
  105. else
  106. if [ -x "${SERVICEDIR}/${SERVICE}" ]; then
  107. env -i LANG="$LANG" LANGUAGE="$LANGUAGE" LC_CTYPE="$LC_CTYPE" LC_NUMERIC="$LC_NUMERIC" LC_TIME="$LC_TIME" LC_COLLATE="$LC_COLLATE" LC_MONETARY="$LC_MONETARY" LC_MESSAGES="$LC_MESSAGES" LC_PAPER="$LC_PAPER" LC_NAME="$LC_NAME" LC_ADDRESS="$LC_ADDRESS" LC_TELEPHONE="$LC_TELEPHONE" LC_MEASUREMENT="$LC_MEASUREMENT" LC_IDENTIFICATION="$LC_IDENTIFICATION" LC_ALL="$LC_ALL" PATH="$PATH" TERM="$TERM" "$SERVICEDIR/$SERVICE" stop
  108. env -i LANG="$LANG" LANGUAGE="$LANGUAGE" LC_CTYPE="$LC_CTYPE" LC_NUMERIC="$LC_NUMERIC" LC_TIME="$LC_TIME" LC_COLLATE="$LC_COLLATE" LC_MONETARY="$LC_MONETARY" LC_MESSAGES="$LC_MESSAGES" LC_PAPER="$LC_PAPER" LC_NAME="$LC_NAME" LC_ADDRESS="$LC_ADDRESS" LC_TELEPHONE="$LC_TELEPHONE" LC_MEASUREMENT="$LC_MEASUREMENT" LC_IDENTIFICATION="$LC_IDENTIFICATION" LC_ALL="$LC_ALL" PATH="$PATH" TERM="$TERM" "$SERVICEDIR/$SERVICE" start
  109. exit $?
  110. fi
  111. fi
  112. elif [ -z "${SERVICE}" ]; then
  113. SERVICE="${1}"
  114. elif [ -z "${ACTION}" ]; then
  115. ACTION="${1}"
  116. else
  117. OPTIONS="${OPTIONS} ${1}"
  118. fi
  119. shift
  120. ;;
  121. esac
  122. done
  123. # Operate against system upstart, not session
  124. unset UPSTART_SESSION
  125. if [ -r "/etc/init/${SERVICE}.conf" ] && which initctl >/dev/null \
  126. && initctl version 2>/dev/null | grep -q upstart \
  127. && initctl status ${SERVICE} 2>/dev/null 1>/dev/null
  128. then
  129. # Upstart configuration exists for this job and we're running on upstart
  130. case "${ACTION}" in
  131. start|stop|status|reload)
  132. # Action is a valid upstart action
  133. exec ${ACTION} ${SERVICE} ${OPTIONS}
  134. ;;
  135. restart|force-reload)
  136. # Map restart to the usual sysvinit behavior.
  137. # Map force-reload to restart as per Debian policy 9.3.2,
  138. # since there is no way to know if "reload" is supported
  139. stop ${SERVICE} ${OPTIONS} || :
  140. exec start ${SERVICE} ${OPTIONS}
  141. ;;
  142. esac
  143. fi
  144. run_via_sysvinit() {
  145. # Otherwise, use the traditional sysvinit
  146. if [ -x "${SERVICEDIR}/${SERVICE}" ]; then
  147. exec env -i LANG="$LANG" LANGUAGE="$LANGUAGE" LC_CTYPE="$LC_CTYPE" LC_NUMERIC="$LC_NUMERIC" LC_TIME="$LC_TIME" LC_COLLATE="$LC_COLLATE" LC_MONETARY="$LC_MONETARY" LC_MESSAGES="$LC_MESSAGES" LC_PAPER="$LC_PAPER" LC_NAME="$LC_NAME" LC_ADDRESS="$LC_ADDRESS" LC_TELEPHONE="$LC_TELEPHONE" LC_MEASUREMENT="$LC_MEASUREMENT" LC_IDENTIFICATION="$LC_IDENTIFICATION" LC_ALL="$LC_ALL" PATH="$PATH" TERM="$TERM" "$SERVICEDIR/$SERVICE" ${ACTION} ${OPTIONS}
  148. else
  149. echo "${SERVICE}: unrecognized service" >&2
  150. exit 1
  151. fi
  152. }
  153. update_openrc_started_symlinks() {
  154. # maintain the symlinks of /run/openrc/started so that
  155. # rc-status works with the service command as well
  156. if [ -d /run/openrc/started ] ; then
  157. case "${ACTION}" in
  158. start)
  159. if [ ! -h /run/openrc/started/$SERVICE ] ; then
  160. ln -s $SERVICEDIR/$SERVICE /run/openrc/started/$SERVICE || true
  161. fi
  162. ;;
  163. stop)
  164. rm /run/openrc/started/$SERVICE || true
  165. ;;
  166. esac
  167. fi
  168. }
  169. # When this machine is running systemd, standard service calls are turned into
  170. # systemctl calls.
  171. if [ -n "$is_systemd" ]
  172. then
  173. UNIT="${SERVICE%.sh}.service"
  174. # avoid deadlocks during bootup and shutdown from units/hooks
  175. # which call "invoke-rc.d service reload" and similar, since
  176. # the synchronous wait plus systemd's normal behaviour of
  177. # transactionally processing all dependencies first easily
  178. # causes dependency loops
  179. if ! systemctl --quiet is-active multi-user.target; then
  180. sctl_args="--job-mode=ignore-dependencies"
  181. fi
  182. case "${ACTION}" in
  183. restart|status|try-restart)
  184. exec systemctl $sctl_args ${ACTION} ${UNIT}
  185. ;;
  186. start|stop)
  187. # Follow the principle of least surprise for SysV people:
  188. # When running "service foo stop" and foo happens to be a service that
  189. # has one or more .socket files, we also stop the .socket units.
  190. # Users who need more control will use systemctl directly.
  191. for unit in $(systemctl list-unit-files --full --type=socket 2>/dev/null | sed -ne 's/\.socket\s*[a-z]*\s*$/.socket/p'); do
  192. if [ "$(systemctl -p Triggers show $unit)" = "Triggers=${UNIT}" ]; then
  193. systemctl $sctl_args ${ACTION} $unit
  194. fi
  195. done
  196. exec systemctl $sctl_args ${ACTION} ${UNIT}
  197. ;;
  198. reload)
  199. _canreload="$(systemctl -p CanReload show ${UNIT} 2>/dev/null)"
  200. if [ "$_canreload" = "CanReload=no" ]; then
  201. # The reload action falls back to the sysv init script just in case
  202. # the systemd service file does not (yet) support reload for a
  203. # specific service.
  204. run_via_sysvinit
  205. else
  206. exec systemctl $sctl_args reload "${UNIT}"
  207. fi
  208. ;;
  209. force-stop)
  210. exec systemctl --signal=KILL kill "${UNIT}"
  211. ;;
  212. force-reload)
  213. _canreload="$(systemctl -p CanReload show ${UNIT} 2>/dev/null)"
  214. if [ "$_canreload" = "CanReload=no" ]; then
  215. exec systemctl $sctl_args restart "${UNIT}"
  216. else
  217. exec systemctl $sctl_args reload "${UNIT}"
  218. fi
  219. ;;
  220. *)
  221. # We try to run non-standard actions by running
  222. # the init script directly.
  223. run_via_sysvinit
  224. ;;
  225. esac
  226. fi
  227. update_openrc_started_symlinks
  228. run_via_sysvinit