|
1 |
|
2 /* UNIX group file access module */ |
|
3 |
|
4 #include "Python.h" |
|
5 #include "structseq.h" |
|
6 |
|
7 #include <sys/types.h> |
|
8 #include <grp.h> |
|
9 |
|
10 static PyStructSequence_Field struct_group_type_fields[] = { |
|
11 {"gr_name", "group name"}, |
|
12 {"gr_passwd", "password"}, |
|
13 {"gr_gid", "group id"}, |
|
14 {"gr_mem", "group memebers"}, |
|
15 {0} |
|
16 }; |
|
17 |
|
18 PyDoc_STRVAR(struct_group__doc__, |
|
19 "grp.struct_group: Results from getgr*() routines.\n\n\ |
|
20 This object may be accessed either as a tuple of\n\ |
|
21 (gr_name,gr_passwd,gr_gid,gr_mem)\n\ |
|
22 or via the object attributes as named in the above tuple.\n"); |
|
23 |
|
24 static PyStructSequence_Desc struct_group_type_desc = { |
|
25 "grp.struct_group", |
|
26 struct_group__doc__, |
|
27 struct_group_type_fields, |
|
28 4, |
|
29 }; |
|
30 |
|
31 |
|
32 static int initialized; |
|
33 static PyTypeObject StructGrpType; |
|
34 |
|
35 static PyObject * |
|
36 mkgrent(struct group *p) |
|
37 { |
|
38 int setIndex = 0; |
|
39 PyObject *v = PyStructSequence_New(&StructGrpType), *w; |
|
40 char **member; |
|
41 |
|
42 if (v == NULL) |
|
43 return NULL; |
|
44 |
|
45 if ((w = PyList_New(0)) == NULL) { |
|
46 Py_DECREF(v); |
|
47 return NULL; |
|
48 } |
|
49 for (member = p->gr_mem; *member != NULL; member++) { |
|
50 PyObject *x = PyString_FromString(*member); |
|
51 if (x == NULL || PyList_Append(w, x) != 0) { |
|
52 Py_XDECREF(x); |
|
53 Py_DECREF(w); |
|
54 Py_DECREF(v); |
|
55 return NULL; |
|
56 } |
|
57 Py_DECREF(x); |
|
58 } |
|
59 |
|
60 #define SET(i,val) PyStructSequence_SET_ITEM(v, i, val) |
|
61 SET(setIndex++, PyString_FromString(p->gr_name)); |
|
62 #ifdef __VMS |
|
63 SET(setIndex++, Py_None); |
|
64 Py_INCREF(Py_None); |
|
65 #else |
|
66 if (p->gr_passwd) |
|
67 SET(setIndex++, PyString_FromString(p->gr_passwd)); |
|
68 else { |
|
69 SET(setIndex++, Py_None); |
|
70 Py_INCREF(Py_None); |
|
71 } |
|
72 #endif |
|
73 SET(setIndex++, PyInt_FromLong((long) p->gr_gid)); |
|
74 SET(setIndex++, w); |
|
75 #undef SET |
|
76 |
|
77 if (PyErr_Occurred()) { |
|
78 Py_DECREF(v); |
|
79 Py_DECREF(w); |
|
80 return NULL; |
|
81 } |
|
82 |
|
83 return v; |
|
84 } |
|
85 |
|
86 static PyObject * |
|
87 grp_getgrgid(PyObject *self, PyObject *pyo_id) |
|
88 { |
|
89 PyObject *py_int_id; |
|
90 unsigned int gid; |
|
91 struct group *p; |
|
92 |
|
93 py_int_id = PyNumber_Int(pyo_id); |
|
94 if (!py_int_id) |
|
95 return NULL; |
|
96 gid = PyInt_AS_LONG(py_int_id); |
|
97 Py_DECREF(py_int_id); |
|
98 |
|
99 if ((p = getgrgid(gid)) == NULL) { |
|
100 PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid); |
|
101 return NULL; |
|
102 } |
|
103 return mkgrent(p); |
|
104 } |
|
105 |
|
106 static PyObject * |
|
107 grp_getgrnam(PyObject *self, PyObject *pyo_name) |
|
108 { |
|
109 PyObject *py_str_name; |
|
110 char *name; |
|
111 struct group *p; |
|
112 |
|
113 py_str_name = PyObject_Str(pyo_name); |
|
114 if (!py_str_name) |
|
115 return NULL; |
|
116 name = PyString_AS_STRING(py_str_name); |
|
117 |
|
118 if ((p = getgrnam(name)) == NULL) { |
|
119 PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name); |
|
120 Py_DECREF(py_str_name); |
|
121 return NULL; |
|
122 } |
|
123 |
|
124 Py_DECREF(py_str_name); |
|
125 return mkgrent(p); |
|
126 } |
|
127 |
|
128 static PyObject * |
|
129 grp_getgrall(PyObject *self, PyObject *ignore) |
|
130 { |
|
131 PyObject *d; |
|
132 struct group *p; |
|
133 |
|
134 if ((d = PyList_New(0)) == NULL) |
|
135 return NULL; |
|
136 setgrent(); |
|
137 while ((p = getgrent()) != NULL) { |
|
138 PyObject *v = mkgrent(p); |
|
139 if (v == NULL || PyList_Append(d, v) != 0) { |
|
140 Py_XDECREF(v); |
|
141 Py_DECREF(d); |
|
142 return NULL; |
|
143 } |
|
144 Py_DECREF(v); |
|
145 } |
|
146 endgrent(); |
|
147 return d; |
|
148 } |
|
149 |
|
150 static PyMethodDef grp_methods[] = { |
|
151 {"getgrgid", grp_getgrgid, METH_O, |
|
152 "getgrgid(id) -> tuple\n\ |
|
153 Return the group database entry for the given numeric group ID. If\n\ |
|
154 id is not valid, raise KeyError."}, |
|
155 {"getgrnam", grp_getgrnam, METH_O, |
|
156 "getgrnam(name) -> tuple\n\ |
|
157 Return the group database entry for the given group name. If\n\ |
|
158 name is not valid, raise KeyError."}, |
|
159 {"getgrall", grp_getgrall, METH_NOARGS, |
|
160 "getgrall() -> list of tuples\n\ |
|
161 Return a list of all available group entries, in arbitrary order."}, |
|
162 {NULL, NULL} /* sentinel */ |
|
163 }; |
|
164 |
|
165 PyDoc_STRVAR(grp__doc__, |
|
166 "Access to the Unix group database.\n\ |
|
167 \n\ |
|
168 Group entries are reported as 4-tuples containing the following fields\n\ |
|
169 from the group database, in order:\n\ |
|
170 \n\ |
|
171 name - name of the group\n\ |
|
172 passwd - group password (encrypted); often empty\n\ |
|
173 gid - numeric ID of the group\n\ |
|
174 mem - list of members\n\ |
|
175 \n\ |
|
176 The gid is an integer, name and password are strings. (Note that most\n\ |
|
177 users are not explicitly listed as members of the groups they are in\n\ |
|
178 according to the password database. Check both databases to get\n\ |
|
179 complete membership information.)"); |
|
180 |
|
181 |
|
182 PyMODINIT_FUNC |
|
183 initgrp(void) |
|
184 { |
|
185 PyObject *m, *d; |
|
186 m = Py_InitModule3("grp", grp_methods, grp__doc__); |
|
187 if (m == NULL) |
|
188 return; |
|
189 d = PyModule_GetDict(m); |
|
190 if (!initialized) |
|
191 PyStructSequence_InitType(&StructGrpType, &struct_group_type_desc); |
|
192 PyDict_SetItemString(d, "struct_group", (PyObject *) &StructGrpType); |
|
193 initialized = 1; |
|
194 } |