123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- """An object-oriented interface to .netrc files."""
- # Module and documentation by Eric S. Raymond, 21 Dec 1998
- import os, shlex
- __all__ = ["netrc", "NetrcParseError"]
- class NetrcParseError(Exception):
- """Exception raised on syntax errors in the .netrc file."""
- def __init__(self, msg, filename=None, lineno=None):
- self.filename = filename
- self.lineno = lineno
- self.msg = msg
- Exception.__init__(self, msg)
- def __str__(self):
- return "%s (%s, line %s)" % (self.msg, self.filename, self.lineno)
- class netrc:
- def __init__(self, file=None):
- if file is None:
- try:
- file = os.path.join(os.environ['HOME'], ".netrc")
- except KeyError:
- raise IOError("Could not find .netrc: $HOME is not set")
- fp = open(file)
- self.hosts = {}
- self.macros = {}
- lexer = shlex.shlex(fp)
- lexer.wordchars += r"""!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"""
- while 1:
- # Look for a machine, default, or macdef top-level keyword
- toplevel = tt = lexer.get_token()
- if not tt:
- break
- elif tt == 'machine':
- entryname = lexer.get_token()
- elif tt == 'default':
- entryname = 'default'
- elif tt == 'macdef': # Just skip to end of macdefs
- entryname = lexer.get_token()
- self.macros[entryname] = []
- lexer.whitespace = ' \t'
- while 1:
- line = lexer.instream.readline()
- if not line or line == '\012':
- lexer.whitespace = ' \t\r\n'
- break
- self.macros[entryname].append(line)
- continue
- else:
- raise NetrcParseError(
- "bad toplevel token %r" % tt, file, lexer.lineno)
- # We're looking at start of an entry for a named machine or default.
- 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 password:
- self.hosts[entryname] = (login, account, password)
- lexer.push_token(tt)
- break
- else:
- raise NetrcParseError(
- "malformed %s entry %s terminated by %s"
- % (toplevel, entryname, repr(tt)),
- file, lexer.lineno)
- 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 NetrcParseError("bad follower token %r" % tt,
- file, lexer.lineno)
- def authenticators(self, host):
- """Return a (user, account, password) tuple for given host."""
- if host in self.hosts:
- return self.hosts[host]
- elif 'default' in self.hosts:
- return self.hosts['default']
- else:
- return None
- def __repr__(self):
- """Dump the class data in the format of a .netrc file."""
- 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
- if __name__ == '__main__':
- print netrc()
|