#!/sbin/runscript # Copyright 1999-2004 Gentoo Foundation # Distributed under the terms of the GNU General Public License, v2 or later # $Header: $ [ -n "${PIDFILE}" ] || PIDFILE=/var/run/slimserver.pid depend() { after net } # Utility function to test files access rights. check_rights() { [ $# -lt 3 ] && return 2 local user=${1} ; shift local groups="$(groups ${user})" || return 1 local rights=${1} ; shift [ ${#rights} -ne 3 ] && return 2 local stat_u stat_g stat_a local file file_rights i # pos_rights is octal form of rights we want # pos_neg is octal form of rights we don't want local pos_rights=0 local neg_rights=0 for i in 0 1 2 ; do if [ "${rights:${i}:1}" != "-" ] \ && [ "${rights:${i}:1}" != "." ] ; then (( pos_rights += (2**(2-i)) )) elif [ "${rights:${i}:1}" = "-" ] ; then (( neg_rights += (2**(2-i)) )) fi done # Check that the rights spec holds for all files while [ $# -ge 1 ] ; do file="${1}" ; shift [ ! -e "${file}" ] && return 1 # Compute octal form of the rights user has on the file: read stat_u stat_g stat_a \ <<<$(stat -c"%U %G %a" "${file}") file_rights=${stat_a:2:1} [ "${user}" = "${stat_u}" ] \ && (( file_rights|=${stat_a:0:1} )) grep -q "\<${stat_g}\>" <<<${groups} \ && (( file_rights|=${stat_a:1:1} )) # Compare with what was requested: (( pos_rights == (file_rights & pos_rights) )) \ || return 1 (( neg_rights == ((~file_rights) & neg_rights) )) \ || return 1 done # Success only if all files are ok return 0 } start() { ebegin "Starting SlimServer" # This are settings that got a default value from the ebuild SLIM_INSTALL_DIR="${SLIM_INSTALL_DIR:-}" SLIM_HOME_DIR="${SLIM_HOME_DIR:-}" SLIM_LOG_FILE="${SLIM_LOG_FILE:-}" SLIM_CONFIG_FILE="${SLIM_CONFIG_FILE:-}" SLIM_USER="${SLIM_USER:-}" SLIM_GROUP="${SLIM_GROUP:-}" # For SLIM_{MUSIC,PLAYLIST,CACHE}_DIR, use defaults only if not already # defined in the config file. Otherwise, web config is useless. [ -f "${SLIM_CONFIG_FILE}" ] \ && grep -q "^audiodir[[:blank:]]*=[[:blank:]]*/" "${SLIM_CONFIG_FILE}" \ || SLIM_MUSIC_DIR="${SLIM_MUSIC_DIR:-}" [ -f "${SLIM_CONFIG_FILE}" ] \ && grep -q "^playlistdir[[:blank:]]*=[[:blank:]]*/" "${SLIM_CONFIG_FILE}" \ || SLIM_PLAYLISTS_DIR="${SLIM_PLAYLISTS_DIR:-}" [ -f "${SLIM_CONFIG_FILE}" ] \ && grep -q "^cachedir[[:blank:]]*=[[:blank:]]*/" "${SLIM_CONFIG_FILE}" \ || SLIM_CACHE_DIR="${SLIM_CACHE_DIR:-}" # Cleanup unset variables local var_names_list="SLIM_INSTALL_DIR SLIM_HOME_DIR SLIM_CACHE_DIR \ SLIM_MUSIC_DIR SLIM_PLAYLISTS_DIR SLIM_LOG_FILE SLIM_CONFIG_FILE \ SLIM_USER SLIM_GROUP" local var_name var_value for var_name in ${var_names_list} ; do eval var_value="\${${var_name}}" [ -z "${var_value}" ] || [ "${var_value}" = "unset" ] \ && unset "${var_name}" done # If SLIM_USER or SLIM_GROUP are unset, use "root:root": SLIM_USER="${SLIM_USER:-root}" SLIM_GROUP="${SLIM_GROUP:-root}" # Check $SLIM_USER grep -q "^${SLIM_USER}\\>" /etc/passwd \ || eend 1 "User \"${SLIM_USER}\" does not exists." \ || return 1 # Check $SLIM_GROUP grep -q "\\<${SLIM_GROUP}\\>" <( groups ${SLIM_USER} ) \ || eend 1 "User \"${SLIM_USER}\" is not in group \"${SLIM_GROUP}\"." \ || return 1 # Directories check/creation local mydir for mydir in "${SLIM_HOME_DIR}" "${SLIM_MUSIC_DIR}" \ "${SLIM_PLAYLISTS_DIR}" "${SLIM_CACHE_DIR}" do if [ -n "${mydir}" ] && [ ! -d "${mydir}" ] ; then einfo "Directory ${mydir} missing, creating..." mkdir -p "${mydir}" chown ${SLIM_USER}:${SLIM_GROUP} "${mydir}" if [ "${mydir}" = "${SLIM_MUSIC_DIR}" ] \ || [ "${mydir}" = "${SLIM_PLAYLISTS_DIR}" ] ; then # Chmod only if creating new dirs einfo "Making ${mydir} writable for group ${SLIM_GROUP}..." chmod 775 "${mydir}" fi fi done # Is cache dir rwx? [ -z "${SLIM_CACHE_DIR}" ] \ || check_rights ${SLIM_USER} "rwx" "${SLIM_CACHE_DIR}" \ || eend 1 "${SLIM_CACHE_DIR} should be writable for user ${SLIM_USER}:${SLIM_GROUP}" \ || return 1 # Is music dir r-x? [ -z "${SLIM_MUSIC_DIR}" ] \ || check_rights ${SLIM_USER} "r.x" "${SLIM_MUSIC_DIR}" \ || ewarn "${SLIM_MUSIC_DIR} is not readable for user ${SLIM_USER}:${SLIM_GROUP}" # Is playlist dir r-x? [ -z "${SLIM_PLAYLISTS_DIR}" ] \ || check_rights ${SLIM_USER} "r.x" "${SLIM_PLAYLISTS_DIR}" \ || ewarn "${SLIM_PLAYLISTS_DIR} is not readable for user ${SLIM_USER}:${SLIM_GROUP}" # Is playlist dir -w-? [ -z "${SLIM_PLAYLISTS_DIR}" ] \ || check_rights ${SLIM_USER} ".w." "${SLIM_PLAYLISTS_DIR}" \ || ewarn "${SLIM_PLAYLISTS_DIR} is not writable for user ${SLIM_USER}:${SLIM_GROUP}" # Config file check/creation if [ -n "${SLIM_CONFIG_FILE}" ] ; then if [ "${SLIM_DISABLE_SERVER_SETUP}" != "yes" ] \ && [ "${SLIM_DISABLE_SETUP}" != "yes" ] ; then touch "${SLIM_CONFIG_FILE}" \ || eend 1 "Can't write config file ${SLIM_CONFIG_FILE}" \ || return 1 chown ${SLIM_USER}:${SLIM_GROUP} "${SLIM_CONFIG_FILE}" chmod 644 "${SLIM_CONFIG_FILE}" fi check_rights ${SLIM_USER} "r.." "${SLIM_CONFIG_FILE}" \ || eend 1 "${SLIM_CONFIG_FILE} should be readable for user ${SLIM_USER}:${SLIM_GROUP}" \ || return 1 fi # Log file check/creation if [ -n "${SLIM_LOG_FILE}" ] && [ "${SLIM_LOG_FILE}" != "/dev/null" ] ; then touch "${SLIM_LOG_FILE}" \ || eend 1 "Can't write log file ${SLIM_LOG_FILE}" \ || return 1 chown ${SLIM_USER}:${SLIM_GROUP} "${SLIM_LOG_FILE}" chmod 644 "${SLIM_LOG_FILE}" fi # Prepare the server command line options. For some settings, to avoid # issues with spaces, we'll use a double quoting and then eval. local SLIM_OPTIONS [ -n "${SLIM_CONFIG_FILE}" ] && \ SLIM_OPTIONS="${SLIM_OPTIONS} --prefsfile=\"\${SLIM_CONFIG_FILE}\"" [ -n "${SLIM_MUSIC_DIR}" ] && \ SLIM_OPTIONS="${SLIM_OPTIONS} --audiodir=\"\${SLIM_MUSIC_DIR}\"" [ -n "${SLIM_PLAYLISTS_DIR}" ] && \ SLIM_OPTIONS="${SLIM_OPTIONS} --playlistdir=\"\${SLIM_PLAYLISTS_DIR}\"" [ -n "${SLIM_CACHE_DIR}" ] && \ SLIM_OPTIONS="${SLIM_OPTIONS} --cachedir=\"\${SLIM_CACHE_DIR}\"" [ -n "${SLIM_LOG_FILE}" ] && \ SLIM_OPTIONS="${SLIM_OPTIONS} --logfile=\"\${SLIM_LOG_FILE}\"" [ -n "${SLIM_HTTP_PORT}" ] && \ SLIM_OPTIONS="${SLIM_OPTIONS} --httpport=${SLIM_HTTP_PORT}" [ -n "${SLIM_HTTP_ADDR}" ] && \ SLIM_OPTIONS="${SLIM_OPTIONS} --httpaddr=${SLIM_HTTP_ADDR}" [ -n "${SLIM_CLI_PORT}" ] && \ SLIM_OPTIONS="${SLIM_OPTIONS} --cliport=${SLIM_CLI_PORT}" [ -n "${SLIM_CLI_ADDR}" ] && \ SLIM_OPTIONS="${SLIM_OPTIONS} --cliaddr=${SLIM_CLI_ADDR}" [ -n "${SLIM_PLAYER_ADDR}" ] && \ SLIM_OPTIONS="${SLIM_OPTIONS} --playeraddr=${SLIM_PLAYER_ADDR}" [ -n "${SLIM_STREAM_ADDR}" ] && \ SLIM_OPTIONS="${SLIM_OPTIONS} --streamaddr=${SLIM_STREAM_ADDR}" [ "${SLIM_DISABLE_SERVER_SETUP}" = "yes" ] && \ SLIM_OPTIONS="${SLIM_OPTIONS} --noserver" [ "${SLIM_DISABLE_SETUP}" = "yes" ] && \ SLIM_OPTIONS="${SLIM_OPTIONS} --nosetup" [ "${SLIM_DEBUG}" = "yes" ] && \ SLIM_OPTIONS="${SLIM_OPTIONS} --diag" [ "${SLIM_QUIET}" = "no" ] || \ SLIM_OPTIONS="${SLIM_OPTIONS} --quiet" # Prepare the start-stop-daemon command line options. We won't use the # daemonization features of the slimserver, because too much things are # done before it changes uid/gid, like loading plugins which may be a # security issue (and also it creates some files with wrong perms). local SSDAEMON_OPTIONS [ -n "${SLIM_PRIORITY}" ] && \ if [ ${SLIM_PRIORITY} -ge -20 -a ${SLIM_PRIORITY} -le 20 ] ; then SSDAEMON_OPTIONS="${SSDAEMON_OPTIONS} --priority=${SLIM_PRIORITY}" else ewarn "Invalid priority: ${SLIM_PRIORITY}" fi [ "${SLIM_USER}:${SLIM_GROUP}" != "root:root" ] && \ SSDAEMON_OPTIONS="${SSDAEMON_OPTIONS} --chuid=${SLIM_USER}:${SLIM_GROUP}" # Debug: #eval ewarn "SLIM_OPTIONS: ${SLIM_OPTIONS}" #ewarn "SSDAEMON_OPTIONS: ${SSDAEMON_OPTIONS}" # Launch the server eval start-stop-daemon --start --quiet --background --make-pidfile \ --pidfile="${PIDFILE}" ${SSDAEMON_OPTIONS} \ --exec="${SLIM_INSTALL_DIR}/slimserver" -- ${SLIM_OPTIONS} eend $? "Failed to start SlimServer" } stop() { ebegin "Stopping SlimServer" start-stop-daemon --stop --quiet --pidfile=${PIDFILE} local status=$? rm -f ${PIDFILE} eend ${status} "Failed to stop SlimServer" }