~ubuntu-branches/ubuntu/hardy/libuser/hardy-updates

« back to all changes in this revision

Viewing changes to python/quotamodule.c

  • Committer: Bazaar Package Importer
  • Author(s): Ghe Rivero
  • Date: 2005-09-30 16:22:04 UTC
  • Revision ID: james.westby@ubuntu.com-20050930162204-qubxaa7e2lbovdgh
Tags: upstream-0.54.dfsg.1
ImportĀ upstreamĀ versionĀ 0.54.dfsg.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2001,2002 Red Hat, Inc.
 
2
 *
 
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.
 
7
 *
 
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.
 
12
 *
 
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.
 
16
 */
 
17
 
 
18
#ident "$Id: quotamodule.c,v 1.17 2004/09/27 04:33:11 mitr Exp $"
 
19
 
 
20
#include <Python.h>
 
21
#ifdef HAVE_CONFIG_H
 
22
#include "config.h"
 
23
#endif
 
24
#include <sys/types.h>
 
25
#include <linux/quota.h>
 
26
#include <grp.h>
 
27
#include <pwd.h>
 
28
#include <stdlib.h>
 
29
#include <unistd.h>
 
30
#include "../lib/userquota.h"
 
31
#include "debug.h"
 
32
 
 
33
void initlibuserquota(void);
 
34
 
 
35
static PyTypeObject quota_object_type;
 
36
struct quota_struct {
 
37
        PyObject_HEAD char *user;
 
38
        char *group;
 
39
        char *special;
 
40
        int32_t inode_usage, inode_soft, inode_hard, inode_grace;
 
41
        int32_t block_usage, block_soft, block_hard, block_grace;
 
42
};
 
43
 
 
44
static void
 
45
quota_struct_dealloc(struct quota_struct *q)
 
46
{
 
47
        DEBUG_ENTRY;
 
48
        if (q->user)
 
49
                free(q->user);
 
50
        if (q->group)
 
51
                free(q->group);
 
52
        if (q->special)
 
53
                free(q->special);
 
54
        PyMem_DEL(q);
 
55
        DEBUG_EXIT;
 
56
}
 
57
 
 
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)
 
64
{
 
65
        struct quota_struct *ret = NULL;
 
66
 
 
67
        DEBUG_ENTRY;
 
68
        ret = PyObject_NEW(struct quota_struct, &quota_object_type);
 
69
        if (ret == NULL) {
 
70
                DEBUG_EXIT;
 
71
                return NULL;
 
72
        }
 
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;
 
84
        DEBUG_EXIT;
 
85
        return ret;
 
86
}
 
87
 
 
88
static PyObject *
 
89
quota_struct_copy(struct quota_struct *self, PyObject * args)
 
90
{
 
91
        return (PyObject *) quota_struct_new(self->user, self->group,
 
92
                                             self->special,
 
93
                                             self->inode_usage,
 
94
                                             self->inode_soft,
 
95
                                             self->inode_hard,
 
96
                                             self->inode_grace,
 
97
                                             self->block_usage,
 
98
                                             self->block_soft,
 
99
                                             self->block_hard,
 
100
                                             self->block_grace);
 
101
}
 
102
 
 
103
PyMethodDef quota_struct_methods[] = {
 
104
        {"copy", (PyCFunction) quota_struct_copy, 0, NULL},
 
105
        {NULL, NULL, 0, NULL},
 
106
};
 
107
 
 
108
static PyObject *
 
109
quota_struct_getattr(struct quota_struct *self, char *attr)
 
110
{
 
111
        struct {
 
112
                const char *name;
 
113
                const char *value;
 
114
        } named_string_attributes[] = {
 
115
                {"user", self->user},
 
116
                {"group", self->group},
 
117
                {"special", self->special},
 
118
        };
 
119
        struct {
 
120
                const char *name;
 
121
                int32_t value;
 
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},
 
139
        };
 
140
        int i;
 
141
 
 
142
        DEBUG_ENTRY;
 
143
        if ((self->user == NULL) && (self->group == NULL))
 
144
        {
 
145
                PyErr_SetString(PyExc_RuntimeError,
 
146
                                "invalid quota object");
 
147
                DEBUG_EXIT;
 
148
                return NULL;
 
149
        }
 
150
 
 
151
        for (i = 0;
 
152
             i < sizeof(named_string_attributes) /
 
153
             sizeof(named_string_attributes[0]); i++) {
 
154
                if (strcmp(attr, named_string_attributes[i].name) == 0) {
 
155
                        DEBUG_EXIT;
 
156
                        return
 
157
                            PyString_FromString(named_string_attributes[i].
 
158
                                                value);
 
159
                }
 
160
        }
 
