source: trunk/debathena/config/cluster-login-config/debian/getty.debathena @ 24761

Revision 24761, 4.4 KB checked in by broder, 14 years ago (diff)
In cluster-login-config: * Make getty.debathena more robust by looking harder for the kiosk session or any X session, and displaying a message to the user if that fails.
Line 
1#!/usr/bin/python
2"""getty replacement for Debathena
3
4Debathena clusters only allow logins through X, in order to avoid a
5user logging into a tty, then switching away from that tty, and
6walking away from their session.
7
8This replacement for getty clears the screen, and offers to switch the
9user back to their session if they press any key.
10"""
11
12
13import curses
14import getopt
15import os
16import pwd
17import subprocess
18import sys
19import time
20
21import dbus
22
23
24CK_NAME = 'org.freedesktop.ConsoleKit'
25CK_MANAGER_PATH = '/org/freedesktop/ConsoleKit/Manager'
26CK_MANAGER_IFACE = 'org.freedesktop.ConsoleKit.Manager'
27CK_SESSION_IFACE = 'org.freedesktop.ConsoleKit.Session'
28KIOSK_USER = None
29
30
31def find_tty(args):
32    """Find the tty in a set of getty arguments.
33
34    Given the command line arguments one might pass to getty, find and
35    return the argument that is the tty to use.
36
37    find_tty uses the getopt option specifier and tty identifying
38    logic from util-linux 2.13.1.1.
39
40    Note that all other arguments will be ignored, making this getty
41    useless for gettys that are not on normal ttys.
42    """
43    opts, args = getopt.getopt(args, '8I:LH:f:hil:mt:wUn')
44
45    # Accept both "tty baudrate" and "baudrate tty"
46    if '0' <= args[0][0] <= '9':
47        return args[1]
48    else:
49        return args[0]
50
51
52def activate_session():
53    """Seek out and activate what should be the current session.
54
55    Using ConsoleKit, activate_session first looks to see if there is
56    an active kiosk-mode browsing session, and if so, switches to
57    that. Otherwise, it picks the first local session it can find and
58    assumes that's the user's session.
59
60    With the exception of the kiosk-mode session, it should be
61    impossible to have more than one session running simultaneously,
62    so blindly using the first session shouldn't be a problem.
63    """
64    global KIOSK_USER
65    if KIOSK_USER is None:
66        try:
67            KIOSK_USER = pwd.getpwnam('kiosk@mit').pw_uid
68        except KeyError:
69            # There is no kiosk user
70            KIOSK_USER = False
71
72    bus = dbus.SystemBus()
73    manager = dbus.Interface(bus.get_object(CK_NAME, CK_MANAGER_PATH),
74                             CK_MANAGER_IFACE)
75
76    session = None
77    if KIOSK_USER:
78        # We'll prefer kiosk sessions if they exist
79        sessions = manager.GetSessionsForUnixUser(KIOSK_USER)
80    if not sessions:
81        # But if not, we'll take any graphical session that identifies
82        # as local
83        sessions = manager.GetSessions()
84
85    for s in sessions:
86        session = dbus.Interface(bus.get_object(CK_NAME, s),
87                                 CK_SESSION_IFACE)
88        if session.IsLocal() and session.GetX11Display():
89               break
90        else:
91            session = None
92
93    if session:
94        session.Activate()
95    else:
96        vt = None
97
98        # Look for a kiosk-mode session that we missed
99        try:
100            vt = open('/var/run/athena-kiosk-vt').read().strip()
101        except IOError, e:
102            pass
103
104        # Look for any X session
105        try:
106            p = subprocess.Popen(['pgrep', '-x', 'Xorg'],
107                                 stdout=subprocess.PIPE)
108            pid, _ = p.communicate()
109            pid = pid.splitlines()[0]
110
111            if pid:
112                p = subprocess.Popen(['ps', '-otty=', pid],
113                                     stdout=subprocess.PIPE)
114                tty, _ = p.communicate()
115                tty = tty.splitlines()[0]
116
117                if tty.startswith('tty'):
118                    vt = tty[len('tty'):]
119
120        if vt:
121            subprocess.call(['chvt', vt])
122
123
124def main():
125    tty_name = find_tty(sys.argv[1:])
126    tty = open(os.path.join('/dev', tty_name), 'a+')
127    # We want to set TERM for a tty, not for whatever TERM was set to
128    # on getty's controlling terminal.
129    curses.setupterm("linux", tty.fileno())
130
131    CLEAR = curses.tigetstr('clear')
132
133    while True:
134        tty.write(CLEAR)
135        tty.write('Please press Enter to return to your session\n')
136        tty.readline()
137
138        activate_session()
139
140        tty.write("If you are seeing this message, it was not possible to return you to\n")
141        tty.write("your session automatically, Try pressing Ctrl-Alt-F7, Ctrl-Alt-F8 or\n")
142        tty.write("Ctrl-Alt-F9. If that does not work, reboot the computer by pressing\n")
143        tty.write("Ctrl-Alt-Delete.\n")
144
145        time.sleep(10)
146
147
148if __name__ == '__main__':
149    main()
Note: See TracBrowser for help on using the repository browser.