ยปCore Development>Code coverage>Lib/plat-os2emx/grp.py

Python code coverage for Lib/plat-os2emx/grp.py

#countcontent
1n/a# this module is an OS/2 oriented replacement for the grp standard
2n/a# extension module.
3n/a
4n/a# written by Andrew MacIntyre, April 2001.
5n/a# updated July 2003, adding field accessor support
6n/a
7n/a# note that this implementation checks whether ":" or ";" as used as
8n/a# the field separator character.
9n/a
10n/a"""Replacement for grp standard extension module, intended for use on
11n/aOS/2 and similar systems which don't normally have an /etc/group file.
12n/a
13n/aThe standard Unix group database is an ASCII text file with 4 fields per
14n/arecord (line), separated by a colon:
15n/a - group name (string)
16n/a - group password (optional encrypted string)
17n/a - group id (integer)
18n/a - group members (comma delimited list of userids, with no spaces)
19n/a
20n/aNote that members are only included in the group file for groups that
21n/aaren't their primary groups.
22n/a(see the section 8.2 of the Python Library Reference)
23n/a
24n/aThis implementation differs from the standard Unix implementation by
25n/aallowing use of the platform's native path separator character - ';' on OS/2,
26n/aDOS and MS-Windows - as the field separator in addition to the Unix
27n/astandard ":".
28n/a
29n/aThe module looks for the group database at the following locations
30n/a(in order first to last):
31n/a - ${ETC_GROUP} (or %ETC_GROUP%)
32n/a - ${ETC}/group (or %ETC%/group)
33n/a - ${PYTHONHOME}/Etc/group (or %PYTHONHOME%/Etc/group)
34n/a
35n/aClasses
36n/a-------
37n/a
38n/aNone
39n/a
40n/aFunctions
41n/a---------
42n/a
43n/agetgrgid(gid) - return the record for group-id gid as a 4-tuple
44n/a
45n/agetgrnam(name) - return the record for group 'name' as a 4-tuple
46n/a
47n/agetgrall() - return a list of 4-tuples, each tuple being one record
48n/a (NOTE: the order is arbitrary)
49n/a
50n/aAttributes
51n/a----------
52n/a
53n/agroup_file - the path of the group database file
54n/a
55n/a"""
56n/a
57n/aimport os
58n/a
59n/a# try and find the group file
60n/a__group_path = []
61n/aif 'ETC_GROUP' in os.environ:
62n/a __group_path.append(os.environ['ETC_GROUP'])
63n/aif 'ETC' in os.environ:
64n/a __group_path.append('%s/group' % os.environ['ETC'])
65n/aif 'PYTHONHOME' in os.environ:
66n/a __group_path.append('%s/Etc/group' % os.environ['PYTHONHOME'])
67n/a
68n/agroup_file = None
69n/afor __i in __group_path:
70n/a try:
71n/a __f = open(__i, 'r')
72n/a __f.close()
73n/a group_file = __i
74n/a break
75n/a except:
76n/a pass
77n/a
78n/a# decide what field separator we can try to use - Unix standard, with
79n/a# the platform's path separator as an option. No special field conversion
80n/a# handlers are required for the group file.
81n/a__field_sep = [':']
82n/aif os.pathsep:
83n/a if os.pathsep != ':':
84n/a __field_sep.append(os.pathsep)
85n/a
86n/a# helper routine to identify which separator character is in use
87n/adef __get_field_sep(record):
88n/a fs = None
89n/a for c in __field_sep:
90n/a # there should be 3 delimiter characters (for 4 fields)
91n/a if record.count(c) == 3:
92n/a fs = c
93n/a break
94n/a if fs:
95n/a return fs
96n/a else:
97n/a raise KeyError('>> group database fields not delimited <<')
98n/a
99n/a# class to match the new record field name accessors.
100n/a# the resulting object is intended to behave like a read-only tuple,
101n/a# with each member also accessible by a field name.
102n/aclass Group:
103n/a def __init__(self, name, passwd, gid, mem):
104n/a self.__dict__['gr_name'] = name
105n/a self.__dict__['gr_passwd'] = passwd
106n/a self.__dict__['gr_gid'] = gid
107n/a self.__dict__['gr_mem'] = mem
108n/a self.__dict__['_record'] = (self.gr_name, self.gr_passwd,
109n/a self.gr_gid, self.gr_mem)
110n/a
111n/a def __len__(self):
112n/a return 4
113n/a
114n/a def __getitem__(self, key):
115n/a return self._record[key]
116n/a
117n/a def __setattr__(self, name, value):
118n/a raise AttributeError('attribute read-only: %s' % name)
119n/a
120n/a def __repr__(self):
121n/a return str(self._record)
122n/a
123n/a def __cmp__(self, other):
124n/a this = str(self._record)
125n/a if this == other:
126n/a return 0
127n/a elif this < other:
128n/a return -1
129n/a else:
130n/a return 1
131n/a
132n/a
133n/a# read the whole file, parsing each entry into tuple form
134n/a# with dictionaries to speed recall by GID or group name
135n/adef __read_group_file():
136n/a if group_file:
137n/a group = open(group_file, 'r')
138n/a else:
139n/a raise KeyError('>> no group database <<')
140n/a gidx = {}
141n/a namx = {}
142n/a sep = None
143n/a while 1:
144n/a entry = group.readline().strip()
145n/a if len(entry) > 3:
146n/a if sep is None:
147n/a sep = __get_field_sep(entry)
148n/a fields = entry.split(sep)
149n/a fields[2] = int(fields[2])
150n/a fields[3] = [f.strip() for f in fields[3].split(',')]
151n/a record = Group(*fields)
152n/a if fields[2] not in gidx:
153n/a gidx[fields[2]] = record
154n/a if fields[0] not in namx:
155n/a namx[fields[0]] = record
156n/a elif len(entry) > 0:
157n/a pass # skip empty or malformed records
158n/a else:
159n/a break
160n/a group.close()
161n/a if len(gidx) == 0:
162n/a raise KeyError
163n/a return (gidx, namx)
164n/a
165n/a# return the group database entry by GID
166n/adef getgrgid(gid):
167n/a g, n = __read_group_file()
168n/a return g[gid]
169n/a
170n/a# return the group database entry by group name
171n/adef getgrnam(name):
172n/a g, n = __read_group_file()
173n/a return n[name]
174n/a
175n/a# return all the group database entries
176n/adef getgrall():
177n/a g, n = __read_group_file()
178n/a return g.values()
179n/a
180n/a# test harness
181n/aif __name__ == '__main__':
182n/a getgrall()