From Will Pittenger, 7 Years ago, written in Plain Text.
Embed
  1. # Oracle VM VirtualBox
  2. # VirtualBox installer shell routines
  3. #
  4.  
  5. # Copyright (C) 2007-2015 Oracle Corporation
  6. #
  7. # This file is part of VirtualBox Open Source Edition (OSE), as
  8. # available from http://www.virtualbox.org. This file is free software;
  9. # you can redistribute it and/or modify it under the terms of the GNU
  10. # General Public License (GPL) as published by the Free Software
  11. # Foundation, in version 2 as it comes in the "COPYING" file of the
  12. # VirtualBox OSE distribution. VirtualBox OSE is distributed in the
  13. # hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
  14. #
  15.  
  16. ro_LOG_FILE=""
  17. ro_X11_AUTOSTART="/etc/xdg/autostart"
  18. ro_KDE_AUTOSTART="/usr/share/autostart"
  19.  
  20. ## Aborts the script and prints an error message to stderr.
  21. #
  22. # syntax: abort message
  23.  
  24. abort()
  25. {
  26.     echo 1>&2 "$1"
  27.     exit 1
  28. }
  29.  
  30. ## Creates an empty log file and remembers the name for future logging
  31. # operations
  32. create_log()
  33. {
  34.     ## The path of the file to create.
  35.     ro_LOG_FILE="$1"
  36.     if [ "$ro_LOG_FILE" = "" ]; then
  37.         abort "create_log called without an argument!  Aborting..."
  38.     fi
  39.     # Create an empty file
  40.     echo > "$ro_LOG_FILE" 2> /dev/null
  41.     if [ ! -f "$ro_LOG_FILE" -o "`cat "$ro_LOG_FILE"`" != "" ]; then
  42.         abort "Error creating log file!  Aborting..."
  43.     fi
  44. }
  45.  
  46. ## Writes text to standard error
  47. #
  48. # Syntax: info text
  49. info()
  50. {
  51.     echo 1>&2 "$1"
  52. }
  53.  
  54. ## Writes text to the log file
  55. #
  56. # Syntax: log text
  57. log()
  58. {
  59.     if [ "$ro_LOG_FILE" = "" ]; then
  60.         abort "Error!  Logging has not been set up yet!  Aborting..."
  61.     fi
  62.     echo "$1" >> $ro_LOG_FILE
  63.     return 0
  64. }
  65.  
  66. ## Writes test to standard output and to the log file
  67. #
  68. # Syntax: infolog text
  69. infolog()
  70. {
  71.     info "$1"
  72.     log "$1"
  73. }
  74.  
  75. ## Checks whether a module is loaded with a given string in its name.
  76. #
  77. # syntax: module_loaded string
  78. module_loaded()
  79. {
  80.     if [ "$1" = "" ]; then
  81.         log "module_loaded called without an argument.  Aborting..."
  82.         abort "Error in installer.  Aborting..."
  83.     fi
  84.     lsmod | grep -q $1
  85. }
  86.  
  87. ## Abort if we are not running as root
  88. check_root()
  89. {
  90.     if [ `id -u` -ne 0 ]; then
  91.         abort "This program must be run with administrator privileges.  Aborting"
  92.     fi
  93. }
  94.  
  95. ## Abort if a copy of VirtualBox is already running
  96. check_running()
  97. {
  98.     VBOXSVC_PID=`pidof VBoxSVC 2> /dev/null`
  99.     if [ -n "$VBOXSVC_PID" ]; then
  100.         if [ -f /etc/init.d/vboxweb-service ]; then
  101.             kill -USR1 $VBOXSVC_PID
  102.         fi
  103.         sleep 1
  104.         if pidof VBoxSVC > /dev/null 2>&1; then
  105.             echo 1>&2 "A copy of VirtualBox is currently running.  Please close it and try again."
  106.             abort "Please note that it can take up to ten seconds for VirtualBox to finish running."
  107.         fi
  108.     fi
  109. }
  110.  
  111. ## Creates a systemd wrapper in /lib for an LSB init script
  112. systemd_wrap_init_script()
  113. {
  114.     self="systemd_wrap_init_script"
  115.     ## The init script to be installed.  The file may be copied or referenced.
  116.     script="$(readlink -f -- "${1}")"
  117.     ## Name for the service.
  118.     name="$2"
  119.     test -x "$script" && test ! "$name" = "" || \
  120.         { echo "$self: invalid arguments" >&2 && return 1; }
  121.     test -d /usr/lib/systemd/system && unit_path=/usr/lib/systemd/system
  122.     test -d /lib/systemd/system && unit_path=/lib/systemd/system
  123.     test -n "${unit_path}" || \
  124.         { echo "$self: systemd unit path not found" >&2 && return 1; }
  125.     description=`sed -n 's/# *Short-Description: *\(.*\)/\1/p' "${script}"`
  126.     required=`sed -n 's/# *Required-Start: *\(.*\)/\1/p' "${script}" | sed 's/\$[a-z]*//'`
  127.     runlevels=`sed -n 's/# *Default-Start: *\(.*\)/\1/p' "${script}"`
  128.     before=`for i in ${runlevels}; do printf "runlevel${i}.target "; done`
  129.     after=`for i in ${required}; do printf "${i}.service "; done`
  130.     cat > "${unit_path}/${name}.service" << EOF
  131. [Unit]
  132. SourcePath=${script}
  133. Description=${description}
  134. Before=${before}shutdown.target
  135. After=${after}
  136. Conflicts=shutdown.target
  137.  
  138. [Service]
  139. Type=forking
  140. Restart=no
  141. TimeoutSec=5min
  142. IgnoreSIGPIPE=no
  143. KillMode=process
  144. GuessMainPID=no
  145. RemainAfterExit=yes
  146. ExecStart=${script} start
  147. ExecStop=${script} stop
  148.  
  149. [Install]
  150. WantedBy=multi-user.target
  151. EOF
  152.     systemctl daemon-reexec
  153. }
  154.  
  155. ## Installs a file containing a shell script as an init script
  156. install_init_script()
  157. {
  158.     self="install_init_script"
  159.     ## The init script to be installed.  The file may be copied or referenced.
  160.     script="$1"
  161.     ## Name for the service.
  162.     name="$2"
  163.  
  164.     test -x "${script}" && test ! "${name}" = "" ||
  165.         { echo "${self}: invalid arguments" >&2; return 1; }
  166.     # Do not unconditionally silence the following "ln".
  167.     test -L "/sbin/rc${name}" && rm "/sbin/rc${name}"
  168.     ln -s "${script}" "/sbin/rc${name}"
  169.     if test -x "`which systemctl 2>/dev/null`"; then
  170.         if ! test -f /sbin/init || ls -l /sbin/init | grep -q ">.*systemd"; then
  171.             { systemd_wrap_init_script "$script" "$name"; return; }
  172.         fi
  173.     fi
  174.     if test -d /etc/rc.d/init.d; then
  175.         cp "${script}" "/etc/rc.d/init.d/${name}" &&
  176.             chmod 755 "/etc/rc.d/init.d/${name}"
  177.     elif test -d /etc/init.d; then
  178.         cp "${script}" "/etc/init.d/${name}" &&
  179.             chmod 755 "/etc/init.d/${name}"
  180.     else
  181.         { echo "${self}: error: unknown init type" >&2; return 1; }
  182.     fi
  183. }
  184.  
  185. ## Remove the init script "name"
  186. remove_init_script()
  187. {
  188.     self="remove_init_script"
  189.     ## Name of the service to remove.
  190.     name="$1"
  191.  
  192.     test -n "${name}" ||
  193.         { echo "$self: missing argument"; return 1; }
  194.     rm -f "/sbin/rc${name}"
  195.     rm -f /lib/systemd/system/"$name".service /usr/lib/systemd/system/"$name".service
  196.     rm -f "/etc/rc.d/init.d/$name"
  197.     rm -f "/etc/init.d/$name"
  198. }
  199.  
  200. ## Did we install a systemd service?
  201. systemd_service_installed()
  202. {
  203.     ## Name of service to test.
  204.     name="${1}"
  205.  
  206.     test -f /lib/systemd/system/"${name}".service ||
  207.         test -f /usr/lib/systemd/system/"${name}".service
  208. }
  209.  
  210. ## Perform an action on a service
  211. do_sysvinit_action()
  212. {
  213.     self="do_sysvinit_action"
  214.     ## Name of service to start.
  215.     name="${1}"
  216.     ## The action to perform, normally "start", "stop" or "status".
  217.     action="${2}"
  218.  
  219.     test ! -z "${name}" && test ! -z "${action}" ||
  220.         { echo "${self}: missing argument" >&2; return 1; }
  221.     if systemd_service_installed "${name}"; then
  222.         systemctl -q ${action} "${name}"
  223.     elif test -x "`which service 2>/dev/null`"; then
  224.         service "${name}" ${action}
  225.     elif test -x "`which invoke-rc.d 2>/dev/null`"; then
  226.         invoke-rc.d "${name}" ${action}
  227.     elif test -x "/etc/rc.d/init.d/${name}"; then
  228.         "/etc/rc.d/init.d/${name}" "${action}"
  229.     elif test -x "/etc/init.d/${name}"; then
  230.         "/etc/init.d/${name}" "${action}"
  231.     fi
  232. }
  233.  
  234. ## Start a service
  235. start_init_script()
  236. {
  237.     do_sysvinit_action "${1}" start
  238. }
  239.  
  240. ## Stop the init script "name"
  241. stop_init_script()
  242. {
  243.     do_sysvinit_action "${1}" stop
  244. }
  245.  
  246. ## Extract chkconfig information from a sysvinit script.
  247. get_chkconfig_info()
  248. {
  249.     ## The script to extract the information from.
  250.     script="${1}"
  251.  
  252.     set `sed -n 's/# *chkconfig: *\([0-9]*\) *\(.*\)/\1 \2/p' "${script}"`
  253.     ## Which runlevels should we start in?
  254.     runlevels="${1}"
  255.     ## How soon in the boot process will we start, from 00 (first) to 99
  256.     start_order="${2}"
  257.     ## How soon in the shutdown process will we stop, from 99 (first) to 00
  258.     stop_order="${3}"
  259.     test ! -z "${name}" || \
  260.         { echo "${self}: missing name" >&2; return 1; }
  261.     expr "${start_order}" + 0 > /dev/null 2>&1 && \
  262.         expr 0 \<= "${start_order}" > /dev/null 2>&1 && \
  263.         test `expr length "${start_order}"` -eq 2 > /dev/null 2>&1 || \
  264.         { echo "${self}: start sequence number must be between 00 and 99" >&2;
  265.             return 1; }
  266.     expr "${stop_order}" + 0 > /dev/null 2>&1 && \
  267.         expr 0 \<= "${stop_order}" > /dev/null 2>&1 && \
  268.         test `expr length "${stop_order}"` -eq 2 > /dev/null 2>&1 || \
  269.         { echo "${self}: stop sequence number must be between 00 and 99" >&2;
  270.             return 1; }
  271. }
  272.  
  273. ## Add a service to a runlevel
  274. addrunlevel()
  275. {
  276.     self="addrunlevel"
  277.     ## Service name.
  278.     name="${1}"
  279.  
  280.     test -n "${name}" || \
  281.         { echo "${self}: missing argument" >&2; return 1; }
  282.     systemd_service_installed "${name}" && \
  283.         { systemctl -q enable "${name}"; return; }
  284.     if test -x "/etc/rc.d/init.d/${name}"; then
  285.         init_d_path=/etc/rc.d
  286.     elif test -x "/etc/init.d/${name}"; then
  287.         init_d_path=/etc
  288.     else
  289.         { echo "${self}: error: unknown init type" >&2; return 1; }
  290.     fi
  291.     get_chkconfig_info "${init_d_path}/init.d/${name}" || return 1
  292.     # Redhat based sysvinit systems
  293.     if test -x "`which chkconfig 2>/dev/null`"; then
  294.         chkconfig --add "${name}"
  295.     # SUSE-based sysvinit systems
  296.     elif test -x "`which insserv 2>/dev/null`"; then
  297.         insserv "${name}"
  298.     # Debian/Ubuntu-based systems
  299.     elif test -x "`which update-rc.d 2>/dev/null`"; then
  300.         # Old Debians did not support dependencies
  301.         update-rc.d "${name}" defaults "${start_order}" "${stop_order}"
  302.     # Gentoo Linux
  303.     elif test -x "`which rc-update 2>/dev/null`"; then
  304.         rc-update add "${name}" default
  305.     # Generic sysvinit
  306.     elif test -n "${init_d_path}/rc0.d"
  307.     then
  308.         for locali in 0 1 2 3 4 5 6
  309.         do
  310.             target="${init_d_path}/rc${locali}.d/K${stop_order}${name}"
  311.             expr "${runlevels}" : ".*${locali}" >/dev/null && \
  312.                 target="${init_d_path}/rc${locali}.d/S${start_order}${name}"
  313.             test -e "${init_d_path}/rc${locali}.d/"[KS][0-9]*"${name}" || \
  314.                 ln -fs "${init_d_path}/init.d/${name}" "${target}"
  315.         done
  316.     else
  317.         { echo "${self}: error: unknown init type" >&2; return 1; }
  318.     fi
  319. }
  320.  
  321.  
  322. ## Delete a service from a runlevel
  323. delrunlevel()
  324. {
  325.     self="delrunlevel"
  326.     ## Service name.
  327.     name="${1}"
  328.  
  329.     test -n "${name}" ||
  330.         { echo "${self}: missing argument" >&2; return 1; }
  331.     systemctl -q disable "${name}" >/dev/null 2>&1
  332.     # Redhat-based systems
  333.     chkconfig --del "${name}" >/dev/null 2>&1
  334.     # SUSE-based sysvinit systems
  335.     insserv -r "${name}" >/dev/null 2>&1
  336.     # Debian/Ubuntu-based systems
  337.     update-rc.d -f "${name}" remove >/dev/null 2>&1
  338.     # Gentoo Linux
  339.     rc-update del "${name}" >/dev/null 2>&1
  340.     # Generic sysvinit
  341.     rm -f /etc/rc.d/rc?.d/[SK]??"${name}"
  342.     rm -f /etc/rc?.d/[SK]??"${name}"
  343. }
  344.  
  345.  
  346. terminate_proc() {
  347.     PROC_NAME="${1}"
  348.     SERVER_PID=`pidof $PROC_NAME 2> /dev/null`
  349.     if [ "$SERVER_PID" != "" ]; then
  350.         killall -TERM $PROC_NAME > /dev/null 2>&1
  351.         sleep 2
  352.     fi
  353. }
  354.  
  355.  
  356. maybe_run_python_bindings_installer() {
  357.     VBOX_INSTALL_PATH="${1}"
  358.  
  359.     PYTHON=python
  360.     if [ ! `python -c 'print "test"' 2> /dev/null` = "test" ]; then
  361.         echo  1>&2 "Python not available, skipping bindings installation."
  362.         return 1
  363.     fi
  364.  
  365.     echo  1>&2 "Python found: $PYTHON, installing bindings..."
  366.     # Pass install path via environment
  367.     export VBOX_INSTALL_PATH
  368.     $SHELL -c "cd $VBOX_INSTALL_PATH/sdk/installer && $PYTHON vboxapisetup.py install \
  369.         --record $CONFIG_DIR/python-$CONFIG_FILES"
  370.     cat $CONFIG_DIR/python-$CONFIG_FILES >> $CONFIG_DIR/$CONFIG_FILES
  371.     rm $CONFIG_DIR/python-$CONFIG_FILES
  372.     # remove files created during build
  373.     rm -rf $VBOX_INSTALL_PATH/sdk/installer/build
  374.  
  375.     return 0
  376. }
  377.