1
/* Copyright (C) 2001,2002 Red Hat, Inc.
3
* This is free software; you can redistribute it and/or modify it under
4
* the terms of the GNU Library General Public License as published by
5
* the Free Software Foundation; either version 2 of the License, or
6
* (at your option) any later version.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
* General Public License for more details.
13
* You should have received a copy of the GNU Library General Public
14
* License along with this program; if not, write to the Free Software
15
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
#ident "$Id: quotamodule.c,v 1.17 2004/09/27 04:33:11 mitr Exp $"
24
#include <sys/types.h>
25
#include <linux/quota.h>
30
#include "../lib/userquota.h"
33
void initlibuserquota(void);
35
static PyTypeObject quota_object_type;
37
PyObject_HEAD char *user;
40
int32_t inode_usage, inode_soft, inode_hard, inode_grace;
41
int32_t block_usage, block_soft, block_hard, block_grace;
45
quota_struct_dealloc(struct quota_struct *q)
58
static struct quota_struct *
59
quota_struct_new(const char *user, const char *group, const char *special,
60
int32_t inode_usage, int32_t inode_soft,
61
int32_t inode_hard, int32_t inode_grace,
62
int32_t block_usage, int32_t block_soft,
63
int32_t block_hard, int32_t block_grace)
65
struct quota_struct *ret = NULL;
68
ret = PyObject_NEW(struct quota_struct, "a_object_type);
73
ret->user = user ? strdup(user) : NULL;
74
ret->group = group ? strdup(group) : NULL;
75
ret->special = special ? strdup(special) : NULL;
76
ret->inode_usage = inode_usage;
77
ret->inode_soft = inode_soft;
78
ret->inode_hard = inode_hard;
79
ret->inode_grace = inode_grace;
80
ret->block_usage = block_usage;
81
ret->block_soft = block_soft;
82
ret->block_hard = block_hard;
83
ret->block_grace = block_grace;
89
quota_struct_copy(struct quota_struct *self, PyObject * args)
91
return (PyObject *) quota_struct_new(self->user, self->group,
103
PyMethodDef quota_struct_methods[] = {
104
{"copy", (PyCFunction) quota_struct_copy, 0, NULL},
105
{NULL, NULL, 0, NULL},
109
quota_struct_getattr(struct quota_struct *self, char *attr)
114
} named_string_attributes[] = {
115
{"user", self->user},
116
{"group", self->group},
117
{"special", self->special},
122
} named_int_attributes[] = {
123
{"inode_usage", self->inode_usage},
124
{"inode_soft", self->inode_soft},
125
{"inode_hard", self->inode_hard},
126
{"inode_grace", self->inode_grace},
127
{"block_usage", self->block_usage},
128
{"block_soft", self->block_soft},
129
{"block_hard", self->block_hard},
130
{"block_grace", self->block_grace},
131
{"inodeUsage", self->inode_usage},
132
{"inodeSoft", self->inode_soft},
133
{"inodeHard", self->inode_hard},
134
{"inodeGrace", self->inode_grace},
135
{"blockUsage", self->block_usage},
136
{"blockSoft", self->block_soft},
137
{"blockHard", self->block_hard},
138
{"blockGrace", self->block_grace},
143
if ((self->user == NULL) && (self->group == NULL))
145
PyErr_SetString(PyExc_RuntimeError,
146
"invalid quota object");
152
i < sizeof(named_string_attributes) /
153
sizeof(named_string_attributes[0]); i++) {
154
if (strcmp(attr, named_string_attributes[i].name) == 0) {
157
PyString_FromString(named_string_attributes[i].
163
i < sizeof(named_int_attributes) /
164
sizeof(named_int_attributes[0]); i++) {
165
if (strcmp(attr, named_int_attributes[i].name) == 0) {
167
return PyInt_FromLong(named_int_attributes[i].
173
return Py_FindMethod(quota_struct_methods, (PyObject*)self, attr);
177
quota_struct_setattr(struct quota_struct *self, char *attr,
183
} named_string_attributes[] = {
184
{"user", &self->user},
185
{"group", &self->group},
186
{"special", &self->special},
191
} named_int_attributes[] = {
192
{"inode_usage", &self->inode_usage},
193
{"inode_soft", &self->inode_soft},
194
{"inode_hard", &self->inode_hard},
195
{"inode_grace", &self->inode_grace},
196
{"block_usage", &self->block_usage},
197
{"block_soft", &self->block_soft},
198
{"block_hard", &self->block_hard},
199
{"block_grace", &self->block_grace},
200
{"inodeUsage", &self->inode_usage},
201
{"inodeSoft", &self->inode_soft},
202
{"inodeHard", &self->inode_hard},
203
{"inodeGrace", &self->inode_grace},
204
{"blockUsage", &self->block_usage},
205
{"blockSoft", &self->block_soft},
206
{"blockHard", &self->block_hard},
207
{"blockGrace", &self->block_grace},
212
if ((self->user == NULL) && (self->group == NULL)) {
213
PyErr_SetString(PyExc_RuntimeError, "invalid quota object");
219
i < G_N_ELEMENTS(named_string_attributes);
221
if (strcmp(attr, named_string_attributes[i].name) == 0) {
222
if (!PyString_Check(args)) {
223
PyErr_SetString(PyExc_TypeError,
224
"attribute is a string");
228
if (*named_string_attributes[i].value) {
229
free(*named_string_attributes[i].value);
231
*(named_string_attributes[i].value) =
232
strdup(PyString_AsString(args));
239
i < G_N_ELEMENTS(named_int_attributes);
241
if (strcmp(attr, named_int_attributes[i].name) == 0) {
242
if (!PyInt_Check(args)) {
243
PyErr_SetString(PyExc_TypeError,
244
"attribute is an integer");
248
*(named_int_attributes[i].value) =
254
PyErr_SetString(PyExc_AttributeError, "no such attribute");
261
quota_struct_print(struct quota_struct *self, FILE * output, int flag)
264
fprintf(output, "(user = '%s', group = '%s', special = '%s', "
265
"inode_usage = %d, inode_soft = %d, inode_hard = %d, "
266
"inode_grace = %d, block_usage = %d, block_soft = %d, "
267
"block_hard = %d, block_grace = %d)",
268
self->user ? : "(null)",
269
self->group ? : "(null)",
270
self->special ? : "(null)",
271
self->inode_usage, self->inode_soft,
272
self->inode_hard, self->inode_grace,
273
self->block_usage, self->block_soft,
274
self->block_hard, self->block_grace);
279
static PyTypeObject quota_object_type = {
280
PyObject_HEAD_INIT(&PyType_Type)
283
sizeof(struct quota_struct),
286
(destructor) quota_struct_dealloc,
287
(printfunc) quota_struct_print,
288
(getattrfunc) quota_struct_getattr,
289
(setattrfunc) quota_struct_setattr,
293
(PyNumberMethods *) NULL,
294
(PySequenceMethods *) NULL,
295
(PyMappingMethods *) NULL,
302
quotamodule_get(PyObject * self, PyObject * args, PyObject * kwargs)
304
PyObject *dict = NULL;
305
int type = USRQUOTA, i;
306
char *name = NULL, *special = NULL;
307
char **specials = NULL;
308
char *kwlist[] = { "type", "name", "special", NULL };
309
int32_t inode_usage, inode_soft, inode_hard, inode_grace;
310
int32_t block_usage, block_soft, block_hard, block_grace;
314
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "is|s", kwlist,
315
&type, &name, &special)) {
316
if (!PyErr_Occurred())
317
PyErr_SetString(PyExc_RuntimeError,
319
"string, optional string");
323
if ((type != USRQUOTA) && (type != GRPQUOTA)) {
324
PyErr_SetString(PyExc_RuntimeError,
325
"invalid type, expected USER or GROUP");
330
if (type == USRQUOTA) {
331
struct passwd pwd, *res;
333
getpwnam_r(name, &pwd, buf, sizeof(buf), &res);
335
PyErr_SetString(PyExc_RuntimeError,
336
"invalid user name");
342
struct group grp, *res;
344
getgrnam_r(name, &grp, buf, sizeof(buf), &res);
346
PyErr_SetString(PyExc_RuntimeError,
347
"invalid group name");
355
if (special == NULL) {
356
specials = (type == USRQUOTA) ?
357
quota_get_specials_user() : quota_get_specials_group();
358
for (i = 0; (specials != NULL) && (specials[i] != NULL); i++) {
360
USRQUOTA ? quota_get_user(id, specials[i],
369
quota_get_group(id, specials[i], &inode_usage,
370
&inode_soft, &inode_hard,
371
&inode_grace, &block_usage,
372
&block_soft, &block_hard,
373
&block_grace)) != 0) {
374
PyErr_SetString(PyExc_RuntimeError,
375
"error querying quota");
379
PyDict_SetItemString(dict, specials[i],
382
quota_struct_new(name, NULL,
393
quota_struct_new(NULL,
406
quota_free_specials(specials);
408
PyDict_SetItemString(dict, special,
411
quota_struct_new(name, NULL, special,
421
quota_struct_new(NULL, name, special,
437
quotamodule_set(PyObject * self, PyObject * args)
439
struct quota_struct *obj;
442
if (PyList_Check(args)) {
444
for (i = 0; i < PyList_Size(args); i++) {
445
if (quotamodule_set(self, PyList_GetItem(args, i))
452
return Py_BuildValue("");
455
if (!PyArg_ParseTuple(args, "O!", "a_object_type, &obj)) {
456
if (!PyErr_Occurred())
457
PyErr_SetString(PyExc_RuntimeError,
458
"expected quota_struct object");
462
if ((obj->user == NULL) && (obj->group == NULL)) {
463
PyErr_SetString(PyExc_RuntimeError,
464
"invalid quota object");
469
struct passwd pwd, *res;
471
getpwnam_r(obj->user, &pwd, buf, sizeof(buf), &res);
473
PyErr_SetString(PyExc_RuntimeError,
478
if (quota_set_user(pwd.pw_uid, obj->special,
479
obj->inode_soft, obj->inode_hard,
481
obj->block_soft, obj->block_hard,
482
obj->block_grace) != 0) {
483
PyErr_SetString(PyExc_RuntimeError,
484
"error setting quota limits");
489
struct group grp, *res;
491
getgrnam_r(obj->user, &grp, buf, sizeof(buf), &res);
493
PyErr_SetString(PyExc_RuntimeError,
498
if (quota_set_group(grp.gr_gid, obj->special,
499
obj->inode_soft, obj->inode_hard,
501
obj->block_soft, obj->block_hard,
502
obj->block_grace) != 0) {
503
PyErr_SetString(PyExc_RuntimeError,
504
"error setting quota limits");
510
return Py_BuildValue("");
514
quotamodule_on(PyObject * self, PyObject * args, PyObject * kwargs)
517
if (quota_on() != 0) {
518
PyErr_SetString(PyExc_RuntimeError,
519
"error enabling quotas");
524
return Py_BuildValue("");
528
quotamodule_off(PyObject * self, PyObject * args, PyObject * kwargs)
531
if (quota_off() != 0) {
532
PyErr_SetString(PyExc_RuntimeError,
533
"error disabling quotas");
538
return Py_BuildValue("");
541
static PyMethodDef quota_methods[] = {
542
{"get", (PyCFunction) quotamodule_get,
543
METH_VARARGS | METH_KEYWORDS},
544
{"set", (PyCFunction) quotamodule_set,
545
METH_VARARGS | METH_KEYWORDS},
546
{"on", (PyCFunction) quotamodule_on, METH_VARARGS | METH_KEYWORDS},
547
{"off", (PyCFunction) quotamodule_off,
548
METH_VARARGS | METH_KEYWORDS},
553
initlibuserquota(void)
555
PyObject *module, *dict;
557
module = Py_InitModule("libuserquota", quota_methods);
558
dict = PyModule_GetDict(module);
559
PyDict_SetItemString(dict, "USER", PyInt_FromLong(USRQUOTA));
560
PyDict_SetItemString(dict, "GROUP", PyInt_FromLong(GRPQUOTA));