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 # None was observed on Android
41 assert isinstance(passwd, bytes) or passwd is None
43 assert isinstance(m, bytes)
44 self.gr_name, self.gr_passwd, self.gr_gid, self.gr_mem = \
45 name, passwd, gid, mem
48 r = _helpers.getgrgid(uid)
49 return Group(*r) if r else None
52 assert isinstance(name, bytes)
53 r = _helpers.getgrnam(name)
54 return Group(*r) if r else None
57 _uid_to_pwd_cache = {}
58 _name_to_pwd_cache = {}
60 def pwd_from_uid(uid):
61 """Return password database entry for uid (may be a cached value).
62 Return None if no entry is found.
64 global _uid_to_pwd_cache, _name_to_pwd_cache
65 entry, cached = cache_key_value(getpwuid, uid, _uid_to_pwd_cache)
66 if entry and not cached:
67 _name_to_pwd_cache[entry.pw_name] = entry
70 def pwd_from_name(name):
71 """Return password database entry for name (may be a cached value).
72 Return None if no entry is found.
74 assert isinstance(name, bytes)
75 global _uid_to_pwd_cache, _name_to_pwd_cache
76 entry, cached = cache_key_value(getpwnam, name, _name_to_pwd_cache)
77 if entry and not cached:
78 _uid_to_pwd_cache[entry.pw_uid] = entry
82 _gid_to_grp_cache = {}
83 _name_to_grp_cache = {}
85 def grp_from_gid(gid):
86 """Return password database entry for gid (may be a cached value).
87 Return None if no entry is found.
89 global _gid_to_grp_cache, _name_to_grp_cache
90 entry, cached = cache_key_value(getgrgid, gid, _gid_to_grp_cache)
91 if entry and not cached:
92 _name_to_grp_cache[entry.gr_name] = entry
96 def grp_from_name(name):
97 """Return password database entry for name (may be a cached value).
98 Return None if no entry is found.
100 assert isinstance(name, bytes)
101 global _gid_to_grp_cache, _name_to_grp_cache
102 entry, cached = cache_key_value(getgrnam, name, _name_to_grp_cache)
103 if entry and not cached:
104 _gid_to_grp_cache[entry.gr_gid] = entry
110 """Get the user's login name."""
114 _username = pwd_from_uid(uid).pw_name or b'user%d' % uid
120 """Get the user's full name."""
122 if not _userfullname:
124 entry = pwd_from_uid(uid)
126 _userfullname = entry.pw_gecos.split(b',')[0] or entry.pw_name
127 if not _userfullname:
128 _userfullname = b'user%d' % uid