include updates
[tomato.git] / release / src-rt-6.x.4708 / router / samba-3.0.25b / source / python / py_tdb.c
blob322d367eda49ff8f1b8cccfa2a80e51c0410f3c7
1 /*
2 Python wrappers for TDB module
4 Copyright (C) Tim Potter, 2002-2003
6 ** NOTE! The following LGPL license applies to the tdb python
7 ** scripting library. This does NOT imply that all of Samba is
8 ** released under the LGPL
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2 of the License, or (at your option) any later version.
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "includes.h"
27 /* This symbol is used in both includes.h and Python.h which causes an
28 annoying compiler warning. */
30 #ifdef HAVE_FSTAT
31 #undef HAVE_FSTAT
32 #endif
34 #include "Python.h"
36 /* Tdb exception */
38 PyObject *py_tdb_error;
40 /* tdb handle object */
42 typedef struct {
43 PyObject_HEAD
44 TDB_CONTEXT *tdb;
45 } tdb_hnd_object;
47 PyTypeObject tdb_hnd_type;
49 PyObject *new_tdb_hnd_object(TDB_CONTEXT *tdb)
51 tdb_hnd_object *obj;
53 obj = PyObject_New(tdb_hnd_object, &tdb_hnd_type);
54 obj->tdb = tdb;
56 return (PyObject *)obj;
59 PyObject *py_tdb_close(PyObject *self, PyObject *args)
61 tdb_hnd_object *obj;
63 if (!PyArg_ParseTuple(args, "O!", &tdb_hnd_type, &obj))
64 return NULL;
66 if (tdb_close(obj->tdb) == -1) {
67 obj->tdb = NULL;
68 PyErr_SetString(py_tdb_error, strerror(errno));
69 return NULL;
72 obj->tdb = NULL;
74 Py_INCREF(Py_None);
75 return Py_None;
78 PyObject *py_tdb_open(PyObject *self, PyObject *args, PyObject *kw)
80 static char *kwlist[] = { "name", "hash_size", "tdb_flags",
81 "open_flags", "mode", NULL };
82 char *name;
83 int hash_size = 0, flags = TDB_DEFAULT, open_flags = -1, open_mode = 0600;
84 TDB_CONTEXT *tdb;
86 if (!PyArg_ParseTupleAndKeywords(
87 args, kw, "s|iiii", kwlist, &name, &hash_size, &flags,
88 &open_flags, &open_mode))
89 return NULL;
91 /* Default open_flags to read/write */
93 if (open_flags == -1) {
94 if (access(name, W_OK) == -1)
95 open_flags = O_RDONLY;
96 else
97 open_flags = O_RDWR;
100 if (!(tdb = tdb_open(name, hash_size, flags, open_flags, open_mode))) {
101 PyErr_SetString(py_tdb_error, strerror(errno));
102 return NULL;
105 return new_tdb_hnd_object(tdb);
109 * Allow a tdb to act as a python mapping (dictionary)
112 static int tdb_traverse_count(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA value,
113 void *state)
115 /* Do nothing - tdb_traverse will return the number of records
116 traversed. */
118 return 0;
121 static int tdb_hnd_length(tdb_hnd_object *obj)
123 int result;
125 result = tdb_traverse(obj->tdb, tdb_traverse_count, NULL);
127 return result;
130 static PyObject *tdb_hnd_subscript(tdb_hnd_object *obj, PyObject *key)
132 TDB_DATA drec, krec;
133 PyObject *result;
135 if (!PyArg_Parse(key, "s#", &krec.dptr, &krec.dsize))
136 return NULL;
138 drec = tdb_fetch(obj->tdb, krec);
140 if (!drec.dptr) {
141 PyErr_SetString(PyExc_KeyError,
142 PyString_AsString(key));
143 return NULL;
146 result = PyString_FromStringAndSize(drec.dptr, drec.dsize);
147 free(drec.dptr);
149 return result;
152 static int tdb_ass_subscript(tdb_hnd_object *obj, PyObject *key, PyObject *value)
154 TDB_DATA krec, drec;
156 if (!PyArg_Parse(key, "s#", &krec.dptr, &krec.dsize)) {
157 PyErr_SetString(PyExc_TypeError,
158 "tdb mappings have string indices only");
159 return -1;
162 if (!obj->tdb) {
163 PyErr_SetString(
164 py_tdb_error, "tdb object has been closed");
165 return -1;
168 if (!value) {
170 /* Delete value */
172 if (tdb_delete(obj->tdb, krec) == -1) {
173 PyErr_SetString(PyExc_KeyError,
174 PyString_AsString(value));
175 return -1;
178 } else {
180 /* Set value */
182 if (!PyArg_Parse(value, "s#", &drec.dptr, &drec.dsize)) {
183 PyErr_SetString(PyExc_TypeError,
184 "tdb mappings have string elements only");
185 return -1;
188 errno = 0;
190 if (tdb_store(obj->tdb, krec, drec, 0) < 0 ) {
191 if (errno != 0)
192 PyErr_SetFromErrno(py_tdb_error);
193 else
194 PyErr_SetString(
195 py_tdb_error,
196 (char *)tdb_errorstr(obj->tdb));
198 return -1;
202 return 0;
205 static PyMappingMethods tdb_mapping = {
206 (inquiry) tdb_hnd_length,
207 (binaryfunc) tdb_hnd_subscript,
208 (objobjargproc) tdb_ass_subscript
212 * Utility methods
215 /* Return non-zero if a given key exists in the tdb */
217 PyObject *py_tdb_hnd_has_key(PyObject *self, PyObject *args)
219 tdb_hnd_object *obj = (tdb_hnd_object *)self;
220 TDB_DATA key;
222 if (!PyArg_ParseTuple(args, "s#", &key.dptr, &key.dsize))
223 return NULL;
225 if (!obj->tdb) {
226 PyErr_SetString(
227 py_tdb_error, "tdb object has been closed");
228 return NULL;
231 return PyInt_FromLong(tdb_exists(obj->tdb, key));
234 /* Return a list of keys in the tdb */
236 static int tdb_traverse_keys(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA value,
237 void *state)
239 PyObject *key_list = (PyObject *)state;
241 PyList_Append(key_list,
242 PyString_FromStringAndSize(key.dptr, key.dsize));
244 return 0;
247 PyObject *py_tdb_hnd_keys(PyObject *self, PyObject *args)
249 tdb_hnd_object *obj = (tdb_hnd_object *)self;
250 PyObject *key_list = PyList_New(0);
252 if (!obj->tdb) {
253 PyErr_SetString(py_tdb_error, "tdb object has been closed");
254 return NULL;
257 if (tdb_traverse(obj->tdb, tdb_traverse_keys, key_list) == -1) {
258 PyErr_SetString(py_tdb_error, "error traversing tdb");
259 Py_DECREF(key_list);
260 return NULL;
263 return key_list;
266 PyObject *py_tdb_hnd_first_key(PyObject *self, PyObject *args)
268 tdb_hnd_object *obj = (tdb_hnd_object *)self;
269 TDB_DATA key;
271 if (!obj->tdb) {
272 PyErr_SetString(py_tdb_error, "tdb object has been closed");
273 return NULL;
276 key = tdb_firstkey(obj->tdb);
278 return Py_BuildValue("s#", key.dptr, key.dsize);
281 PyObject *py_tdb_hnd_next_key(PyObject *self, PyObject *py_oldkey)
283 tdb_hnd_object *obj = (tdb_hnd_object *)self;
284 TDB_DATA key, oldkey;
286 if (!obj->tdb) {
287 PyErr_SetString(py_tdb_error, "tdb object has been closed");
288 return NULL;
291 if (!PyArg_Parse(py_oldkey, "s#", &oldkey.dptr, &oldkey.dsize))
292 return NULL;
294 key = tdb_nextkey(obj->tdb, oldkey);
296 return Py_BuildValue("s#", key.dptr, key.dsize);
300 * Locking routines
303 PyObject *py_tdb_hnd_lock_all(PyObject *self, PyObject *args)
305 tdb_hnd_object *obj = (tdb_hnd_object *)self;
306 int result;
308 if (!obj->tdb) {
309 PyErr_SetString(py_tdb_error, "tdb object has been closed");
310 return NULL;
313 result = tdb_lockall(obj->tdb);
315 return PyInt_FromLong(result != -1);
318 PyObject *py_tdb_hnd_unlock_all(PyObject *self, PyObject *args)
320 tdb_hnd_object *obj = (tdb_hnd_object *)self;
322 if (!obj->tdb) {
323 PyErr_SetString(py_tdb_error, "tdb object has been closed");
324 return NULL;
327 tdb_unlockall(obj->tdb);
329 Py_INCREF(Py_None);
330 return Py_None;
333 /* Return an array of keys from a python object which must be a string or a
334 list of strings. */
336 static BOOL make_lock_list(PyObject *py_keys, TDB_DATA **keys, int *num_keys)
338 /* Are we a list or a string? */
340 if (!PyList_Check(py_keys) && !PyString_Check(py_keys)) {
341 PyErr_SetString(PyExc_TypeError, "arg must be list of string");
342 return False;
345 if (PyList_Check(py_keys)) {
346 int i;
348 /* Turn python list into array of keys */
350 *num_keys = PyList_Size(py_keys);
351 *keys = (TDB_DATA *)SMB_XMALLOC_ARRAY(TDB_DATA, (*num_keys));
353 for (i = 0; i < *num_keys; i++) {
354 PyObject *key = PyList_GetItem(py_keys, i);
356 if (!PyString_Check(key)) {
357 PyErr_SetString(
358 PyExc_TypeError,
359 "list elements must be strings");
360 return False;
363 PyArg_Parse(key, "s#", &(*keys)[i].dptr,
364 &(*keys)[i].dsize);
367 } else {
369 /* Turn python string into a single key */
371 *keys = (TDB_DATA *)SMB_XMALLOC_P(TDB_DATA);
372 *num_keys = 1;
373 PyArg_Parse(py_keys, "s#", &(*keys)->dptr, &(*keys)->dsize);
376 return True;
380 * tdb traversal
383 struct traverse_info {
384 PyObject *callback;
385 PyObject *state;
388 static int tdb_traverse_traverse(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA value,
389 void *state)
391 struct traverse_info *info = state;
392 PyObject *arglist, *py_result;
393 int result;
395 arglist = Py_BuildValue("(s#s#O)", key.dptr, key.dsize, value.dptr,
396 value.dsize, info->state);
398 py_result = PyEval_CallObject(info->callback, arglist);
400 Py_DECREF(arglist);
402 if (!PyInt_Check(py_result)) {
403 result = 1; /* Hmm - non-integer object returned by callback */
404 goto done;
407 result = PyInt_AsLong(py_result);
409 done:
410 Py_DECREF(py_result);
411 return result;
414 PyObject *py_tdb_hnd_traverse(PyObject *self, PyObject *args, PyObject *kw)
416 tdb_hnd_object *obj = (tdb_hnd_object *)self;
417 static char *kwlist[] = { "traverse_fn", "state", NULL };
418 PyObject *state = Py_None, *callback;
419 struct traverse_info info;
420 int result;
422 if (!PyArg_ParseTupleAndKeywords(
423 args, kw, "O|O", kwlist, &callback, &state))
424 return NULL;
426 if (!PyCallable_Check(callback)) {
427 PyErr_SetString(PyExc_TypeError, "parameter must be callable");
428 return NULL;
431 Py_INCREF(callback);
432 Py_INCREF(state);
434 info.callback = callback;
435 info.state = state;
437 result = tdb_traverse(obj->tdb, tdb_traverse_traverse, &info);
439 Py_DECREF(callback);
440 Py_DECREF(state);
442 return PyInt_FromLong(result);
445 PyObject *py_tdb_hnd_chainlock(PyObject *self, PyObject *args)
447 tdb_hnd_object *obj = (tdb_hnd_object *)self;
448 TDB_DATA key;
449 int result;
451 if (!obj->tdb) {
452 PyErr_SetString(py_tdb_error, "tdb object has been closed");
453 return NULL;
456 if (!PyArg_ParseTuple(args, "s#", &key.dptr, &key.dsize))
457 return NULL;
459 result = tdb_chainlock(obj->tdb, key);
461 return PyInt_FromLong(result != -1);
464 PyObject *py_tdb_hnd_chainunlock(PyObject *self, PyObject *args)
466 tdb_hnd_object *obj = (tdb_hnd_object *)self;
467 TDB_DATA key;
468 int result;
470 if (!obj->tdb) {
471 PyErr_SetString(py_tdb_error, "tdb object has been closed");
472 return NULL;
475 if (!PyArg_ParseTuple(args, "s#", &key.dptr, &key.dsize))
476 return NULL;
478 result = tdb_chainunlock(obj->tdb, key);
480 return PyInt_FromLong(result != -1);
483 PyObject *py_tdb_hnd_lock_bystring(PyObject *self, PyObject *args)
485 tdb_hnd_object *obj = (tdb_hnd_object *)self;
486 int result, timeout = 30;
487 char *s;
489 if (!obj->tdb) {
490 PyErr_SetString(py_tdb_error, "tdb object has been closed");
491 return NULL;
494 if (!PyArg_ParseTuple(args, "s|i", &s, &timeout))
495 return NULL;
497 result = tdb_lock_bystring_with_timeout(obj->tdb, s, timeout);
499 return PyInt_FromLong(result != -1);
502 PyObject *py_tdb_hnd_unlock_bystring(PyObject *self, PyObject *args)
504 tdb_hnd_object *obj = (tdb_hnd_object *)self;
505 char *s;
507 if (!obj->tdb) {
508 PyErr_SetString(py_tdb_error, "tdb object has been closed");
509 return NULL;
512 if (!PyArg_ParseTuple(args, "s", &s))
513 return NULL;
515 tdb_unlock_bystring(obj->tdb, s);
517 Py_INCREF(Py_None);
518 return Py_None;
522 * Method dispatch table for this module
525 static PyMethodDef tdb_methods[] = {
526 { "open", (PyCFunction)py_tdb_open, METH_VARARGS | METH_KEYWORDS },
527 { "close", (PyCFunction)py_tdb_close, METH_VARARGS },
528 { NULL }
532 * Methods on a tdb object
535 static PyMethodDef tdb_hnd_methods[] = {
536 { "keys", (PyCFunction)py_tdb_hnd_keys, METH_VARARGS },
537 { "has_key", (PyCFunction)py_tdb_hnd_has_key, METH_VARARGS },
538 { "first_key", (PyCFunction)py_tdb_hnd_first_key, METH_VARARGS },
539 { "next_key", (PyCFunction)py_tdb_hnd_next_key, METH_VARARGS },
540 { "lock_all", (PyCFunction)py_tdb_hnd_lock_all, METH_VARARGS },
541 { "unlock_all", (PyCFunction)py_tdb_hnd_unlock_all, METH_VARARGS },
542 { "traverse", (PyCFunction)py_tdb_hnd_traverse, METH_VARARGS | METH_KEYWORDS },
543 { "chainlock", (PyCFunction)py_tdb_hnd_chainlock, METH_VARARGS | METH_KEYWORDS },
544 { "chainunlock", (PyCFunction)py_tdb_hnd_chainunlock, METH_VARARGS | METH_KEYWORDS },
545 { "lock_bystring", (PyCFunction)py_tdb_hnd_lock_bystring, METH_VARARGS | METH_KEYWORDS },
546 { "unlock_bystring", (PyCFunction)py_tdb_hnd_unlock_bystring, METH_VARARGS | METH_KEYWORDS },
547 { NULL }
550 /* Deallocate a tdb handle object */
552 static void tdb_hnd_dealloc(PyObject* self)
554 tdb_hnd_object *hnd = (tdb_hnd_object *)self;
556 if (hnd->tdb) {
557 tdb_close(hnd->tdb);
558 hnd->tdb = NULL;
562 /* Return tdb handle attributes */
564 static PyObject *tdb_hnd_getattr(PyObject *self, char *attrname)
566 return Py_FindMethod(tdb_hnd_methods, self, attrname);
569 static char tdb_hnd_type_doc[] =
570 "Python wrapper for tdb.";
572 PyTypeObject tdb_hnd_type = {
573 PyObject_HEAD_INIT(NULL)
575 "tdb",
576 sizeof(tdb_hnd_object),
578 tdb_hnd_dealloc, /* tp_dealloc*/
579 0, /* tp_print*/
580 tdb_hnd_getattr, /* tp_getattr*/
581 0, /* tp_setattr*/
582 0, /* tp_compare*/
583 0, /* tp_repr*/
584 0, /* tp_as_number*/
585 0, /* tp_as_sequence*/
586 &tdb_mapping, /* tp_as_mapping*/
587 0, /* tp_hash */
588 0, /* tp_call */
589 0, /* tp_str */
590 0, /* tp_getattro */
591 0, /* tp_setattro */
592 0, /* tp_as_buffer*/
593 Py_TPFLAGS_DEFAULT, /* tp_flags */
594 tdb_hnd_type_doc, /* tp_doc */
597 /* Constants */
599 static struct const_vals {
600 char *name;
601 uint32 value;
602 } module_const_vals[] = {
604 /* Flags for tdb_open() */
606 { "TDB_DEFAULT", TDB_DEFAULT },
607 { "TDB_CLEAR_IF_FIRST", TDB_CLEAR_IF_FIRST },
608 { "TDB_INTERNAL", TDB_INTERNAL },
609 { "TDB_NOLOCK", TDB_NOLOCK },
610 { "TDB_NOMMAP", TDB_NOMMAP },
611 { "TDB_CONVERT", TDB_CONVERT },
612 { "TDB_BIGENDIAN", TDB_BIGENDIAN },
614 { NULL },
617 static void const_init(PyObject *dict)
619 struct const_vals *tmp;
620 PyObject *obj;
622 for (tmp = module_const_vals; tmp->name; tmp++) {
623 obj = PyInt_FromLong(tmp->value);
624 PyDict_SetItemString(dict, tmp->name, obj);
625 Py_DECREF(obj);
629 /* Module initialisation */
631 void inittdb(void)
633 PyObject *module, *dict;
635 /* Initialise module */
637 module = Py_InitModule("tdb", tdb_methods);
638 dict = PyModule_GetDict(module);
640 py_tdb_error = PyErr_NewException("tdb.error", NULL, NULL);
641 PyDict_SetItemString(dict, "error", py_tdb_error);
643 /* Initialise policy handle object */
645 tdb_hnd_type.ob_type = &PyType_Type;
647 PyDict_SetItemString(dict, "tdb.hnd",
648 (PyObject *)&tdb_hnd_type);
650 /* Initialise constants */
652 const_init(dict);