Fixed bug in time-to-midnight calculation.
[python.git] / Modules / grpmodule.c
blob5f33fe972fc8f33213d7132296209f85d04e2a01
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 PyTypeObject StructGrpType;
34 static PyObject *
35 mkgrent(struct group *p)
37 int setIndex = 0;
38 PyObject *v = PyStructSequence_New(&StructGrpType), *w;
39 char **member;
41 if (v == NULL)
42 return NULL;
44 if ((w = PyList_New(0)) == NULL) {
45 Py_DECREF(v);
46 return NULL;
48 for (member = p->gr_mem; *member != NULL; member++) {
49 PyObject *x = PyString_FromString(*member);
50 if (x == NULL || PyList_Append(w, x) != 0) {
51 Py_XDECREF(x);
52 Py_DECREF(w);
53 Py_DECREF(v);
54 return NULL;
56 Py_DECREF(x);
59 #define SET(i,val) PyStructSequence_SET_ITEM(v, i, val)
60 SET(setIndex++, PyString_FromString(p->gr_name));
61 #ifdef __VMS
62 SET(setIndex++, Py_None);
63 Py_INCREF(Py_None);
64 #else
65 if (p->gr_passwd)
66 SET(setIndex++, PyString_FromString(p->gr_passwd));
67 else {
68 SET(setIndex++, Py_None);
69 Py_INCREF(Py_None);
71 #endif
72 SET(setIndex++, PyInt_FromLong((long) p->gr_gid));
73 SET(setIndex++, w);
74 #undef SET
76 if (PyErr_Occurred()) {
77 Py_DECREF(v);
78 Py_DECREF(w);
79 return NULL;
82 return v;
85 static PyObject *
86 grp_getgrgid(PyObject *self, PyObject *args)
88 unsigned int gid;
89 struct group *p;
90 if (!PyArg_ParseTuple(args, "I:getgrgid", &gid))
91 return NULL;
92 if ((p = getgrgid(gid)) == NULL) {
93 PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid);
94 return NULL;
96 return mkgrent(p);
99 static PyObject *
100 grp_getgrnam(PyObject *self, PyObject *args)
102 char *name;
103 struct group *p;
104 if (!PyArg_ParseTuple(args, "s:getgrnam", &name))
105 return NULL;
106 if ((p = getgrnam(name)) == NULL) {
107 PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name);
108 return NULL;
110 return mkgrent(p);
113 static PyObject *
114 grp_getgrall(PyObject *self, PyObject *args)
116 PyObject *d;
117 struct group *p;
119 if (!PyArg_ParseTuple(args, ":getgrall"))
120 return NULL;
121 if ((d = PyList_New(0)) == NULL)
122 return NULL;
123 setgrent();
124 while ((p = getgrent()) != NULL) {
125 PyObject *v = mkgrent(p);
126 if (v == NULL || PyList_Append(d, v) != 0) {
127 Py_XDECREF(v);
128 Py_DECREF(d);
129 return NULL;
131 Py_DECREF(v);
133 endgrent();
134 return d;
137 static PyMethodDef grp_methods[] = {
138 {"getgrgid", grp_getgrgid, METH_VARARGS,
139 "getgrgid(id) -> tuple\n\
140 Return the group database entry for the given numeric group ID. If\n\
141 id is not valid, raise KeyError."},
142 {"getgrnam", grp_getgrnam, METH_VARARGS,
143 "getgrnam(name) -> tuple\n\
144 Return the group database entry for the given group name. If\n\
145 name is not valid, raise KeyError."},
146 {"getgrall", grp_getgrall, METH_VARARGS,
147 "getgrall() -> list of tuples\n\
148 Return a list of all available group entries, in arbitrary order."},
149 {NULL, NULL} /* sentinel */
152 PyDoc_STRVAR(grp__doc__,
153 "Access to the Unix group database.\n\
155 Group entries are reported as 4-tuples containing the following fields\n\
156 from the group database, in order:\n\
158 name - name of the group\n\
159 passwd - group password (encrypted); often empty\n\
160 gid - numeric ID of the group\n\
161 mem - list of members\n\
163 The gid is an integer, name and password are strings. (Note that most\n\
164 users are not explicitly listed as members of the groups they are in\n\
165 according to the password database. Check both databases to get\n\
166 complete membership information.)");
169 PyMODINIT_FUNC
170 initgrp(void)
172 PyObject *m, *d;
173 m = Py_InitModule3("grp", grp_methods, grp__doc__);
174 d = PyModule_GetDict(m);
175 PyStructSequence_InitType(&StructGrpType, &struct_group_type_desc);
176 PyDict_SetItemString(d, "struct_group", (PyObject *) &StructGrpType);