From 4b0e9825ebc50525550c9d499244e680d06b0a94 Mon Sep 17 00:00:00 2001 From: "Casper Ti. Vector" Date: Sat, 7 Apr 2012 19:37:34 +0800 Subject: [PATCH] Major restructuring. classify menu items into console programs and X programs. Console programs are directly `exec'ed. X programs are run with cdm-xlaunch(1). $allowconsole, $usexinit, shutdownmenu(), etc., are removed. --- install | 1 + src/cdm | 242 ++++++++++++++++------------------------- src/cdmrc | 99 +++++++---------- src/profile | 7 ++ src/xinitrc | 10 -- src/zzz-cdm-profile.sh | 9 -- 6 files changed, 141 insertions(+), 227 deletions(-) create mode 100644 src/profile delete mode 100644 src/xinitrc delete mode 100755 src/zzz-cdm-profile.sh diff --git a/install b/install index 42eb7a7..eba61fb 100755 --- a/install +++ b/install @@ -12,3 +12,4 @@ else install -Dm755 zzz-cdm-profile.sh /etc/profile.d/zzz-cdm-profile.sh cp -Rf themes /usr/share/cdm/ fi + diff --git a/src/cdm b/src/cdm index 0964c17..8c972c2 100755 --- a/src/cdm +++ b/src/cdm @@ -27,18 +27,13 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. -name="Console Display Manager" -ver="0.5.3" +name=$(basename "$0") +longname='Console Display Manager' +ver='0.5.3' trap '' SIGINT SIGTSTP source /etc/init.d/functions.sh -dialogrc=${dialogrc:-} -userclientrc=$HOME/.xinitrc -sysclientrc=/etc/X11/xinit/xinitrc -# userserverrc=$HOME/.xserverrc -# sysserverrc=/etc/X11/xinit/xserverrc - # Source cdm configurations. if [[ -n "$1" ]]; then @@ -49,159 +44,108 @@ elif [[ -f /etc/cdmrc ]]; then source /etc/cdmrc fi -# Offer all available sessions in /etc/X11/Sessions -# if wmbinlist if not explicitly set in cdmrc +# Default options. -if [[ "${#wmbinlist[@]}" -eq 0 ]]; then - wmbinlist=($(ls /etc/X11/Sessions)) - wmdisplist=($(echo ${wmbinlist[@]^})) +dialogrc=${dialogrc:-} +countfrom=${countfrom:-0} +binlist=${binlist:-()} +namelist=${namelist:-()} +xtty=${xtty:-7} +locktty=${locktty:-no} +display=${display:-0} +consolekit=${consolekit:-yes} +cktimeout=${cktimeout:-30} +serverargs=${serverargs:-'-nolisten tcp'} + +# Exit functions. + +exitnormal() { exit 0; } +exiterror() { sleep 1; exit 1; } + +# Offer all available sessions in /etc/X11/Sessions, +# if binlist if not explicitly set in cdmrc. + +if [[ "${#binlist[@]}" == 0 ]]; then + binlist=($(ls /etc/X11/Sessions)) + flaglist=($(sed 's/[[:digit:]]\+/X/g' <<< ${!flaglist[*]})) + namelist=(${binlist[@]^}) fi -mainmenu() { - # Generate main menu - count=0 - menu=$( - while [[ ${count} -lt ${#wmdisplist[@]} ]]; do - echo -ne "$((count+countfrom)) ${wmdisplist[${count}]} " - let count=count+1 - done +# Generate the main menu. +menu=() +for ((count=0; count<${#namelist[@]}; count++)); do + menu=("${menu[@]}" "$((count+countfrom))" "${namelist[${count}]}") +done + +# Override dialog display if only one option is available. +if [[ "$count" == 1 ]]; then + binindex=0 +else + # Display selection dialog. + binindex=$( + DIALOGRC="$dialogrc" dialog --colors --stdout \ + --backtitle "${longname} v${ver}" \ + --ok-label ' Select ' --cancel-label ' Exit ' \ + --menu 'Select session' 0 0 0 "${menu[@]}" ) - - # Check if console access is allowed - if $(yesno allowconsole); then - if ! $(yesno allowshutdown); then - let halt=99 - fi - let console=${#wmdisplist[@]}+countfrom - menu="${menu} ${console} Console " - fi - - # Check if shutdown access is allowed - if $(yesno allowshutdown); then - if ! $(yesno allowconsole); then - let halt=${#wmdisplist[@]} - else - let halt=${#wmdisplist[@]}+1 - fi - let halt=halt+countfrom - menu="${menu} ${halt} Shutdown " + if [[ $? != 0 ]]; then + clear + exitnormal fi +fi - # Override dialog display if only one option is available - if ! $(yesno allowconsole) && ! $(yesno allowshutdown) && [[ ${#wmdisplist[@]} == 1 ]]; then - wm=$countfrom - else - # Display selection dialog - wm=$( - DIALOGRC="$dialogrc" dialog --colors \ - --backtitle "${name} v${ver}" --stdout \ - --ok-label " Select " --cancel-label " Logout " \ - --menu "Select Window Manager" 0 0 0 ${menu} - ) - if [[ $? != 0 ]]; then - clear - exit 0 - fi - fi +# Run $bin according to its flag. +let binindex-=countfrom +bin="${binlist[${binindex}]}" +case ${flaglist[$binindex]} in + # *C*onsole programs. + [Cc]) + clear + # If $bin is a login shell, it might `exec' cdm again, causing an endless + # loop. To solve this problem, export $CDM_SPAWN when `exec'ing $bin and + # only let the shell automatically `exec' cdm when $CDM_SPAWN is not set. + # See also the example shell profile file shipped with this cdm package. + CDM_SPAWN=$$ exec $bin + ;; + + # *X* programs. + [Xx]) + clear - # Set wm_bin - clear - if [[ ${wm} -eq ${console} ]]; then - exit 2 #2 signals to the profile file to not exit. - elif [[ ${wm} -eq ${halt} ]]; then - shutdownmenu - else - let wm=wm-countfrom - wm_bin="${wmbinlist[${wm}]}" - xstart - fi -} - -shutdownmenu() { - count=$countfrom - haltmenu=$( - for opt in Shutdown Reboot Suspend Hibernate; do - # Check if suspend/hibernate is enabled - if ([[ $opt != Suspend ]] && [[ $opt != Hibernate ]]) || - ([[ $opt == Suspend ]] && $(yesno allowsuspend)) || - ([[ $opt == Hibernate ]] && $(yesno allowhibernate)); then - echo -ne "$count $opt " - let count=count+1 + # If X is already running and locktty=yes, activate it, + # otherwise increment. + if $(yesno locktty); then + # Activate existing X session. + if xdpyinfo -display ":$display.0" &> /dev/null; then + chvt "$((display+xtty))" + exitnormal fi - done - ) - - # Display shutdown dialog - haltopt=$( - DIALOGRC="$dialogrc" dialog --colors \ - --backtitle "${name} v${ver}" --stdout \ - --ok-label " Select " --cancel-label " Cancel " \ - --menu "Shutdown" 0 0 0 ${haltmenu} - ) - - if [[ $? == 0 ]]; then - clear - if [[ ${haltopt} -eq $countfrom ]]; then - ${shutdowncommand} - elif [[ ${haltopt} -eq $((countfrom+1)) ]]; then - ${rebootcommand} - elif [[ ${haltopt} -eq $((countfrom+2)) ]] && $(yesno allowsuspend); then - ${suspendcommand} else - ${hibernatecommand} - fi - else - mainmenu - fi -} - -xstart() { - # If X is already running and locktty=yes, activate it, - # otherwise, increment. - if $(yesno locktty); then - # Verify display exists - if [[ -n "${display//[0-9]/}" ]]; then + # Get the first empty display. display=0 + while [[ "$display" < 7 ]]; do + if dpyinfo=$(xdpyinfo -display ":$display.0" 2>&1 1>/dev/null) || + # Display is in use by another user. + [[ "$dpyinfo" == 'No protocol specified'* ]] + then + let display+=1 + else + break + fi + done fi - # Activate existing X session - if xdpyinfo -display :${display}.0 &> /dev/null; then - let tty=display+xtty - chvt ${tty} - exit 0 - fi - else - # Get the first empty display - display=0 - while [[ ${display} -lt 7 ]]; do - if dpyinfo=$(xdpyinfo -display :${display}.0 2>&1 1>/dev/null); then - let display=display+1 - elif [[ $dpyinfo = No\ protocol\ specified* ]]; then - # Display is in use by another user - let display=display+1 - else - break - fi - done - fi + serverargs=":${display} $serverargs vt$((xtty+display))" - # Start X - if $(yesno usexinit); then - if [[ -f $userclientrc ]]; then - wm_bin="$userclientrc $wm_bin" - elif [[ -f $sysclientrc ]]; then - wm_bin="$sysclientrc $wm_bin" + $(yesno consolekit) && launchflags="-c -t $cktimeout" + if ! eval cdm-xlaunch $launchflags -- $bin -- $serverargs; then + ewarn "$self: \`cdm-xlaunch' exited unsuccessfully." + exiterror fi - else - wm_bin="/etc/X11/cdm/xinitrc $wm_bin" - fi - - serverargs=":${display} ${serverargs} vt$((xtty+display))" + ;; - $(yesno consolekit) && launchflags="-c -t $cktimeout" - if ! eval cdm-xlaunch $launchflags -- $bin -- $serverargs; then - ewarn "\`cdm-xlaunch' exited unsuccessfully." - exit 1 - fi -} -mainmenu + *) + eerror "$self: unknown flag: \`${flaglist[$binindex]}'." + exiterror + ;; +esac diff --git a/src/cdmrc b/src/cdmrc index 07a8f0e..4d4650a 100644 --- a/src/cdmrc +++ b/src/cdmrc @@ -1,70 +1,51 @@ -############################ -### GLOBAL CONFIGURATION ### -############################ - -# Set CDM theme and dialog options -dialogrc=/usr/share/cdm/themes/cdm -countfrom=1 - -# List all WM binary names -# If this is not set all sessions in -# /etc/X11/Sessions are offered as choices. -wmbinlist=() - -# List all WM display names -wmdisplist=() - -# Allow console login? -allowconsole=yes - -# Allow shutdown? -# Note that this option requires sudo -# to be installed and properly configured. -allowshutdown=no -shutdowncommand='sudo shutdown -h now' -rebootcommand='sudo shutdown -r now' - -# Allow suspend? -# Note that this option requires pm-utils -# to be installed and properly configured. -allowsuspend=no -suspendcommand='sudo pm-suspend' -allowhibernate=no -hibernatecommand='sudo pm-hibernate' - -############################ -### SYSTEM CONFIGURATION ### -############################ - -# Set default display +#!/bin/bash +# +# Example config file for cdm(1). +# Values set here is the default as in cdm(1). + +# Style for the cdm dialog, which is printed with dialog(1). +# Default to unset, causing dialog(1) to use the system wide default. +# See /usr/share/cdm/themes for some nice choices. +dialogrc= + +# Index of the first item in the menu. +countfrom=0 + +# List of programs, commands with whitespaces should be quoted or escaped. +# If unset, all sessions in /etc/X11/Sessions are offered as choices. +# +# (An example:) +# binlist=("~/.xsession" "/bin/bash --login" "/usr/bin/fbterm") + +# List all program display names, one-by-one matched with $binlist. +# Names with whitespaces should be quoted or escaped. +# +# (Continued example:) +# namelist=(XSession Console FBTerm) + +# Type of the programs, one-by-one matched with $binlist. +# `C' for *C*onsole programs, which would be `exec'ed. +# `X' for *X* programs, which would be run with cdm-xlaunch(1). +# +# (Continued example:) +# flaglist=(X C C) + +# Set default display. display=0 # Where should first X tty be spawned? xtty=7 -# Restrict tty? (By default, cdm increments X tty, this setting -# allows administrators to lock users into one specific tty by -# setting the display=N option on a per-user basis.) -locktty=no +# Should cdm(1) stick to the specified display? +locktty=yes -# The use of consolekit has recently become manditory with hal. However, -# some users might prefer not using either one. If you don't want to -# use consolekit, set the following variable to "no". +# Use consolekit for X session? consolekit=yes -# Timeout for waiting for X session to register with consoleKit -cktimeout=30 - -# Additional arguments to pass to X server -# When usexinit=yes, we use ~/.xinitrc when it exists or /etc/X11/xinit/xinitrc -# when it doesn't. These are passed the chosen window manager as $1; note that -# the stock /etc/X11/xinit/xinitrc ignores this and always starts twm and three -# xterms. Your custom xinitrc should start the window manager supplied as $1 -# instead. There is a sample xinitrc included at /usr/share/cdm/xinitrc.skel. -# If usexinit=no, then we instead call the chosen window manager directly. -usexinit=no +# Timeout for waiting for X session to register with consolekit. +cktimeout=5 # Additional arguments to pass to X server; it will be called as: -# exec /usr/bin/X :$display $serverargs vt$((xtty+display)) -serverargs="-nolisten tcp" +# exec /usr/bin/X :$display $serverargs vt$((xtty+display)) +serverargs='-nolisten tcp' diff --git a/src/profile b/src/profile new file mode 100644 index 0000000..959fd64 --- /dev/null +++ b/src/profile @@ -0,0 +1,7 @@ +#!/bin/sh - + +if [[ "$(tty)" == /dev/tty1 ]]; then + [[ -n "$CDM_SPAWN" ]] && return + [[ -z "$DISPLAY`pgrep xinit`$SSH_TTY" ]] && exec cdm +fi + diff --git a/src/xinitrc b/src/xinitrc deleted file mode 100644 index a59fa0f..0000000 --- a/src/xinitrc +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -# -# If option usexinit is set then this file is not used. Instead ~/.xinitrc -# if it exists or else /etc/X11/xinit/xinitrc is used in it's place. - - -# Put your configuration above this line. - -wm_bin="$1" -exec ${wm_bin} diff --git a/src/zzz-cdm-profile.sh b/src/zzz-cdm-profile.sh deleted file mode 100755 index b73e21f..0000000 --- a/src/zzz-cdm-profile.sh +++ /dev/null @@ -1,9 +0,0 @@ -if [[ -z "$DISPLAY" && -z "$SSH_TTY" && $(tty) = /dev/tty* ]]; then - # Drop root to console - if ! [[ $EUID -eq 0 ]]; then - cdm - if (( $? == 0 )); then - exit 0 - fi - fi -fi