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.
RevLine 
[24668]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
[24678]17import subprocess
[24668]18import sys
[24761]19import time
[24668]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:
[24761]78        # We'll prefer kiosk sessions if they exist
[24668]79        sessions = manager.GetSessionsForUnixUser(KIOSK_USER)
[24761]80    if not sessions:
81        # But if not, we'll take any graphical session that identifies
82        # as local
[24668]83        sessions = manager.GetSessions()
[24761]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
[24668]90        else:
91            session = None
92
93    if session:
94        session.Activate()
[24678]95    else:
[24761]96        vt = None
[24668]97
[24761]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
[24668]103
[24761]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
[24668]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
[24761]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")
[24668]144
[24761]145        time.sleep(10)
146
147
[24668]148if __name__ == '__main__':
149    main()
Note: See TracBrowser for help on using the repository browser.