Out with the old, in with the new

This commit is contained in:
Salt 2020-05-15 03:21:28 -05:00
parent eb89a9343b
commit 4e65e0c71d
2 changed files with 429 additions and 429 deletions

View File

@ -6,60 +6,76 @@
# #
# Distributed under terms of the MIT license. # Distributed under terms of the MIT license.
# #
set -e
# "Globals" # Read-only set-once variables
_name="firestarter" declare -r _name="$(basename -- "$0")"
_configdir="${XDG_CONFIG_HOME:-$HOME/.config}/$_name" declare -r _sessionid="$(< /proc/self/sessionid)"
_logdir="${XDG_DATA_HOME:-$HOME/.local/share}/$_name/logs" # Options
_firestarterrc="$HOME/.firestarterrc" declare _optconfigdir="${XDG_CONFIG_HOME:-$HOME/.config}/${_name}"
_sessionid="$(< /proc/self/sessionid)" declare _optdryrun
# Dummy fd for read sleeping declare _optlogdir="$_optconfigdir/logs"
exec 1023<> <(:) declare _optpregen
declare -i _opthelp
declare -i _optverbose
# Working variables
declare -a _args
declare _return
# Basic functions # Helper functions
print() {
# Write a message to STDOUT without a name attached
# 1: That message
[ -z "$1" ] && return 1
printf "%s\\n" \
"$1"
}
log() { log() {
# Write a message to STDOUT # Print a line to the terminal if _optverbose is greater than $2
# 1: That message # $2 defaults to 0
# loglevel 0: Daily-use messages
# loglevel 1: Detailed but not quite debugging
# loglevel 2: Definitely debugging
[ -z "$1" ] && return 1 [ -z "$1" ] && return 1
printf "%s log: %s\\n" \ if (( _optverbose >= ${2:-0} )); then
"$_name" \ printf "%s\\n" "$1"
"$1" >&1
}
err() {
# Write a message to STDERR, also exit if arg 2 is specified
# 1: That message
# 2: An optional exit code (will only exit if provided)
[ -z "$1" ] && return 1
printf "%s err: %s\\n" \
"$_name" \
"$1" >&2
[ -z "$2" ] && return 0
if ! [ "$2" -ge "0" ] > /dev/null 2>&1; then
err "Attempted to exit with malformed exit code \"$2\"" 10
else
exit "$2"
fi fi
} }
has() { warn() {
# See if a program exists in $PATH # Print a yellow line to the terminal, respecting _optverbose
# 1: A program
[ -z "$1" ] && return 1 [ -z "$1" ] && return 1
command -v "$1" > /dev/null 2>&1 if (( _optverbose >= ${2:-0} )); then
if [ -t 1 ]; then
printf "\\e[33m%s\\e[0m\\n" "$1"
else
printf "WARN: %s\\n" "$1"
fi
fi
} }
gettarget() { error() {
# Parse a defaults file to get the target program # Print a red line to the terminal, exit if $2 is specified
# 1: A defaults file
[ -z "$1" ] && return 1 [ -z "$1" ] && return 1
if [ -t 2 ]; then
printf "\\e[31m%s\\e[0m\\n" "$1" 1>&2
else
printf "ERROR: %s\\n" "$1" 1>&2
fi
[ -z "$2" ] && return
exit "${2:-1}"
}
has() {
# Parse out all arguments and try to find them in path
# If an argument cannot be found, set _return and fail
for prog in "$@"; do
if ! command -v "$prog" > /dev/null 2>&1; then
_return="$prog"
return 1
fi
done
return 0
}
# Core program functions
gettarget() {
# Parse a defaults file to get a target program
[ -z "$1" ] && return 1
[ -d "$1" ] && return 1
[ -r "$1" ] || return 1 [ -r "$1" ] || return 1
# Every odd line is the check line # Every odd line is a condition
# Every even one is the exec line # Every even one is a target
local firstline local firstline
while read -r checkline; do while read -r checkline; do
if [ -z "$firstline" ]; then if [ -z "$firstline" ]; then
@ -70,9 +86,7 @@ gettarget() {
return 50 return 50
fi fi
fi fi
if [ "${checkline#"#"}" != "$checkline" ]; then [ "${checkline#"#"}" != "$checkline" ] && continue
continue
fi
read -r execline read -r execline
if bash -c "$checkline" > /dev/null 2>&1; then if bash -c "$checkline" > /dev/null 2>&1; then
_return="$execline" _return="$execline"
@ -83,19 +97,17 @@ gettarget() {
done < "$1" done < "$1"
return 2 return 2
} }
genconfigs() {
# Steps in execution log "Creating default config setup in \"$_optconfigdir\""
step_generate() {
log "Creating default config setup in \"$_configdir\""
log "See firestarter -h for more information" log "See firestarter -h for more information"
# Audio daemon # Audio daemon
cat << EOF > "$_configdir/audio-daemon" cat << EOF > "$_optconfigdir/audio-daemon"
#.fsdefaults #.fsdefaults
command -v pulseaudio command -v pulseaudio
pulseaudio pulseaudio
EOF EOF
# Information bars # Information bars
cat << EOF > "$_configdir/bar" cat << EOF > "$_optconfigdir/bar"
#.fsdefaults #.fsdefaults
command -v polybar && [ -r "$HOME/.config/polybar/launch.sh" ] command -v polybar && [ -r "$HOME/.config/polybar/launch.sh" ]
"$HOME/.config/polybar/launch.sh" "$HOME/.config/polybar/launch.sh"
@ -111,7 +123,7 @@ command -v xfce4-panel
xfce4-panel xfce4-panel
EOF EOF
# Blue light filter # Blue light filter
cat << EOF > "$_configdir/blue-light-filter" cat << EOF > "$_optconfigdir/blue-light-filter"
#.fsdefaults #.fsdefaults
command -v redshift-gtk command -v redshift-gtk
redshift-gtk redshift-gtk
@ -119,7 +131,7 @@ command -v redshift
redshift redshift
EOF EOF
# Compositor # Compositor
cat << EOF > "$_configdir/compositor" cat << EOF > "$_optconfigdir/compositor"
#.fsdefaults #.fsdefaults
[ -z "\$DISPLAY" ] [ -z "\$DISPLAY" ]
: :
@ -131,7 +143,7 @@ command -v xcompmgr
xcompmgr xcompmgr
EOF EOF
# Polkit authentication agents # Polkit authentication agents
cat << EOF > "$_configdir/polkit-agent" cat << EOF > "$_optconfigdir/polkit-agent"
#.fsdefaults #.fsdefaults
command -v lxqt-policykit-agent command -v lxqt-policykit-agent
lxqt-policykit-agent lxqt-policykit-agent
@ -176,7 +188,7 @@ polkit-efl-authentication-agent-1
/usr/libexec/polkit-gnome-authentication-agent-1 /usr/libexec/polkit-gnome-authentication-agent-1
EOF EOF
# Hotkey daemon # Hotkey daemon
cat << EOF > "$_configdir/hotkey-daemon" cat << EOF > "$_optconfigdir/hotkey-daemon"
#.fsdefaults #.fsdefaults
[ -z "\$DISPLAY" ] [ -z "\$DISPLAY" ]
: :
@ -186,13 +198,13 @@ command -v lxqt-globalkeysd
lxqt-globalkeysd lxqt-globalkeysd
EOF EOF
# Network daemon # Network daemon
cat << EOF > "$_configdir/network-daemon" cat << EOF > "$_optconfigdir/network-daemon"
#.fsdefaults #.fsdefaults
command -v nm-applet command -v nm-applet
nm-applet nm-applet
EOF EOF
# Notification daemon # Notification daemon
cat << EOF > "$_configdir/notification-daemon" cat << EOF > "$_optconfigdir/notification-daemon"
#.fsdefaults #.fsdefaults
[ -z "\$DISPLAY" ] [ -z "\$DISPLAY" ]
: :
@ -202,7 +214,7 @@ command -v lxqt-notificationd
notificationd notificationd
EOF EOF
# Power daemons # Power daemons
cat << EOF > "$_configdir/power-daemon" cat << EOF > "$_optconfigdir/power-daemon"
#.fsdefaults #.fsdefaults
command -v batterymon command -v batterymon
batterymon batterymon
@ -219,13 +231,13 @@ gnome-power-manager
EOF EOF
# Runners # Runners
# Note that rofi is not a daemon and is not included here # Note that rofi is not a daemon and is not included here
cat << EOF > "$_configdir/runner" cat << EOF > "$_optconfigdir/runner"
#.fsdefaults #.fsdefaults
command -v krunner command -v krunner
krunner krunner
EOF EOF
# Settings daemons # Settings daemons
cat << EOF > "$_configdir/settings-daemon" cat << EOF > "$_optconfigdir/settings-daemon"
#.fsdefaults #.fsdefaults
command -v xsettingsd command -v xsettingsd
xsettingsd xsettingsd
@ -241,7 +253,7 @@ command -v gnome-settings-daemon
gnome-settings-daemon gnome-settings-daemon
EOF EOF
# System statistics glances # System statistics glances
cat << EOF > "$_configdir/stat-glances" cat << EOF > "$_optconfigdir/stat-glances"
#.fsdefaults #.fsdefaults
[ -z "\$DISPLAY" ] [ -z "\$DISPLAY" ]
: :
@ -251,7 +263,7 @@ command -v conky && [ -r "\${XDG_CONFIG_HOME:-$HOME/.config}/conky/conky.conf" ]
sleep 5 && conky sleep 5 && conky
EOF EOF
# Wallpaper setters # Wallpaper setters
cat << EOF > "$_configdir/wallpaper" cat << EOF > "$_optconfigdir/wallpaper"
#.fsdefaults #.fsdefaults
[ -z "\$DISPLAY" ] [ -z "\$DISPLAY" ]
: :
@ -261,7 +273,7 @@ command -v nitrogen
nitrogen --restore nitrogen --restore
EOF EOF
# Window managers # Window managers
cat << EOF > "$_configdir/wm" cat << EOF > "$_optconfigdir/wm"
#.fsdefaults #.fsdefaults
[ -z "\$DISPLAY" ] [ -z "\$DISPLAY" ]
: :
@ -327,125 +339,70 @@ command -v tinywm
tinywm tinywm
EOF EOF
} }
step_printhelp() {
cat << EOF
Usage: $(basename -- "$0") [OPTION...]
Start or generate a desktop environment configuration
-h Show this help text
-g Generate a default configuration. This will clobber
-d Perform a dry run. This will print the results of all decisions
without executing them.
Additionally, $(basename -- "$0") responds to the following environment variables:
FS_DIEONWM If nonempty, end the session when the WM dies. This is useful
both for preventing session lock-ins and for using built-in WM
features to log out of the session.
FS_NOLOG If nonempty, create no log files
FS_NOWAITWM If nonempty, skip waiting on the WM to initialize
Copyright (c) 2019 rehashedsalt@cock.li
Licensed under the MIT License
https://gitlab.com/rehashedsalt/firestarter
EOF
}
step_check() {
if [ -z "$_dryrun" ] && [ -z "$_generate" ]; then
for pid in $(pgrep firestarter); do
# Skip invalid PIDs
! [ -d "/proc/$pid" ] && continue
# If it's not our session then who cares
[ "$_sessionid" != "$(< "/proc/$pid/sessionid")" ] && continue
if [ "$pid" != "$BASHPID" ]; then
err "Firestarter is already running: $pid" 40
fi
done
fi
if ! [ -d "$HOME" ] || ! [ -r "$HOME" ]; then
err "Inaccessible home directory: \"$HOME\"" 54
fi
if ! [ -d "$_configdir" ]; then
if ! mkdir -p "$_configdir" > /dev/null 2>&1; then
err "Failed to create configuration directory: \"$_configdir\"" 52
fi
fi
return 0
}
step_preexecute() { step_preexecute() {
# Special things that can't use simple configuration files # Special things that can't use simple configuration files
[ -n "$_dryrun" ] && return 0 [ -n "$_optdryrun" ] && return 0
[ -r "$HOME/.xsessionrc" ] && . "$HOME/.xsessionrc"
# Xsessionrc
[ -r "$HOME/.xsessionrc" ] && source "$HOME/.xsessionrc"
# Exports
export XDG_CURRENT_DESKTOP="${XDG_CURRENT_DESKTOP:-firestarter}" export XDG_CURRENT_DESKTOP="${XDG_CURRENT_DESKTOP:-firestarter}"
# dbus # dbus
if \ if \
[ -z "$DBUS_SESSION_BUS_ADDRESS" ] && \ [ -z "$DBUS_SESSION_BUS_ADDRESS" ] && \
[ -n "$XDG_RUNTIME_DIR" ] && \ [ -n "$XDG_RUNTIME_DIR" ] && \
[ "$XDG_RUNTIME_DIR" = "/run/user/$(id -u)" ] && \ [ "$XDG_RUNTIME_DIR" = "/run/user/$(id -u)" ] && \
[ -S "$XDG_RUNTIME_DIR/bus" ]; then [ -S "$XDG_RUNTIME_DIR/bus" ]; then
# We already have a bus started, use it # We already have a bus started; use it
export DBUS_SESSION_BUS_ADDRESS="unix:path=$XDG_RUNTIME_DIR/bus" export DBUS_SESSION_BUS_ADDRESS="unix:path=$XDG_RUNTIME_DIR/bus"
hasdbus=1 hasdbus=1
elif \ elif \
[ -z "$DBUS_SESSION_BUS_ADDRESS" ] && \ [ -z "$DBUS_SESSION_BUS_ADDRESS" ] && \
has dbus-launch; then has dbus-launch; then
# We have dbus but haven't started up a bus yet # We have dbus but haven't started it yet
eval "$(dbus-launch --exit-with-session --sh-syntax)" eval "$(dbus-laucnh --exit-with-session --sh-syntax)"
hasdbus=1 hasdbus=1
else else
log "Did not start dbus; some applications may misbehave" warn "Did not start dbus; some applications may misbehave"
fi fi
if [ -n "$hasdbus" ]; then if [ -n "$hasdbus" ]; then
if has dbus-update-activation-environment; then has dbus-update-activation-environment && \
dbus-update-activation-environment --verbose --systemd --all > /dev/null 2>&1 dbus-update-activation-environment --verbose --systemd --all >/dev/null 2>&1
fi
fi fi
unset hasdbus unset hasdbus
# kcminit/Qt settings # kcminit/Qt settings
if has kcminit; then if has kcminit; then
log "Initializing KDE Control Module settings" log "Initializing KDE Control Module settings"
kcminit > /dev/null 2>&1 kcminit >/dev/null 2>&1
export XDG_CURRENT_DESKTOP="KDE" export XDG_CURRENT_DESKTOP="KDE"
elif has qt5ct; then elif has qt5ct; then
log "Integrating qt5ct" log "Initializing qt5ct"
if [ -z "$QT_QPA_PLATFORMTHEME" ]; then if [ -z "$QT_QPA_PLATFORMTHEME" ]; then
export QT_QPA_PLATFORMTHEME="qt5ct" export QT_QPA_PLATFORMTHEME="qt5ct"
log "Exporting QT_QPA_PLATFORMTHEME as \"$QT_QPA_PLATFORMTHEME\"" log "Exporting QT_QPA_PLATFORMTHEME as \"$QT_QPA_PLATFORMTHEME\"" 2
else else
log "Using existing theme setting \"$QT_QPA_PLATFORMTHEME\"" log "Using existing theme setting \"$QT_QPA_PLATFORMTHEME\"" 2
fi fi
if [ -z "$QT_AUTO_SCREEN_SCALE_FACTOR" ]; then if [ -z "$QT_AUTO_SCREEN_SCALE_FACTOR" ]; then
export QT_AUTO_SCREEN_SCALE_FACTOR="0" export QT_AUTO_SCREEN_SCALE_FACTOR="0"
log "Exporting QT_AUTO_SCREEN_SCALE_FACTOR as $QT_AUTO_SCREEN_SCALE_FACTOR" log "Exporting QT_AUTO_SCREEN_SCALE_FACTOR as \"$QT_AUTO_SCREEN_SCALE_FACTOR\"" 2
else else
log "Using existing scale setting \"$QT_AUTO_SCREEN_SCALE_FACTOR\"" log "Using existing scale factor \"$QT_AUTO_SCREEN_SCALE_FACTOR\"" 2
fi fi
fi fi
# xhost # xhost
if has xhost; then if has xhost; then
if xhost +si:localuser:"$(id -un)" > /dev/null 2>&1; then if xhost +si:localuser:"$(id -un)" >/dev/null 2>&1; then
log "Session can be accessed in other sessions by this user" log "Session open to other sessions by this user"
else else
log "Failed to open session up via xhost" warn "Failed to open session via xhost"
fi fi
fi fi
# xresources # xresources
if [ -n "$DISPLAY" ] && has xrdb && [ -r "$HOME/.Xresources" ]; then if [ -n "$DISPLAY" ] && has xrdb && [ -r "$HOME/.Xresources" ]; then
if xrdb "$HOME/.Xresources" > /dev/null 2>&1; then if xrdb "$HOME/.Xresources" >/dev/null 2>&1; then
log "Loaded in .Xresources" log "Loaded in .Xresources"
else else
log "Failed to load .Xresources" warn "Failed to load .Xresources"
fi fi
fi fi
# xset # xset
if has xset; then if has xset; then
log "Disabling bell" log "Disabling bell"
@ -453,84 +410,81 @@ step_preexecute() {
fi fi
} }
step_execute() { step_execute() {
# Ensure we can log if we have to # Parse out our defaults lists and execute their targets
if [ -n "$FS_NOLOG" ]; then if ! [ -d "$_optlogdir" ]; then
log "No logs will be created per FS_NOLOG" if ! mkdir -p "$_optlogdir" >/dev/null 2>&1; then
elif ! [ -d "$_logdir" ]; then error "Failed to create log directory: \"$_optlogdir\"" 53
if ! mkdir -p "$_logdir" > /dev/null 2>&1; then
err "Failed to create log directory: \"$_logdir\"" 53
fi fi
fi fi
# Parse configs for file in "$_optconfigdir"/*; do
for file in "$_configdir"/*; do
if ! [ -e "$file" ]; then if ! [ -e "$file" ]; then
log "No configuration files found; generating defaults" log "No configuration files found; generating defaults"
step_generate genconfigs
step_execute step_execute
break return
fi fi
# Skip our logs directory
[ "$_optlogdir" == "$file" ] && continue
local filename="$(basename -- "$file")" local filename="$(basename -- "$file")"
local logfile="$_logdir/$filename" local logfile="$_optlogdir/$filename.log"
[ -n "$FS_NOLOG" ] && logfile="/dev/null"
if gettarget "$file"; then if gettarget "$file"; then
# It's a defaults file with a selected target # It's a defaults file with a selected target
target="$_return" target="$_return"
log "Found target for \"$filename\": \"$target\"" log "Found target for $filename: \"$target\""
if [ -z "$_dryrun" ]; then [ -n "$_optdryrun" ] && continue
if [ -f "$logfile" ]; then if [ -f "$logfile" ]; then
[ -f "$logfile.old" ] && rm "$logfile.old" [ -f "$logfile.old" ] && rm "$logfile.old"
mv "$logfile" "$logfile.old" mv "$logfile" "$logfile.old"
fi
bash -c "$target" > "$logfile" 2>&1 &
fi fi
bash -c "$target" > "$logfile" 2>&1 &
elif [ $? = 50 ] && [ -x "$file" ]; then elif [ $? = 50 ] && [ -x "$file" ]; then
# It's a shell script or something # It's a shell script or executable symlink
log "Executing file straight out: \"$filename\"" log "Executing file: \"$filename\""
if [ -z "$_dryrun" ]; then [ -n "$_optdryrun" ] && continue
"$file" > "$logfile" 2>&1 & "$file" > "$logfile" 2>&1 &
fi
else else
err "Could not execute file: \"$filename\"" warn "Could not execute file: \"$filename\""
fi fi
done done
} }
step_postexecute() { step_postexecute() {
# Wait for the WM to initialize, if one was found and we have the tools # Wait for the WM to initialize, if one was found and we have the tools
if [ -z "$FS_NOWAITWM" ] && gettarget "$_configdir/wm" && has xprop && has grep; then if [ -z "$FS_NOWAITWM" ] && gettarget "$_configdir/wm" && has xprop grep; then
log "Waiting for WM to initialize: \"$_return\"" log "Waiting for WM to initialize: \"$_return\""
for (( i=0; i<10; i++ )); do for (( i=0; i<10; i++ )); do
line="$(xprop -root | grep ^_NET_WM_NAME | grep -o '"\S*"$')" line="$(xprop -root | grep ^_NET_WM_NAME | grep -o '"\S*"$')"
if [ -n "$line" ]; then if [ -n "$line" ]; then
log "WM has intiailized, _NET_WM_NAME atom reads: $line" log "WM has initialized, _NET_WM_NAME atom reads: $line"
break break
fi fi
read -t 1 -u 1023 read -t 1 -u 1023
done done
fi fi
# Dumb Polybar workaround # Dumb polybar workaround
killall polybar -SIGUSR1 killall polybar -SIGUSR1
# Execute a user script if it exists # Execute a user rc if it exists
if [ -r "$_firestarterrc" ] && [ -z "$_dryrun" ]; then local firestarterrc="$HOME/.firestarterrc"
log "Executing .firestarterrc" if [ -r "$firestarterrc" ] && [ -z "$dryrun" ]; then
"$_firestarterrc" log "Executing rc script: $firestarterrc"
"$firestarterrc"
fi fi
# Start XDG autostarters, if they exist # Start XDG autostarters, if they exist
if [ -z "$_dryrun" ]; then if [ -z "$_optdryrun" ]; then
if has dex; then if has dex; then
dex -a > /dev/null 2>&1 dex -a >/dev/null 2>&1
elif has fbautostart; then elif has fbautostart; then
fbautostart > /dev/null 2>&1 fbautostart > /dev/null 2>&1
elif has xdg-autostart; then elif has xdg-autostart; then
xdg-autostart ${XDG_CURRENT_DESKTOP:-firestarter} xdg-autostart ${XDG_CURRENT_DESKTOP:-firestarter}
else else
err "Could not find an XDG autostarter" warn "Could not find an XDG autostarter"
fi fi
fi fi
} }
step_wait() { step_wait() {
[ -n "$_dryrun" ] && exit 0 [ -n "$_optdryrun" ] && exit 0
trap step_logout EXIT trap step_logout EXIT
if [ -n "$FS_DIEONWM" ] && gettarget "$_configdir/wm" && has readlink && has "$_return"; then if [ -n "$FS_DIEONWM" ] && gettarget "$_configdir/wm" && has readlink "$_return"; then
target="$(command -v "$_return")" target="$(command -v "$_return")"
for job in $(jobs -p); do for job in $(jobs -p); do
if [ "$target" = "$(readlink /proc/$job/exe)" ]; then if [ "$target" = "$(readlink /proc/$job/exe)" ]; then
@ -539,7 +493,7 @@ step_wait() {
exit 0 exit 0
fi fi
done done
err "Could not find WM: \"$target\"" warn "Could not find WM: \"$target\""
fi fi
log "Waiting for programs to exit" log "Waiting for programs to exit"
wait wait
@ -553,45 +507,108 @@ step_logout() {
loginctl terminate-session "$_sessionid" loginctl terminate-session "$_sessionid"
fi fi
else else
# Otherwise just brute it # Otherwise just brute it out
kill $(jobs -p) kill $(jobs -p)
fi fi
return 0 return 0
} }
printhelp() {
cat << EOF
Usage: $_name [OPTION]...
-d Perform a dry run; print what programs would have been
executed instead of doing so
-g Regenerate default configs. This will clobber
-h Print this help text
-v Print more status messages. Stacks
Environment Variables:
FS_DIEONWM If nonempty, end the session when the WM dies.
FS_NOWAITWM If nonempty, skip waiting for the WM to initialize
Copyright (c) 2019 rehashedsalt@cock.li
Licensed under the MIT license
EOF
}
# Main # Main
main() { main() {
while getopts ":dgh" opt; do # Parse out arguments
case $opt in while [ -n "$1" ]; do
d) # Parse out flags
_dryrun=1 while getopts ":dghv" opt; do
;; case $opt in
g) d)
_generate=1 _optdryrun=1
;; ;;
h) g)
step_printhelp _optpregen=1
exit $? ;;
;; h)
*) _opthelp=1
err "Unrecognized argument: \"$OPTARG\"" 50 ;;
;; v)
:) _optverbose+=1
err "Invalid option: \"$OPTARG\"" 51 ;;
;; :)
esac error "Option requires argument: -$OPTARG" 2
;;
*)
error "Invalid option: -$OPTARG" 2
;;
esac
done
# Store arguments
shift $((OPTIND - 1))
if [ -n "$1" ]; then
_args+=("$1")
shift
fi
unset OPTIND
done done
step_check # Early hook for help
if [ -n "$_generate" ]; then [ -n "$_opthelp" ] && printhelp && exit 0
step_generate # Early hook for generating configs
else [ -n "$_optpregen" ] && genconfigs && exit $?
[ -n "$_dryrun" ] && log "Performing a dry run" # Ensure our running environment is sane and that we're not about to nest
step_preexecute if [ -z "$_optdryrun" ] && [ -z "$_optpregen" ]; then
step_execute for pid in $(pgrep firestarter); do
step_postexecute # Skip invalid PIDs
step_wait ! [ -d "$/proc/$pid" ] && continue
# If it's not our session then who cares
[ "$_sessionid" != "$(< "/proc/$pid/sessionid")" ] && continue
# If it's us then who cares
[ "$pid" == "$BASHPID" ] && continue
# We care
error "Firestarter is already running: $pid" 40
done
fi fi
return 0 if ! [ -d "$HOME" ] || ! [ -r "$HOME" ]; then
error "Home directory not found or inaccessable: \"$HOME\"" 54
fi
if ! [ -d "$_optconfigdir" ]; then
if [ -f "$_optconfigdir" ]; then
error "Config directory is a file, should be directory: \"$_optconfigdir\"" 52
fi
if ! mkdir -p "$_optconfigdir" > /dev/null 2>&1; then
error "Failed to find or create config directory: \"$_optconfigdir\"" 52
fi
fi
# Validate core program dependencies
log "Validating dependencies" 2
if ! has basename; then
error "Failed to find program: $_return" 1
fi
# Do the do
[ -n "$_optdryrun" ] && log "Performing a dry run"
step_preexecute
step_execute
step_wait
step_logout
exit 0
} }
main "$@" main "$@"

View File

@ -6,76 +6,60 @@
# #
# Distributed under terms of the MIT license. # Distributed under terms of the MIT license.
# #
set -e
# Read-only set-once variables # "Globals"
declare -r _name="$(basename -- "$0")" _name="firestarter"
declare -r _sessionid="$(< /proc/self/sessionid)" _configdir="${XDG_CONFIG_HOME:-$HOME/.config}/$_name"
# Options _logdir="${XDG_DATA_HOME:-$HOME/.local/share}/$_name/logs"
declare _optconfigdir="${XDG_CONFIG_HOME:-$HOME/.config}/${_name}" _firestarterrc="$HOME/.firestarterrc"
declare _optdryrun _sessionid="$(< /proc/self/sessionid)"
declare _optlogdir="$_optconfigdir/logs" # Dummy fd for read sleeping
declare _optpregen exec 1023<> <(:)
declare -i _opthelp
declare -i _optverbose
# Working variables
declare -a _args
declare _return
# Helper functions # Basic functions
print() {
# Write a message to STDOUT without a name attached
# 1: That message
[ -z "$1" ] && return 1
printf "%s\\n" \
"$1"
}
log() { log() {
# Print a line to the terminal if _optverbose is greater than $2 # Write a message to STDOUT
# $2 defaults to 0 # 1: That message
# loglevel 0: Daily-use messages
# loglevel 1: Detailed but not quite debugging
# loglevel 2: Definitely debugging
[ -z "$1" ] && return 1 [ -z "$1" ] && return 1
if (( _optverbose >= ${2:-0} )); then printf "%s log: %s\\n" \
printf "%s\\n" "$1" "$_name" \
fi "$1" >&1
} }
warn() { err() {
# Print a yellow line to the terminal, respecting _optverbose # Write a message to STDERR, also exit if arg 2 is specified
# 1: That message
# 2: An optional exit code (will only exit if provided)
[ -z "$1" ] && return 1 [ -z "$1" ] && return 1
if (( _optverbose >= ${2:-0} )); then printf "%s err: %s\\n" \
if [ -t 1 ]; then "$_name" \
printf "\\e[33m%s\\e[0m\\n" "$1" "$1" >&2
else [ -z "$2" ] && return 0
printf "WARN: %s\\n" "$1" if ! [ "$2" -ge "0" ] > /dev/null 2>&1; then
fi err "Attempted to exit with malformed exit code \"$2\"" 10
fi
}
error() {
# Print a red line to the terminal, exit if $2 is specified
[ -z "$1" ] && return 1
if [ -t 2 ]; then
printf "\\e[31m%s\\e[0m\\n" "$1" 1>&2
else else
printf "ERROR: %s\\n" "$1" 1>&2 exit "$2"
fi fi
[ -z "$2" ] && return
exit "${2:-1}"
} }
has() { has() {
# Parse out all arguments and try to find them in path # See if a program exists in $PATH
# If an argument cannot be found, set _return and fail # 1: A program
for prog in "$@"; do [ -z "$1" ] && return 1
if ! command -v "$prog" > /dev/null 2>&1; then command -v "$1" > /dev/null 2>&1
_return="$prog" }
return 1 gettarget() {
fi # Parse a defaults file to get the target program
done # 1: A defaults file
return 0
}
# Core program functions
gettarget() {
# Parse a defaults file to get a target program
[ -z "$1" ] && return 1 [ -z "$1" ] && return 1
[ -d "$1" ] && return 1
[ -r "$1" ] || return 1 [ -r "$1" ] || return 1
# Every odd line is a condition # Every odd line is the check line
# Every even one is a target # Every even one is the exec line
local firstline local firstline
while read -r checkline; do while read -r checkline; do
if [ -z "$firstline" ]; then if [ -z "$firstline" ]; then
@ -86,7 +70,9 @@ gettarget() {
return 50 return 50
fi fi
fi fi
[ "${checkline#"#"}" != "$checkline" ] && continue if [ "${checkline#"#"}" != "$checkline" ]; then
continue
fi
read -r execline read -r execline
if bash -c "$checkline" > /dev/null 2>&1; then if bash -c "$checkline" > /dev/null 2>&1; then
_return="$execline" _return="$execline"
@ -97,17 +83,19 @@ gettarget() {
done < "$1" done < "$1"
return 2 return 2
} }
genconfigs() {
log "Creating default config setup in \"$_optconfigdir\"" # Steps in execution
step_generate() {
log "Creating default config setup in \"$_configdir\""
log "See firestarter -h for more information" log "See firestarter -h for more information"
# Audio daemon # Audio daemon
cat << EOF > "$_optconfigdir/audio-daemon" cat << EOF > "$_configdir/audio-daemon"
#.fsdefaults #.fsdefaults
command -v pulseaudio command -v pulseaudio
pulseaudio pulseaudio
EOF EOF
# Information bars # Information bars
cat << EOF > "$_optconfigdir/bar" cat << EOF > "$_configdir/bar"
#.fsdefaults #.fsdefaults
command -v polybar && [ -r "$HOME/.config/polybar/launch.sh" ] command -v polybar && [ -r "$HOME/.config/polybar/launch.sh" ]
"$HOME/.config/polybar/launch.sh" "$HOME/.config/polybar/launch.sh"
@ -123,7 +111,7 @@ command -v xfce4-panel
xfce4-panel xfce4-panel
EOF EOF
# Blue light filter # Blue light filter
cat << EOF > "$_optconfigdir/blue-light-filter" cat << EOF > "$_configdir/blue-light-filter"
#.fsdefaults #.fsdefaults
command -v redshift-gtk command -v redshift-gtk
redshift-gtk redshift-gtk
@ -131,7 +119,7 @@ command -v redshift
redshift redshift
EOF EOF
# Compositor # Compositor
cat << EOF > "$_optconfigdir/compositor" cat << EOF > "$_configdir/compositor"
#.fsdefaults #.fsdefaults
[ -z "\$DISPLAY" ] [ -z "\$DISPLAY" ]
: :
@ -143,7 +131,7 @@ command -v xcompmgr
xcompmgr xcompmgr
EOF EOF
# Polkit authentication agents # Polkit authentication agents
cat << EOF > "$_optconfigdir/polkit-agent" cat << EOF > "$_configdir/polkit-agent"
#.fsdefaults #.fsdefaults
command -v lxqt-policykit-agent command -v lxqt-policykit-agent
lxqt-policykit-agent lxqt-policykit-agent
@ -188,7 +176,7 @@ polkit-efl-authentication-agent-1
/usr/libexec/polkit-gnome-authentication-agent-1 /usr/libexec/polkit-gnome-authentication-agent-1
EOF EOF
# Hotkey daemon # Hotkey daemon
cat << EOF > "$_optconfigdir/hotkey-daemon" cat << EOF > "$_configdir/hotkey-daemon"
#.fsdefaults #.fsdefaults
[ -z "\$DISPLAY" ] [ -z "\$DISPLAY" ]
: :
@ -198,13 +186,13 @@ command -v lxqt-globalkeysd
lxqt-globalkeysd lxqt-globalkeysd
EOF EOF
# Network daemon # Network daemon
cat << EOF > "$_optconfigdir/network-daemon" cat << EOF > "$_configdir/network-daemon"
#.fsdefaults #.fsdefaults
command -v nm-applet command -v nm-applet
nm-applet nm-applet
EOF EOF
# Notification daemon # Notification daemon
cat << EOF > "$_optconfigdir/notification-daemon" cat << EOF > "$_configdir/notification-daemon"
#.fsdefaults #.fsdefaults
[ -z "\$DISPLAY" ] [ -z "\$DISPLAY" ]
: :
@ -214,7 +202,7 @@ command -v lxqt-notificationd
notificationd notificationd
EOF EOF
# Power daemons # Power daemons
cat << EOF > "$_optconfigdir/power-daemon" cat << EOF > "$_configdir/power-daemon"
#.fsdefaults #.fsdefaults
command -v batterymon command -v batterymon
batterymon batterymon
@ -231,13 +219,13 @@ gnome-power-manager
EOF EOF
# Runners # Runners
# Note that rofi is not a daemon and is not included here # Note that rofi is not a daemon and is not included here
cat << EOF > "$_optconfigdir/runner" cat << EOF > "$_configdir/runner"
#.fsdefaults #.fsdefaults
command -v krunner command -v krunner
krunner krunner
EOF EOF
# Settings daemons # Settings daemons
cat << EOF > "$_optconfigdir/settings-daemon" cat << EOF > "$_configdir/settings-daemon"
#.fsdefaults #.fsdefaults
command -v xsettingsd command -v xsettingsd
xsettingsd xsettingsd
@ -253,7 +241,7 @@ command -v gnome-settings-daemon
gnome-settings-daemon gnome-settings-daemon
EOF EOF
# System statistics glances # System statistics glances
cat << EOF > "$_optconfigdir/stat-glances" cat << EOF > "$_configdir/stat-glances"
#.fsdefaults #.fsdefaults
[ -z "\$DISPLAY" ] [ -z "\$DISPLAY" ]
: :
@ -263,7 +251,7 @@ command -v conky && [ -r "\${XDG_CONFIG_HOME:-$HOME/.config}/conky/conky.conf" ]
sleep 5 && conky sleep 5 && conky
EOF EOF
# Wallpaper setters # Wallpaper setters
cat << EOF > "$_optconfigdir/wallpaper" cat << EOF > "$_configdir/wallpaper"
#.fsdefaults #.fsdefaults
[ -z "\$DISPLAY" ] [ -z "\$DISPLAY" ]
: :
@ -273,7 +261,7 @@ command -v nitrogen
nitrogen --restore nitrogen --restore
EOF EOF
# Window managers # Window managers
cat << EOF > "$_optconfigdir/wm" cat << EOF > "$_configdir/wm"
#.fsdefaults #.fsdefaults
[ -z "\$DISPLAY" ] [ -z "\$DISPLAY" ]
: :
@ -339,70 +327,125 @@ command -v tinywm
tinywm tinywm
EOF EOF
} }
step_printhelp() {
cat << EOF
Usage: $(basename -- "$0") [OPTION...]
Start or generate a desktop environment configuration
-h Show this help text
-g Generate a default configuration. This will clobber
-d Perform a dry run. This will print the results of all decisions
without executing them.
Additionally, $(basename -- "$0") responds to the following environment variables:
FS_DIEONWM If nonempty, end the session when the WM dies. This is useful
both for preventing session lock-ins and for using built-in WM
features to log out of the session.
FS_NOLOG If nonempty, create no log files
FS_NOWAITWM If nonempty, skip waiting on the WM to initialize
Copyright (c) 2019 rehashedsalt@cock.li
Licensed under the MIT License
https://gitlab.com/rehashedsalt/firestarter
EOF
}
step_check() {
if [ -z "$_dryrun" ] && [ -z "$_generate" ]; then
for pid in $(pgrep firestarter); do
# Skip invalid PIDs
! [ -d "/proc/$pid" ] && continue
# If it's not our session then who cares
[ "$_sessionid" != "$(< "/proc/$pid/sessionid")" ] && continue
if [ "$pid" != "$BASHPID" ]; then
err "Firestarter is already running: $pid" 40
fi
done
fi
if ! [ -d "$HOME" ] || ! [ -r "$HOME" ]; then
err "Inaccessible home directory: \"$HOME\"" 54
fi
if ! [ -d "$_configdir" ]; then
if ! mkdir -p "$_configdir" > /dev/null 2>&1; then
err "Failed to create configuration directory: \"$_configdir\"" 52
fi
fi
return 0
}
step_preexecute() { step_preexecute() {
# Special things that can't use simple configuration files # Special things that can't use simple configuration files
[ -n "$_optdryrun" ] && return 0 [ -n "$_dryrun" ] && return 0
[ -r "$HOME/.xsessionrc" ] && . "$HOME/.xsessionrc"
# Xsessionrc
[ -r "$HOME/.xsessionrc" ] && source "$HOME/.xsessionrc"
# Exports
export XDG_CURRENT_DESKTOP="${XDG_CURRENT_DESKTOP:-firestarter}" export XDG_CURRENT_DESKTOP="${XDG_CURRENT_DESKTOP:-firestarter}"
# dbus # dbus
if \ if \
[ -z "$DBUS_SESSION_BUS_ADDRESS" ] && \ [ -z "$DBUS_SESSION_BUS_ADDRESS" ] && \
[ -n "$XDG_RUNTIME_DIR" ] && \ [ -n "$XDG_RUNTIME_DIR" ] && \
[ "$XDG_RUNTIME_DIR" = "/run/user/$(id -u)" ] && \ [ "$XDG_RUNTIME_DIR" = "/run/user/$(id -u)" ] && \
[ -S "$XDG_RUNTIME_DIR/bus" ]; then [ -S "$XDG_RUNTIME_DIR/bus" ]; then
# We already have a bus started; use it # We already have a bus started, use it
export DBUS_SESSION_BUS_ADDRESS="unix:path=$XDG_RUNTIME_DIR/bus" export DBUS_SESSION_BUS_ADDRESS="unix:path=$XDG_RUNTIME_DIR/bus"
hasdbus=1 hasdbus=1
elif \ elif \
[ -z "$DBUS_SESSION_BUS_ADDRESS" ] && \ [ -z "$DBUS_SESSION_BUS_ADDRESS" ] && \
has dbus-launch; then has dbus-launch; then
# We have dbus but haven't started it yet # We have dbus but haven't started up a bus yet
eval "$(dbus-laucnh --exit-with-session --sh-syntax)" eval "$(dbus-launch --exit-with-session --sh-syntax)"
hasdbus=1 hasdbus=1
else else
warn "Did not start dbus; some applications may misbehave" log "Did not start dbus; some applications may misbehave"
fi fi
if [ -n "$hasdbus" ]; then if [ -n "$hasdbus" ]; then
has dbus-update-activation-environment && \ if has dbus-update-activation-environment; then
dbus-update-activation-environment --verbose --systemd --all >/dev/null 2>&1 dbus-update-activation-environment --verbose --systemd --all > /dev/null 2>&1
fi
fi fi
unset hasdbus unset hasdbus
# kcminit/Qt settings # kcminit/Qt settings
if has kcminit; then if has kcminit; then
log "Initializing KDE Control Module settings" log "Initializing KDE Control Module settings"
kcminit >/dev/null 2>&1 kcminit > /dev/null 2>&1
export XDG_CURRENT_DESKTOP="KDE" export XDG_CURRENT_DESKTOP="KDE"
elif has qt5ct; then elif has qt5ct; then
log "Initializing qt5ct" log "Integrating qt5ct"
if [ -z "$QT_QPA_PLATFORMTHEME" ]; then if [ -z "$QT_QPA_PLATFORMTHEME" ]; then
export QT_QPA_PLATFORMTHEME="qt5ct" export QT_QPA_PLATFORMTHEME="qt5ct"
log "Exporting QT_QPA_PLATFORMTHEME as \"$QT_QPA_PLATFORMTHEME\"" 2 log "Exporting QT_QPA_PLATFORMTHEME as \"$QT_QPA_PLATFORMTHEME\""
else else
log "Using existing theme setting \"$QT_QPA_PLATFORMTHEME\"" 2 log "Using existing theme setting \"$QT_QPA_PLATFORMTHEME\""
fi fi
if [ -z "$QT_AUTO_SCREEN_SCALE_FACTOR" ]; then if [ -z "$QT_AUTO_SCREEN_SCALE_FACTOR" ]; then
export QT_AUTO_SCREEN_SCALE_FACTOR="0" export QT_AUTO_SCREEN_SCALE_FACTOR="0"
log "Exporting QT_AUTO_SCREEN_SCALE_FACTOR as \"$QT_AUTO_SCREEN_SCALE_FACTOR\"" 2 log "Exporting QT_AUTO_SCREEN_SCALE_FACTOR as $QT_AUTO_SCREEN_SCALE_FACTOR"
else else
log "Using existing scale factor \"$QT_AUTO_SCREEN_SCALE_FACTOR\"" 2 log "Using existing scale setting \"$QT_AUTO_SCREEN_SCALE_FACTOR\""
fi fi
fi fi
# xhost # xhost
if has xhost; then if has xhost; then
if xhost +si:localuser:"$(id -un)" >/dev/null 2>&1; then if xhost +si:localuser:"$(id -un)" > /dev/null 2>&1; then
log "Session open to other sessions by this user" log "Session can be accessed in other sessions by this user"
else else
warn "Failed to open session via xhost" log "Failed to open session up via xhost"
fi fi
fi fi
# xresources # xresources
if [ -n "$DISPLAY" ] && has xrdb && [ -r "$HOME/.Xresources" ]; then if [ -n "$DISPLAY" ] && has xrdb && [ -r "$HOME/.Xresources" ]; then
if xrdb "$HOME/.Xresources" >/dev/null 2>&1; then if xrdb "$HOME/.Xresources" > /dev/null 2>&1; then
log "Loaded in .Xresources" log "Loaded in .Xresources"
else else
warn "Failed to load .Xresources" log "Failed to load .Xresources"
fi fi
fi fi
# xset # xset
if has xset; then if has xset; then
log "Disabling bell" log "Disabling bell"
@ -410,81 +453,84 @@ step_preexecute() {
fi fi
} }
step_execute() { step_execute() {
# Parse out our defaults lists and execute their targets # Ensure we can log if we have to
if ! [ -d "$_optlogdir" ]; then if [ -n "$FS_NOLOG" ]; then
if ! mkdir -p "$_optlogdir" >/dev/null 2>&1; then log "No logs will be created per FS_NOLOG"
error "Failed to create log directory: \"$_optlogdir\"" 53 elif ! [ -d "$_logdir" ]; then
if ! mkdir -p "$_logdir" > /dev/null 2>&1; then
err "Failed to create log directory: \"$_logdir\"" 53
fi fi
fi fi
for file in "$_optconfigdir"/*; do # Parse configs
for file in "$_configdir"/*; do
if ! [ -e "$file" ]; then if ! [ -e "$file" ]; then
log "No configuration files found; generating defaults" log "No configuration files found; generating defaults"
genconfigs step_generate
step_execute step_execute
return break
fi fi
# Skip our logs directory
[ "$_optlogdir" == "$file" ] && continue
local filename="$(basename -- "$file")" local filename="$(basename -- "$file")"
local logfile="$_optlogdir/$filename.log" local logfile="$_logdir/$filename"
[ -n "$FS_NOLOG" ] && logfile="/dev/null"
if gettarget "$file"; then if gettarget "$file"; then
# It's a defaults file with a selected target # It's a defaults file with a selected target
target="$_return" target="$_return"
log "Found target for $filename: \"$target\"" log "Found target for \"$filename\": \"$target\""
[ -n "$_optdryrun" ] && continue if [ -z "$_dryrun" ]; then
if [ -f "$logfile" ]; then if [ -f "$logfile" ]; then
[ -f "$logfile.old" ] && rm "$logfile.old" [ -f "$logfile.old" ] && rm "$logfile.old"
mv "$logfile" "$logfile.old" mv "$logfile" "$logfile.old"
fi
bash -c "$target" > "$logfile" 2>&1 &
fi fi
bash -c "$target" > "$logfile" 2>&1 &
elif [ $? = 50 ] && [ -x "$file" ]; then elif [ $? = 50 ] && [ -x "$file" ]; then
# It's a shell script or executable symlink # It's a shell script or something
log "Executing file: \"$filename\"" log "Executing file straight out: \"$filename\""
[ -n "$_optdryrun" ] && continue if [ -z "$_dryrun" ]; then
"$file" > "$logfile" 2>&1 & "$file" > "$logfile" 2>&1 &
fi
else else
warn "Could not execute file: \"$filename\"" err "Could not execute file: \"$filename\""
fi fi
done done
} }
step_postexecute() { step_postexecute() {
# Wait for the WM to initialize, if one was found and we have the tools # Wait for the WM to initialize, if one was found and we have the tools
if [ -z "$FS_NOWAITWM" ] && gettarget "$_configdir/wm" && has xprop grep; then if [ -z "$FS_NOWAITWM" ] && gettarget "$_configdir/wm" && has xprop && has grep; then
log "Waiting for WM to initialize: \"$_return\"" log "Waiting for WM to initialize: \"$_return\""
for (( i=0; i<10; i++ )); do for (( i=0; i<10; i++ )); do
line="$(xprop -root | grep ^_NET_WM_NAME | grep -o '"\S*"$')" line="$(xprop -root | grep ^_NET_WM_NAME | grep -o '"\S*"$')"
if [ -n "$line" ]; then if [ -n "$line" ]; then
log "WM has initialized, _NET_WM_NAME atom reads: $line" log "WM has intiailized, _NET_WM_NAME atom reads: $line"
break break
fi fi
read -t 1 -u 1023 read -t 1 -u 1023
done done
fi fi
# Dumb polybar workaround # Dumb Polybar workaround
killall polybar -SIGUSR1 killall polybar -SIGUSR1
# Execute a user rc if it exists # Execute a user script if it exists
local firestarterrc="$HOME/.firestarterrc" if [ -r "$_firestarterrc" ] && [ -z "$_dryrun" ]; then
if [ -r "$firestarterrc" ] && [ -z "$dryrun" ]; then log "Executing .firestarterrc"
log "Executing rc script: $firestarterrc" "$_firestarterrc"
"$firestarterrc"
fi fi
# Start XDG autostarters, if they exist # Start XDG autostarters, if they exist
if [ -z "$_optdryrun" ]; then if [ -z "$_dryrun" ]; then
if has dex; then if has dex; then
dex -a >/dev/null 2>&1 dex -a > /dev/null 2>&1
elif has fbautostart; then elif has fbautostart; then
fbautostart > /dev/null 2>&1 fbautostart > /dev/null 2>&1
elif has xdg-autostart; then elif has xdg-autostart; then
xdg-autostart ${XDG_CURRENT_DESKTOP:-firestarter} xdg-autostart ${XDG_CURRENT_DESKTOP:-firestarter}
else else
warn "Could not find an XDG autostarter" err "Could not find an XDG autostarter"
fi fi
fi fi
} }
step_wait() { step_wait() {
[ -n "$_optdryrun" ] && exit 0 [ -n "$_dryrun" ] && exit 0
trap step_logout EXIT trap step_logout EXIT
if [ -n "$FS_DIEONWM" ] && gettarget "$_configdir/wm" && has readlink "$_return"; then if [ -n "$FS_DIEONWM" ] && gettarget "$_configdir/wm" && has readlink && has "$_return"; then
target="$(command -v "$_return")" target="$(command -v "$_return")"
for job in $(jobs -p); do for job in $(jobs -p); do
if [ "$target" = "$(readlink /proc/$job/exe)" ]; then if [ "$target" = "$(readlink /proc/$job/exe)" ]; then
@ -493,7 +539,7 @@ step_wait() {
exit 0 exit 0
fi fi
done done
warn "Could not find WM: \"$target\"" err "Could not find WM: \"$target\""
fi fi
log "Waiting for programs to exit" log "Waiting for programs to exit"
wait wait
@ -507,108 +553,45 @@ step_logout() {
loginctl terminate-session "$_sessionid" loginctl terminate-session "$_sessionid"
fi fi
else else
# Otherwise just brute it out # Otherwise just brute it
kill $(jobs -p) kill $(jobs -p)
fi fi
return 0 return 0
} }
printhelp() {
cat << EOF
Usage: $_name [OPTION]...
-d Perform a dry run; print what programs would have been
executed instead of doing so
-g Regenerate default configs. This will clobber
-h Print this help text
-v Print more status messages. Stacks
Environment Variables:
FS_DIEONWM If nonempty, end the session when the WM dies.
FS_NOWAITWM If nonempty, skip waiting for the WM to initialize
Copyright (c) 2019 rehashedsalt@cock.li
Licensed under the MIT license
EOF
}
# Main # Main
main() { main() {
# Parse out arguments while getopts ":dgh" opt; do
while [ -n "$1" ]; do case $opt in
# Parse out flags d)
while getopts ":dghv" opt; do _dryrun=1
case $opt in ;;
d) g)
_optdryrun=1 _generate=1
;; ;;
g) h)
_optpregen=1 step_printhelp
;; exit $?
h) ;;
_opthelp=1 *)
;; err "Unrecognized argument: \"$OPTARG\"" 50
v) ;;
_optverbose+=1 :)
;; err "Invalid option: \"$OPTARG\"" 51
:) ;;
error "Option requires argument: -$OPTARG" 2 esac
;;
*)
error "Invalid option: -$OPTARG" 2
;;
esac
done
# Store arguments
shift $((OPTIND - 1))
if [ -n "$1" ]; then
_args+=("$1")
shift
fi
unset OPTIND
done done
# Early hook for help step_check
[ -n "$_opthelp" ] && printhelp && exit 0 if [ -n "$_generate" ]; then
# Early hook for generating configs step_generate
[ -n "$_optpregen" ] && genconfigs && exit $? else
# Ensure our running environment is sane and that we're not about to nest [ -n "$_dryrun" ] && log "Performing a dry run"
if [ -z "$_optdryrun" ] && [ -z "$_optpregen" ]; then step_preexecute
for pid in $(pgrep firestarter); do step_execute
# Skip invalid PIDs step_postexecute
! [ -d "$/proc/$pid" ] && continue step_wait
# If it's not our session then who cares
[ "$_sessionid" != "$(< "/proc/$pid/sessionid")" ] && continue
# If it's us then who cares
[ "$pid" == "$BASHPID" ] && continue
# We care
error "Firestarter is already running: $pid" 40
done
fi fi
if ! [ -d "$HOME" ] || ! [ -r "$HOME" ]; then return 0
error "Home directory not found or inaccessable: \"$HOME\"" 54
fi
if ! [ -d "$_optconfigdir" ]; then
if [ -f "$_optconfigdir" ]; then
error "Config directory is a file, should be directory: \"$_optconfigdir\"" 52
fi
if ! mkdir -p "$_optconfigdir" > /dev/null 2>&1; then
error "Failed to find or create config directory: \"$_optconfigdir\"" 52
fi
fi
# Validate core program dependencies
log "Validating dependencies" 2
if ! has basename; then
error "Failed to find program: $_return" 1
fi
# Do the do
[ -n "$_optdryrun" ] && log "Performing a dry run"
step_preexecute
step_execute
step_wait
step_logout
exit 0
} }
main "$@" main "$@"