161
 
 
162
        for (i = 0;
 
163
             i < sizeof(named_int_attributes) /
 
164
             sizeof(named_int_attributes[0]); i++) {
 
165
                if (strcmp(attr, named_int_attributes[i].name) == 0) {
 
166
                        DEBUG_EXIT;
 
167
                        return PyInt_FromLong(named_int_attributes[i].
 
168
                                              value);
 
169
                }
 
170
        }
 
171
 
 
172
        DEBUG_EXIT;
 
173
        return Py_FindMethod(quota_struct_methods, (PyObject*)self, attr);
 
174
}
 
175
 
 
176
static int
 
177
quota_struct_setattr(struct quota_struct *self, char *attr,
 
178
                     PyObject * args)
 
179
{
 
180
        struct {
 
181
                const char *name;
 
182
                char **value;
 
183
        } named_string_attributes[] = {
 
184
                {"user", &self->user},
 
185
                {"group", &self->group},
 
186
                {"special", &self->special},
 
187
        };
 
188
        struct {
 
189
                const char *name;
 
190
                int32_t *value;
 
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},
 
208
        };
 
209
        int i;
 
210
 
 
211
        DEBUG_ENTRY;
 
212
        if ((self->user == NULL) && (self->group == NULL)) {
 
213
                PyErr_SetString(PyExc_RuntimeError, "invalid quota object");
 
214
                DEBUG_EXIT;
 
215
                return -1;
 
216
        }
 
217
 
 
218
        for (i = 0;
 
219
             i < G_N_ELEMENTS(named_string_attributes);
 
220
             i++) {
 
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");
 
225
                                DEBUG_EXIT;
 
226
                                return -1;
 
227
                        }
 
228
                        if (*named_string_attributes[i].value) {
 
229
                                free(*named_string_attributes[i].value);
 
230
                        }
 
231
                        *(named_string_attributes[i].value) =
 
232
                                strdup(PyString_AsString(args));
 
233
                        DEBUG_EXIT;
 
234
                        return 0;
 
235
                }
 
236
        }
 
237
 
 
238
        for (i = 0;
 
239
             i < G_N_ELEMENTS(named_int_attributes);
 
240
             i++) {
 
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");
 
245
                                DEBUG_EXIT;
 
246
                                return -1;
 
247
                        }
 
248
                        *(named_int_attributes[i].value) =
 
249
                                PyInt_AsLong(args);
 
250
                        DEBUG_EXIT;
 
251
                        return 0;
 
252
                }
 
253
        }
 
254
        PyErr_SetString(PyExc_AttributeError, "no such attribute");
 
255
 
 
256
        DEBUG_EXIT;
 
257
        return -1;
 
258
}
 
259
 
 
260
static int
 
261
quota_struct_print(struct quota_struct *self, FILE * output, int flag)
 
262
{
 
263
        DEBUG_ENTRY;
 
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);
 
275
        DEBUG_EXIT;
 
276
        return 0;
 
277
}
 
278
 
 
279
static PyTypeObject quota_object_type = {
 
280
        PyObject_HEAD_INIT(&PyType_Type)
 
281
            0,
 
282
        "Quota",
 
283
        sizeof(struct quota_struct),
 
284
        0,
 
285
 
 
286
        (destructor) quota_struct_dealloc,
 
287
        (printfunc) quota_struct_print,
 
288
        (getattrfunc) quota_struct_getattr,
 
289
        (setattrfunc) quota_struct_setattr,
 
290
        (cmpfunc) NULL,
 
291
        (reprfunc) NULL,
 
292
 
 
293
        (PyNumberMethods *) NULL,
 
294
        (PySequenceMethods *) NULL,
 
295
        (PyMappingMethods *) NULL,
 
296
        (hashfunc) NULL,
 
297
        (ternaryfunc) NULL,
 
298
        (reprfunc) NULL,
 
299
};
 
300
 
 
301
static PyObject *
 
302
quotamodule_get(PyObject * self, PyObject * args, PyObject * kwargs)
 
303
{
 
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;
 
311
        long id;
 
312
 
 
313
        DEBUG_ENTRY;
 
314
        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "is|s", kwlist,
 
315
                                         &type, &name, &special)) {
 
316
                if (!PyErr_Occurred())
 
317
                        PyErr_SetString(PyExc_RuntimeError,
 
318
                                        "expected int, "
 
319
                                        "string, optional string");
 
320
                DEBUG_EXIT;
 
321
                return NULL;
 
322
        }
 
