1"""Utilities to get a password and/or the current user name.
2
3getpass(prompt) - prompt for a password, with echo turned off
4getuser() - get the user name from the environment or password database
5
6On Windows, the msvcrt module will be used.
7On the Mac EasyDialogs.AskPassword is used, if available.
8
9"""
10
11# From CPython 2.5.1 with a fix to _raw_input (see
12# http://bugs.python.org/issue1703 )
13
14# Authors: Piers Lauder (original)
15#          Guido van Rossum (Windows support and cleanup)
16
17import os
18import sys
19
20__all__ = ["getpass","getuser"]
21
22def jython_getpass(prompt='Password: ', stream=None):
23    """Prompt for a password, with echo turned off.
24    The prompt is written on stream, by default stdout.
25
26    Restore terminal settings at end.
27    """
28    if stream is None:
29        stream = sys.stdout
30
31    try:
32        terminal = sys._jy_interpreter.reader.terminal
33    except:
34        return default_getpass(prompt)
35
36    echoed = terminal.getEcho()
37    terminal.disableEcho()
38    try:
39        passwd = _raw_input(prompt, stream)
40    finally:
41        if echoed:
42           terminal.enableEcho()
43
44    stream.write('\n')
45    return passwd
46
47
48def unix_getpass(prompt='Password: ', stream=None):
49    """Prompt for a password, with echo turned off.
50    The prompt is written on stream, by default stdout.
51
52    Restore terminal settings at end.
53    """
54    if stream is None:
55        stream = sys.stdout
56
57    try:
58        fd = sys.stdin.fileno()
59    except:
60        return default_getpass(prompt)
61
62    old = termios.tcgetattr(fd)     # a copy to save
63    new = old[:]
64
65    new[3] = new[3] & ~termios.ECHO # 3 == 'lflags'
66    try:
67        termios.tcsetattr(fd, termios.TCSADRAIN, new)
68        passwd = _raw_input(prompt, stream)
69    finally:
70        termios.tcsetattr(fd, termios.TCSADRAIN, old)
71
72    stream.write('\n')
73    return passwd
74
75
76def win_getpass(prompt='Password: ', stream=None):
77    """Prompt for password with echo off, using Windows getch()."""
78    if sys.stdin is not sys.__stdin__:
79        return default_getpass(prompt, stream)
80    import msvcrt
81    for c in prompt:
82        msvcrt.putch(c)
83    pw = ""
84    while 1:
85        c = msvcrt.getch()
86        if c == '\r' or c == '\n':
87            break
88        if c == '\003':
89            raise KeyboardInterrupt
90        if c == '\b':
91            pw = pw[:-1]
92        else:
93            pw = pw + c
94    msvcrt.putch('\r')
95    msvcrt.putch('\n')
96    return pw
97
98
99def default_getpass(prompt='Password: ', stream=None):
100    print >>sys.stderr, "Warning: Problem with getpass. Passwords may be echoed."
101    return _raw_input(prompt, stream)
102
103
104def _raw_input(prompt="", stream=None):
105    # A raw_input() replacement that doesn't save the string in the
106    # GNU readline history.
107    if stream is None:
108        stream = sys.stdout
109    prompt = str(prompt)
110    if prompt:
111        stream.write(prompt)
112        stream.flush()
113    line = sys.stdin.readline()
114    if not line:
115        raise EOFError
116    if line[-1] == '\n':
117        line = line[:-1]
118    return line
119
120
121def getuser():
122    """Get the username from the environment or password database.
123
124    First try various environment variables, then the password
125    database.  This works on Windows as long as USERNAME is set.
126
127    """
128
129    for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):
130        user = os.environ.get(name)
131        if user:
132            return user
133
134    # If this fails, the exception will "explain" why
135    import pwd
136    return pwd.getpwuid(os.getuid())[0]
137
138# Bind the name getpass to the appropriate function
139try:
140    import termios
141    # it's possible there is an incompatible termios from the
142    # McMillan Installer, make sure we have a UNIX-compatible termios
143    termios.tcgetattr, termios.tcsetattr
144except (ImportError, AttributeError):
145    try:
146        import msvcrt
147    except ImportError:
148        try:
149            from EasyDialogs import AskPassword
150        except ImportError:
151            if os.name == 'java':
152                getpass = jython_getpass
153            else:
154                getpass = default_getpass
155        else:
156            getpass = AskPassword
157    else:
158        getpass = win_getpass
159else:
160    getpass = unix_getpass
161