grpmodule.c 4.7 KB
Newer Older
1 2 3

/* UNIX group file access module */

Roger E. Masse's avatar
Roger E. Masse committed
4
#include "Python.h"
5
#include "structseq.h"
6 7 8 9

#include <sys/types.h>
#include <grp.h>

10 11 12 13 14 15 16 17
static PyStructSequence_Field struct_group_type_fields[] = {
   {"gr_name", "group name"},
   {"gr_passwd", "password"},
   {"gr_gid", "group id"}, 
   {"gr_mem", "group memebers"}, 
   {0}
};

18
PyDoc_STRVAR(struct_group__doc__,
19 20 21
"grp.struct_group: Results from getgr*() routines.\n\n\
This object may be accessed either as a tuple of\n\
  (gr_name,gr_passwd,gr_gid,gr_mem)\n\
22
or via the object attributes as named in the above tuple.\n");
23 24 25 26 27 28 29 30 31

static PyStructSequence_Desc struct_group_type_desc = {
   "grp.struct_group",
   struct_group__doc__,
   struct_group_type_fields,
   4,
};


32
static int initialized;
33
static PyTypeObject StructGrpType;
34 35 36

static PyObject *
mkgrent(struct group *p)
37
{
38 39
    int setIndex = 0;
    PyObject *v = PyStructSequence_New(&StructGrpType), *w;
40
    char **member;
41 42 43 44

    if (v == NULL)
        return NULL;

45
    if ((w = PyList_New(0)) == NULL) {
46
        Py_DECREF(v);
47 48 49 50 51 52 53
        return NULL;
    }
    for (member = p->gr_mem; *member != NULL; member++) {
        PyObject *x = PyString_FromString(*member);
        if (x == NULL || PyList_Append(w, x) != 0) {
            Py_XDECREF(x);
            Py_DECREF(w);
54
            Py_DECREF(v);
55 56 57 58
            return NULL;
        }
        Py_DECREF(x);
    }
59 60 61

#define SET(i,val) PyStructSequence_SET_ITEM(v, i, val)
    SET(setIndex++, PyString_FromString(p->gr_name));
62 63 64 65
#ifdef __VMS
    SET(setIndex++, Py_None);
    Py_INCREF(Py_None);
#else
66 67 68 69 70 71
    if (p->gr_passwd)
	    SET(setIndex++, PyString_FromString(p->gr_passwd));
    else {
	    SET(setIndex++, Py_None);
	    Py_INCREF(Py_None);
    }
72
#endif
73 74 75 76 77 78 79 80 81 82
    SET(setIndex++, PyInt_FromLong((long) p->gr_gid));
    SET(setIndex++, w);
#undef SET

    if (PyErr_Occurred()) {
        Py_DECREF(v);
        Py_DECREF(w);
        return NULL;
    }

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 94 95 96 97 98

    py_int_id = PyNumber_Int(pyo_id);
    if (!py_int_id)
	    return NULL;
    gid = PyInt_AS_LONG(py_int_id);
    Py_DECREF(py_int_id);

99
    if ((p = getgrgid(gid)) == NULL) {
100
	PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid);
101 102 103
        return NULL;
    }
    return mkgrent(p);
104 105
}

106
static PyObject *
107
grp_getgrnam(PyObject *self, PyObject *pyo_name)
108
{
109
    PyObject *py_str_name;
110 111
    char *name;
    struct group *p;
112 113 114 115 116 117

    py_str_name = PyObject_Str(pyo_name);
    if (!py_str_name)
	    return NULL;
    name = PyString_AS_STRING(py_str_name);
    
118
    if ((p = getgrnam(name)) == NULL) {
119
	PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name);
120
	Py_DECREF(py_str_name);
121 122
        return NULL;
    }
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 132 133 134 135 136 137 138 139 140 141 142 143 144 145
    PyObject *d;
    struct group *p;

    if ((d = PyList_New(0)) == NULL)
        return NULL;
    setgrent();
    while ((p = getgrent()) != NULL) {
        PyObject *v = mkgrent(p);
        if (v == NULL || PyList_Append(d, v) != 0) {
            Py_XDECREF(v);
            Py_DECREF(d);
            return NULL;
        }
        Py_DECREF(v);
    }
146
    endgrent();
147
    return d;
148 149
}

Roger E. Masse's avatar
Roger E. Masse committed
150
static PyMethodDef grp_methods[] = {
151
    {"getgrgid",	grp_getgrgid,	METH_O,
152 153 154
     "getgrgid(id) -> tuple\n\
Return the group database entry for the given numeric group ID.  If\n\
id is not valid, raise KeyError."},
155
    {"getgrnam",	grp_getgrnam,	METH_O,
156 157 158
     "getgrnam(name) -> tuple\n\
Return the group database entry for the given group name.  If\n\
name is not valid, raise KeyError."},
159
    {"getgrall",	grp_getgrall,	METH_NOARGS,
160 161 162
     "getgrall() -> list of tuples\n\
Return a list of all available group entries, in arbitrary order."},
    {NULL,		NULL}		/* sentinel */
163 164
};

165
PyDoc_STRVAR(grp__doc__,
166 167 168 169 170 171 172 173 174 175 176 177 178
"Access to the Unix group database.\n\
\n\
Group entries are reported as 4-tuples containing the following fields\n\
from the group database, in order:\n\
\n\
  name   - name of the group\n\
  passwd - group password (encrypted); often empty\n\
  gid    - numeric ID of the group\n\
  mem    - list of members\n\
\n\
The gid is an integer, name and password are strings.  (Note that most\n\
users are not explicitly listed as members of the groups they are in\n\
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 186
    PyObject *m, *d;
    m = Py_InitModule3("grp", grp_methods, grp__doc__);
187 188
    if (m == NULL)
        return;
189
    d = PyModule_GetDict(m);
190 191
    if (!initialized)
	    PyStructSequence_InitType(&StructGrpType, &struct_group_type_desc);
192
    PyDict_SetItemString(d, "struct_group", (PyObject *) &StructGrpType);
193
    initialized = 1;
194
}