Merged revisions 81782 via svnmerge from
[python/dscho.git] / Modules / grpmodule.c
blobca3a3583f81742bfb02b99bf8bd66d5ce868f011
2 /* UNIX group file access module */
4 #include "Python.h"
5 #include "structseq.h"
7 #include <sys/types.h>
8 #include <grp.h>
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}
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");
24 static PyStructSequence_Desc struct_group_type_desc = {
25 "grp.struct_group",
26 struct_group__doc__,
27 struct_group_type_fields,
32 static int initialized;
33 static PyTypeObject StructGrpType;
35 static PyObject *
36 mkgrent(struct group *p)
38 int setIndex = 0;
39 PyObject *v = PyStructSequence_New(&StructGrpType), *w;
40 char **member;
42 if (v == NULL)
43 return NULL;
45 if ((w = PyList_New(0)) == NULL) {
46 Py_DECREF(v);
47 return NULL;
49 #define FSDECODE(val) PyUnicode_Decode(val, strlen(val),\
50 Py_FileSystemDefaultEncoding,\
51 "surrogateescape")
52 for (member = p->gr_mem; *member != NULL; member++) {
53 PyObject *x = FSDECODE(*member);
54 if (x == NULL || PyList_Append(w, x) != 0) {
55 Py_XDECREF(x);
56 Py_DECREF(w);
57 Py_DECREF(v);
58 return NULL;
60 Py_DECREF(x);
63 #define SET(i,val) PyStructSequence_SET_ITEM(v, i, val)
64 SET(setIndex++, FSDECODE(p->gr_name));
65 #ifdef __VMS
66 SET(setIndex++, Py_None);
67 Py_INCREF(Py_None);
68 #else
69 if (p->gr_passwd)
70 SET(setIndex++, FSDECODE(p->gr_passwd));
71 else {
72 SET(setIndex++, Py_None);
73 Py_INCREF(Py_None);
75 #endif
76 SET(setIndex++, PyLong_FromLong((long) p->gr_gid));
77 SET(setIndex++, w);
78 #undef SET
80 if (PyErr_Occurred()) {
81 Py_DECREF(v);
82 return NULL;
85 return v;
88 static PyObject *
89 grp_getgrgid(PyObject *self, PyObject *pyo_id)
91 PyObject *py_int_id;
92 unsigned int gid;
93 struct group *p;
95 py_int_id = PyNumber_Long(pyo_id);
96 if (!py_int_id)
97 return NULL;
98 gid = PyLong_AS_LONG(py_int_id);
99 Py_DECREF(py_int_id);
101 if ((p = getgrgid(gid)) == NULL) {
102 PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid);
103 return NULL;
105 return mkgrent(p);
108 static PyObject *
109 grp_getgrnam(PyObject *self, PyObject *args)
111 char *name;
112 struct group *p;
113 PyObject *arg, *bytes, *retval = NULL;
115 if (!PyArg_ParseTuple(args, "U:getgrnam", &arg))
116 return NULL;
117 if ((bytes = PyUnicode_AsEncodedString(arg, Py_FileSystemDefaultEncoding,
118 "surrogateescape")) == NULL)
119 return NULL;
120 if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1)
121 goto out;
123 if ((p = getgrnam(name)) == NULL) {
124 PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name);
125 goto out;
127 retval = mkgrent(p);
128 out:
129 Py_DECREF(bytes);
130 return retval;
133 static PyObject *
134 grp_getgrall(PyObject *self, PyObject *ignore)
136 PyObject *d;
137 struct group *p;
139 if ((d = PyList_New(0)) == NULL)
140 return NULL;
141 setgrent();
142 while ((p = getgrent()) != NULL) {
143 PyObject *v = mkgrent(p);
144 if (v == NULL || PyList_Append(d, v) != 0) {
145 Py_XDECREF(v);
146 Py_DECREF(d);
147 endgrent();
148 return NULL;
150 Py_DECREF(v);
152 endgrent();
153 return d;
156 static PyMethodDef grp_methods[] = {
157 {"getgrgid", grp_getgrgid, METH_O,
158 "getgrgid(id) -> tuple\n\
159 Return the group database entry for the given numeric group ID. If\n\
160 id is not valid, raise KeyError."},
161 {"getgrnam", grp_getgrnam, METH_VARARGS,
162 "getgrnam(name) -> tuple\n\
163 Return the group database entry for the given group name. If\n\
164 name is not valid, raise KeyError."},
165 {"getgrall", grp_getgrall, METH_NOARGS,
166 "getgrall() -> list of tuples\n\
167 Return a list of all available group entries, in arbitrary order."},
168 {NULL, NULL} /* sentinel */
171 PyDoc_STRVAR(grp__doc__,
172 "Access to the Unix group database.\n\
174 Group entries are reported as 4-tuples containing the following fields\n\
175 from the group database, in order:\n\
177 name - name of the group\n\
178 passwd - group password (encrypted); often empty\n\
179 gid - numeric ID of the group\n\
180 mem - list of members\n\
182 The gid is an integer, name and password are strings. (Note that most\n\
183 users are not explicitly listed as members of the groups they are in\n\
184 according to the password database. Check both databases to get\n\
185 complete membership information.)");
189 static struct PyModuleDef grpmodule = {
190 PyModuleDef_HEAD_INIT,
191 "grp",
192 grp__doc__,
194 grp_methods,
195 NULL,
196 NULL,
197 NULL,
198 NULL
201 PyMODINIT_FUNC
202 PyInit_grp(void)
204 PyObject *m, *d;
205 m = PyModule_Create(&grpmodule);
206 if (m == NULL)
207 return NULL;
208 d = PyModule_GetDict(m);
209 if (!initialized)
210 PyStructSequence_InitType(&StructGrpType, &struct_group_type_desc);
211 PyDict_SetItemString(d, "struct_group", (PyObject *) &StructGrpType);
212 initialized = 1;
213 return m;