323
        if ((type != USRQUOTA) && (type != GRPQUOTA)) {
 
324
                PyErr_SetString(PyExc_RuntimeError,
 
325
                                "invalid type, expected USER or GROUP");
 
326
                DEBUG_EXIT;
 
327
                return NULL;
 
328
        }
 
329
 
 
330
        if (type == USRQUOTA) {
 
331
                struct passwd pwd, *res;
 
332
                char buf[LINE_MAX];
 
333
                getpwnam_r(name, &pwd, buf, sizeof(buf), &res);
 
334
                if (res != &pwd) {
 
335
                        PyErr_SetString(PyExc_RuntimeError,
 
336
                                        "invalid user name");
 
337
                        DEBUG_EXIT;
 
338
                        return NULL;
 
339
                }
 
340
                id = pwd.pw_uid;
 
341
        } else {
 
342
                struct group grp, *res;
 
343
                char buf[LINE_MAX];
 
344
                getgrnam_r(name, &grp, buf, sizeof(buf), &res);
 
345
                if (res != &grp) {
 
346
                        PyErr_SetString(PyExc_RuntimeError,
 
347
                                        "invalid group name");
 
348
                        DEBUG_EXIT;
 
349
                        return NULL;
 
350
                }
 
351
                id = grp.gr_gid;
 
352
        }
 
353
 
 
354
        dict = PyDict_New();
 
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++) {
 
359
                        if ((type ==
 
360
                             USRQUOTA ? quota_get_user(id, specials[i],
 
361
                                                       &inode_usage,
 
362
                                                       &inode_soft,
 
363
                                                       &inode_hard,
 
364
                                                       &inode_grace,
 
365
                                                       &block_usage,
 
366
                                                       &block_soft,
 
367
                                                       &block_hard,
 
368
                                                       &block_grace) :
 
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");
 
376
                                DEBUG_EXIT;
 
377
                                return NULL;
 
378
                        }
 
379
                        PyDict_SetItemString(dict, specials[i],
 
380
                                             (type == USRQUOTA ?
 
381
                                              (PyObject*)
 
382
                                              quota_struct_new(name, NULL,
 
383
                                                               specials[i],
 
384
                                                               inode_usage,
 
385
                                                               inode_soft,
 
386
                                                               inode_hard,
 
387
                                                               inode_grace,
 
388
                                                               block_usage,
 
389
                                                               block_soft,
 
390
                                                               block_hard,
 
391
                                                               block_grace) :
 
392
                                              (PyObject*)
 
393
                                              quota_struct_new(NULL,
 
394
                                                                 name,
 
395
                                                                 specials
 
396
                                                                 [i],
 
397
                                                                 inode_usage,
 
398
                                                                 inode_soft,
 
399
                                                                 inode_hard,
 
400
                                                                 inode_grace,
 
401
                                                                 block_usage,
 
402
                                                                 block_soft,
 
403
                                                                 block_hard,
 
404
                                                                 block_grace)));
 
405
                }
 
406
                quota_free_specials(specials);
 
407
        } else {
 
408
                PyDict_SetItemString(dict, special,
 
409
                                     (type == USRQUOTA ?
 
410
                                      (PyObject*)
 
411
                                      quota_struct_new(name, NULL, special,
 
412
                                                       inode_usage,
 
413
                                                       inode_soft,
 
414
                                                       inode_hard,
 
415
                                                       inode_grace,
 
416
                                                       block_usage,
 
417
                                                       block_soft,
 
418
                                                       block_hard,
 
419
                                                       block_grace) :
 
420
                                      (PyObject*)
 
421
                                      quota_struct_new(NULL, name, special,
 
422
                                                       inode_usage,
 
423
                                                       inode_soft,
 
424
                                                       inode_hard,
 
425
                                                       inode_grace,
 
426
                                                       block_usage,
 
427
                                                       block_soft,
 
428
                                                       block_hard,
 
429
                                                       block_grace)));
 
430
        }
 
431
 
 
432
        DEBUG_EXIT;
 
433
        return dict;
 
434
}
 
435
 
 
436
static PyObject *
 
437
quotamodule_set(PyObject * self, PyObject * args)
 
