]> git.lizzy.rs Git - plan9front.git/blob - sys/lib/python/netrc.py
dist/mkfile: run binds in subshell
[plan9front.git] / sys / lib / python / netrc.py
1 """An object-oriented interface to .netrc files."""
2
3 # Module and documentation by Eric S. Raymond, 21 Dec 1998
4
5 import os, shlex
6
7 __all__ = ["netrc", "NetrcParseError"]
8
9
10 class NetrcParseError(Exception):
11     """Exception raised on syntax errors in the .netrc file."""
12     def __init__(self, msg, filename=None, lineno=None):
13         self.filename = filename
14         self.lineno = lineno
15         self.msg = msg
16         Exception.__init__(self, msg)
17
18     def __str__(self):
19         return "%s (%s, line %s)" % (self.msg, self.filename, self.lineno)
20
21
22 class netrc:
23     def __init__(self, file=None):
24         if file is None:
25             try:
26                 file = os.path.join(os.environ['HOME'], ".netrc")
27             except KeyError:
28                 raise IOError("Could not find .netrc: $HOME is not set")
29         fp = open(file)
30         self.hosts = {}
31         self.macros = {}
32         lexer = shlex.shlex(fp)
33         lexer.wordchars += r"""!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"""
34         while 1:
35             # Look for a machine, default, or macdef top-level keyword
36             toplevel = tt = lexer.get_token()
37             if not tt:
38                 break
39             elif tt == 'machine':
40                 entryname = lexer.get_token()
41             elif tt == 'default':
42                 entryname = 'default'
43             elif tt == 'macdef':                # Just skip to end of macdefs
44                 entryname = lexer.get_token()
45                 self.macros[entryname] = []
46                 lexer.whitespace = ' \t'
47                 while 1:
48                     line = lexer.instream.readline()
49                     if not line or line == '\012':
50                         lexer.whitespace = ' \t\r\n'
51                         break
52                     self.macros[entryname].append(line)
53                 continue
54             else:
55                 raise NetrcParseError(
56                     "bad toplevel token %r" % tt, file, lexer.lineno)
57
58             # We're looking at start of an entry for a named machine or default.
59             login = ''
60             account = password = None
61             self.hosts[entryname] = {}
62             while 1:
63                 tt = lexer.get_token()
64                 if (tt=='' or tt == 'machine' or
65                     tt == 'default' or tt =='macdef'):
66                     if password:
67                         self.hosts[entryname] = (login, account, password)
68                         lexer.push_token(tt)
69                         break
70                     else:
71                         raise NetrcParseError(
72                             "malformed %s entry %s terminated by %s"
73                             % (toplevel, entryname, repr(tt)),
74                             file, lexer.lineno)
75                 elif tt == 'login' or tt == 'user':
76                     login = lexer.get_token()
77                 elif tt == 'account':
78                     account = lexer.get_token()
79                 elif tt == 'password':
80                     password = lexer.get_token()
81                 else:
82                     raise NetrcParseError("bad follower token %r" % tt,
83                                           file, lexer.lineno)
84
85     def authenticators(self, host):
86         """Return a (user, account, password) tuple for given host."""
87         if host in self.hosts:
88             return self.hosts[host]
89         elif 'default' in self.hosts:
90             return self.hosts['default']
91         else:
92             return None
93
94     def __repr__(self):
95         """Dump the class data in the format of a .netrc file."""
96         rep = ""
97         for host in self.hosts.keys():
98             attrs = self.hosts[host]
99             rep = rep + "machine "+ host + "\n\tlogin " + repr(attrs[0]) + "\n"
100             if attrs[1]:
101                 rep = rep + "account " + repr(attrs[1])
102             rep = rep + "\tpassword " + repr(attrs[2]) + "\n"
103         for macro in self.macros.keys():
104             rep = rep + "macdef " + macro + "\n"
105             for line in self.macros[macro]:
106                 rep = rep + line
107             rep = rep + "\n"
108         return rep
109
110 if __name__ == '__main__':
111     print netrc()