netrc.py 3.56 KB
Newer Older
1 2
"""An object-oriented interface to .netrc files."""

Tim Peters's avatar
Tim Peters committed
3
# Module and documentation by Eric S. Raymond, 21 Dec 1998
4

5
import os, shlex
6

7 8
__all__ = ["netrc"]

9 10 11 12
class netrc:
    def __init__(self, file=None):
        if not file:
            file = os.path.join(os.environ['HOME'], ".netrc")
13
        fp = open(file)
14 15 16
        self.hosts = {}
        self.macros = {}
        lexer = shlex.shlex(fp)
Tim Peters's avatar
Tim Peters committed
17
        # Allows @ in hostnames.  Not a big deal...
18
        lexer.wordchars = lexer.wordchars + '.-@'
19 20 21
        while 1:
            # Look for a machine, default, or macdef top-level keyword
            toplevel = tt = lexer.get_token()
22
            if not tt:
23 24 25 26 27
                break
            elif tt == 'machine':
                entryname = lexer.get_token()
            elif tt == 'default':
                entryname = 'default'
Tim Peters's avatar
Tim Peters committed
28
            elif tt == 'macdef':                # Just skip to end of macdefs
29 30 31 32 33 34 35 36 37 38 39 40
                entryname = lexer.get_token()
                self.macros[entryname] = []
                lexer.whitepace = ' \t'
                while 1:
                    line = lexer.instream.readline()
                    if not line or line == '\012' and tt == '\012':
                        lexer.whitepace = ' \t\r\n'
                        break
                    tt = line
                    self.macros[entryname].append(line)
            else:
                raise SyntaxError, "bad toplevel token %s, file %s, line %d" \
Tim Peters's avatar
Tim Peters committed
41
                                        % (tt, file, lexer.lineno)
42 43 44 45 46 47 48 49 50

            # We're looking at start of an entry for a named machine or default.
            if toplevel == 'machine':
                login = account = password = None
                self.hosts[entryname] = {}
            while 1:
                tt = lexer.get_token()
                if tt=='' or tt == 'machine' or tt == 'default' or tt == 'macdef':
                    if toplevel == 'macdef':
51
                        break
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
                    elif login and password:
                        self.hosts[entryname] = (login, account, password)
                        lexer.push_token(tt)
                        break
                    else:
                        raise SyntaxError, "malformed %s entry %s terminated by %s" % (toplevel, entryname, repr(tt))
                elif tt == 'login' or tt == 'user':
                    login = lexer.get_token()
                elif tt == 'account':
                    account = lexer.get_token()
                elif tt == 'password':
                    password = lexer.get_token()
                else:
                    raise SyntaxError, "bad follower token %s, file %s, line %d"%(tt,file,lexer.lineno)

    def authenticators(self, host):
68
        """Return a (user, account, password) tuple for given host."""
69 70 71 72 73 74 75 76
        if self.hosts.has_key(host):
            return self.hosts[host]
        elif self.hosts.has_key('default'):
            return self.hosts['default']
        else:
            return None

    def __repr__(self):
77
        """Dump the class data in the format of a .netrc file."""
78 79 80 81 82 83 84 85 86 87 88 89 90 91
        rep = ""
        for host in self.hosts.keys():
            attrs = self.hosts[host]
            rep = rep + "machine "+ host + "\n\tlogin " + repr(attrs[0]) + "\n"
            if attrs[1]:
                rep = rep + "account " + repr(attrs[1])
            rep = rep + "\tpassword " + repr(attrs[2]) + "\n"
        for macro in self.macros.keys():
            rep = rep + "macdef " + macro + "\n"
            for line in self.macros[macro]:
                rep = rep + line
            rep = rep + "\n"
        return rep

Tim Peters's avatar
Tim Peters committed
92
if __name__ == '__main__':
93
    print netrc()