438
{
 
439
        struct quota_struct *obj;
 
440
        DEBUG_ENTRY;
 
441
 
 
442
        if (PyList_Check(args)) {
 
443
                int i;
 
444
                for (i = 0; i < PyList_Size(args); i++) {
 
445
                        if (quotamodule_set(self, PyList_GetItem(args, i))
 
446
                            == NULL) {
 
447
                                DEBUG_EXIT;
 
448
                                return NULL;
 
449
                        }
 
450
                }
 
451
                DEBUG_EXIT;
 
452
                return Py_BuildValue("");
 
453
        }
 
454
 
 
455
        if (!PyArg_ParseTuple(args, "O!", &quota_object_type, &obj)) {
 
456
                if (!PyErr_Occurred())
 
457
                        PyErr_SetString(PyExc_RuntimeError,
 
458
                                        "expected quota_struct object");
 
459
                DEBUG_EXIT;
 
460
                return NULL;
 
461
        }
 
462
        if ((obj->user == NULL) && (obj->group == NULL)) {
 
463
                PyErr_SetString(PyExc_RuntimeError,
 
464
                                "invalid quota object");
 
465
                DEBUG_EXIT;
 
466
                return NULL;
 
467
        }
 
468
        if (obj->user) {
 
469
                struct passwd pwd, *res;
 
470
                char buf[LINE_MAX];
 
471
                getpwnam_r(obj->user, &pwd, buf, sizeof(buf), &res);
 
472
                if (res != &pwd) {
 
473
                        PyErr_SetString(PyExc_RuntimeError,
 
474
                                        "invalid user");
 
475
                        DEBUG_EXIT;
 
476
                        return NULL;
 
477
                }
 
478
                if (quota_set_user(pwd.pw_uid, obj->special,
 
479
                                   obj->inode_soft, obj->inode_hard,
 
480
                                   obj->inode_grace,
 
481
                                   obj->block_soft, obj->block_hard,
 
482
                                   obj->block_grace) != 0) {
 
483
                        PyErr_SetString(PyExc_RuntimeError,
 
484
                                        "error setting quota limits");
 
485
                        DEBUG_EXIT;
 
486
                        return NULL;
 
487
                }
 
488
        } else {
 
489
                struct group grp, *res;
 
490
                char buf[LINE_MAX];
 
491
                getgrnam_r(obj->user, &grp, buf, sizeof(buf), &res);
 
492
                if (res != &grp) {
 
493
                        PyErr_SetString(PyExc_RuntimeError,
 
494
                                        "invalid group");
 
495
                        DEBUG_EXIT;
 
496
                        return NULL;
 
497
                }
 
498
                if (quota_set_group(grp.gr_gid, obj->special,
 
499
                                    obj->inode_soft, obj->inode_hard,
 
500
                                    obj->inode_grace,
 
501
                                    obj->block_soft, obj->block_hard,
 
502
                                    obj->block_grace) != 0) {
 
503
                        PyErr_SetString(PyExc_RuntimeError,
 
504
                                        "error setting quota limits");
 
505
                        DEBUG_EXIT;
 
506
                        return NULL;
 
507
                }
 
508
        }
 
509
        DEBUG_EXIT;
 
510
        return Py_BuildValue("");
 
511
}
 
512
 
 
513
static PyObject *
 
514
quotamodule_on(PyObject * self, PyObject * args, PyObject * kwargs)
 
515
{
 
516
        DEBUG_ENTRY;
 
517
        if (quota_on() != 0) {
 
518
                PyErr_SetString(PyExc_RuntimeError,
 
519
                                "error enabling quotas");
 
520
                DEBUG_EXIT;
 
521
                return NULL;
 
522
        }
 
523
        DEBUG_EXIT;
 
524
        return Py_BuildValue("");
 
525
}
 
526
 
 
527
static PyObject *
 
528
quotamodule_off(PyObject * self, PyObject * args, PyObject * kwargs)
 
529
{
 
530
        DEBUG_ENTRY;
 
531
        if (quota_off() != 0) {
 
532
                PyErr_SetString(PyExc_RuntimeError,
 
533
                                "error disabling quotas");
 
534
                DEBUG_EXIT;
 
535
                return NULL;
 
536
        }
 
537
        DEBUG_EXIT;
 
538
        return Py_BuildValue("");
 
539
}
 
540
 
 
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},
 
549
        {NULL, NULL, 0},
 
550
};
 
551
 
 
552
void
 
553
initlibuserquota(void)
 
554
{
 
555
        PyObject *module, *dict;
 
556
        DEBUG_ENTRY;
 
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));
 
561
        DEBUG_EXIT;
 
562
}