forked from evertiro/cdm
/
cdm
executable file
·251 lines (226 loc) · 6.56 KB
/
cdm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
#!/bin/bash
#
# CDM: The Console Display Manager
#
# Copyright (C) 2009-2011, Daniel J Griffiths <ghost1227@archlinux.us>
# Thanks to:
#
# Andrwe beta-testing and submitting the fix for the all
# important X incrementation function
# brisbin33 code cleanup
# tigrmesh finding a critical issue with the gnome-session handler
# Profjim several incredibly useful patches
# lambchops468 consolekit and hibernation patches
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
name="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 configuration
if [[ -f /etc/X11/cdm/cdmrc ]]; then
source /etc/X11/cdm/cdmrc
count=0
while [[ ${count} -lt ${#userconfig[@]} ]]; do
if [[ "$USER" == "${userconfig[${count}]}" ]]; then
${userconfig[${count}]}
fi
let count=count+1
done
countfrom=${countfrom:-0}
cktimeout=${cktimeout:-30}
else
eerror "A valid cdm configuration was not found!"
ewarn "Logging out."
sleep 3
exit 1
fi
# Offer all available sessions in /etc/X11/Sessions
# if wmbinlist if not explicitly set in cdmrc
if [[ "${#wmbinlist[@]}" -eq 0 ]]; then
wmbinlist=($(ls /etc/X11/Sessions))
wmdisplist=($(echo ${wmbinlist[@]^}))
fi
# 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
display=0
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
mainmenu() {
# Generate main menu
count=0
menu=$(
while [[ ${count} -lt ${#wmdisplist[@]} ]]; do
echo -ne "$((count+countfrom)) ${wmdisplist[${count}]} "
let count=count+1
done
)
# 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 "
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
# 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
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() {
# Start X
if $(yesno usexinit); then
if [[ -f $userclientrc ]]; then
wm_bin="$userclientrc $wm_bin"
elif [[ -f $sysclientrc ]]; then
wm_bin="$sysclientrc $wm_bin"
fi
else
wm_bin="/etc/X11/cdm/xinitrc $wm_bin"
fi
serverargs=":${display} ${serverargs} vt$((xtty+display))"
if $(yesno consolekit); then #do first to avoid race conditions
ebegin "Waiting for ConsoleKit to register X session (timeout ${cktimeout}s)..."
sleep $cktimeout &
clockpid=$!
#have to store pid of dbus-monitor this way since dbus-monitor will run until killed.
fifo=$(mktemp --dry-run)
mkfifo --mode=700 $fifo
(dbus-monitor --system type=signal,interface=org.freedesktop.ConsoleKit.Seat,member=SessionAdded & echo $! > $fifo ) | \
sed -un 's|[[:space:]]*object path \"\(/[a-zA-Z0-9/]*\)\"|\1|p' | while read object; do
if dbus-send --system --print-reply --dest=org.freedesktop.ConsoleKit "$object" org.freedesktop.ConsoleKit.Session.GetX11Display | \
grep -qF "$display"; then break
fi
done &
read dbuspid < $fifo
rm -f $fifo
fi
if $(yesno loginshell); then
nohup bash --login -c "startx $wm_bin -- ${serverargs}" &> /dev/null &
else
nohup startx $wm_bin -- ${serverargs} &> /dev/null &
fi
if [[ -n $clockpid ]]; then
#if wait returns with a value >128, it was interrupted by the trap, so registration was sucessful.
if wait $clockpid; then
eend "Timed out, giving up.\nCheck to see if you are wrapping your session with ck-launch-session or increase the timeout."
kill $dbuspid
exit 1
else
eend 0
kill $dbuspid $clockpid
exit 0
fi
fi
exit 0
}
mainmenu