2 from __future__ import absolute_import, print_function
5 from bup import _helpers
6 from bup.helpers import cache_key_value
9 # Using __slots__ makes these much smaller (even than a namedtuple)
12 """Drop in replacement for pwd's structure with bytes instead of strings."""
13 __slots__ = ('pw_name', 'pw_passwd', 'pw_uid', 'pw_gid', 'pw_gecos',
15 def __init__(self, name, passwd, uid, gid, gecos, dir, shell):
16 assert isinstance(name, bytes)
17 assert isinstance(passwd, bytes)
18 assert isinstance(gecos, bytes)
19 assert isinstance(dir, bytes)
20 assert isinstance(shell, bytes)
21 (self.pw_name, self.pw_passwd, self.pw_uid, self.pw_gid,
22 self.pw_gecos, self.pw_dir, self.pw_shell) = \
23 name, passwd, uid, gid, gecos, dir, shell
26 r = _helpers.getpwuid(uid)
27 return Passwd(*r) if r else None
30 assert isinstance(name, bytes)
31 r = _helpers.getpwnam(name)
32 return Passwd(*r) if r else None
36 """Drop in replacement for grp's structure with bytes instead of strings."""
37 __slots__ = 'gr_name', 'gr_passwd', 'gr_gid', 'gr_mem'
38 def __init__(self, name, passwd, gid, mem):
39 assert isinstance(name, bytes)
40 assert isinstance(passwd, bytes)
42 assert isinstance(m, bytes)
43 self.gr_name, self.gr_passwd, self.gr_gid, self.gr_mem = \
44 name, passwd, gid, mem
47 r = _helpers.getgrgid(uid)
48 return Group(*r) if r else None
51 assert isinstance(name, bytes)
52 r = _helpers.getgrnam(name)
53 return Group(*r) if r else None
56 _uid_to_pwd_cache = {}
57 _name_to_pwd_cache = {}
59 def pwd_from_uid(uid):
60 """Return password database entry for uid (may be a cached value).
61 Return None if no entry is found.
63 global _uid_to_pwd_cache, _name_to_pwd_cache
64 entry, cached = cache_key_value(getpwuid, uid, _uid_to_pwd_cache)
65 if entry and not cached:
66 _name_to_pwd_cache[entry.pw_name] = entry
69 def pwd_from_name(name):
70 """Return password database entry for name (may be a cached value).
71 Return None if no entry is found.
73 assert isinstance(name, bytes)
74 global _uid_to_pwd_cache, _name_to_pwd_cache
75 entry, cached = cache_key_value(getpwnam, name, _name_to_pwd_cache)
76 if entry and not cached:
77 _uid_to_pwd_cache[entry.pw_uid] = entry
81 _gid_to_grp_cache = {}
82 _name_to_grp_cache = {}
84 def grp_from_gid(gid):
85 """Return password database entry for gid (may be a cached value).
86 Return None if no entry is found.
88 global _gid_to_grp_cache, _name_to_grp_cache
89 entry, cached = cache_key_value(getgrgid, gid, _gid_to_grp_cache)
90 if entry and not cached:
91 _name_to_grp_cache[entry.gr_name] = entry
95 def grp_from_name(name):
96 """Return password database entry for name (may be a cached value).
97 Return None if no entry is found.
99 assert isinstance(name, bytes)
100 global _gid_to_grp_cache, _name_to_grp_cache
101 entry, cached = cache_key_value(getgrnam, name, _name_to_grp_cache)
102 if entry and not cached:
103 _gid_to_grp_cache[entry.gr_gid] = entry
109 """Get the user's login name."""
113 _username = pwd_from_uid(uid).pw_name or b'user%d' % uid
119 """Get the user's full name."""
121 if not _userfullname:
123 entry = pwd_from_uid(uid)
125 _userfullname = entry.pw_gecos.split(b',')[0] or entry.pw_name
126 if not _userfullname:
127 _userfullname = b'user%d' % uid