]> arthur.barton.de Git - bup.git/blob - lib/bup/pwdgrp.py
Metadata: specify __slots__
[bup.git] / lib / bup / pwdgrp.py
1
2 from __future__ import absolute_import, print_function
3 import os
4
5 from bup import _helpers
6 from bup.helpers import cache_key_value
7
8
9 # Using __slots__ makes these much smaller (even than a namedtuple)
10
11 class Passwd:
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',
14                  'pw_dir', 'pw_shell')
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
24
25 def getpwuid(uid):
26     r = _helpers.getpwuid(uid)
27     return Passwd(*r) if r else None
28
29 def getpwnam(name):
30     assert isinstance(name, bytes)
31     r = _helpers.getpwnam(name)
32     return Passwd(*r) if r else None
33
34
35 class Group:
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
42         for m in mem:
43             assert isinstance(m, bytes)
44         self.gr_name, self.gr_passwd, self.gr_gid, self.gr_mem = \
45             name, passwd, gid, mem
46
47 def getgrgid(uid):
48     r = _helpers.getgrgid(uid)
49     return Group(*r) if r else None
50
51 def getgrnam(name):
52     assert isinstance(name, bytes)
53     r = _helpers.getgrnam(name)
54     return Group(*r) if r else None
55
56
57 _uid_to_pwd_cache = {}
58 _name_to_pwd_cache = {}
59
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.
63     """
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
68     return entry
69
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.
73     """
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
79     return entry
80
81
82 _gid_to_grp_cache = {}
83 _name_to_grp_cache = {}
84
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.
88     """
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
93     return entry
94
95
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.
99     """
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
105     return entry
106
107
108 _username = None
109 def username():
110     """Get the user's login name."""
111     global _username
112     if not _username:
113         uid = os.getuid()
114         _username = pwd_from_uid(uid).pw_name or b'user%d' % uid
115     return _username
116
117
118 _userfullname = None
119 def userfullname():
120     """Get the user's full name."""
121     global _userfullname
122     if not _userfullname:
123         uid = os.getuid()
124         entry = pwd_from_uid(uid)
125         if entry:
126             _userfullname = entry.pw_gecos.split(b',')[0] or entry.pw_name
127         if not _userfullname:
128             _userfullname = b'user%d' % uid
129     return _userfullname