1 | /*
|
---|
2 | Python wrappers for TDB module
|
---|
3 |
|
---|
4 | Copyright (C) Tim Potter, 2002-2003
|
---|
5 |
|
---|
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
|
---|
9 |
|
---|
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.
|
---|
14 |
|
---|
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.
|
---|
19 |
|
---|
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
|
---|
23 | */
|
---|
24 |
|
---|
25 | #include "includes.h"
|
---|
26 |
|
---|
27 | /* This symbol is used in both includes.h and Python.h which causes an
|
---|
28 | annoying compiler warning. */
|
---|
29 |
|
---|
30 | #ifdef HAVE_FSTAT
|
---|
31 | #undef HAVE_FSTAT
|
---|
32 | #endif
|
---|
33 |
|
---|
34 | #include "Python.h"
|
---|
35 |
|
---|
36 | /* Tdb exception */
|
---|
37 |
|
---|
38 | PyObject *py_tdb_error;
|
---|
39 |
|
---|
40 | /* tdb handle object */
|
---|
41 |
|
---|
42 | typedef struct {
|
---|
43 | PyObject_HEAD
|
---|
44 | TDB_CONTEXT *tdb;
|
---|
45 | } tdb_hnd_object;
|
---|
46 |
|
---|
47 | PyTypeObject tdb_hnd_type;
|
---|
48 |
|
---|
49 | PyObject *new_tdb_hnd_object(TDB_CONTEXT *tdb)
|
---|
50 | {
|
---|
51 | tdb_hnd_object *obj;
|
---|
52 |
|
---|
53 | obj = PyObject_New(tdb_hnd_object, &tdb_hnd_type);
|
---|
54 | obj->tdb = tdb;
|
---|
55 |
|
---|
56 | return (PyObject *)obj;
|
---|
57 | }
|
---|
58 |
|
---|
59 | PyObject *py_tdb_close(PyObject *self, PyObject *args)
|
---|
60 | {
|
---|
61 | tdb_hnd_object *obj;
|
---|
62 |
|
---|
63 | if (!PyArg_ParseTuple(args, "O!", &tdb_hnd_type, &obj))
|
---|
64 | return NULL;
|
---|
65 |
|
---|
66 | if (tdb_close(obj->tdb) == -1) {
|
---|
67 | obj->tdb = NULL;
|
---|
68 | PyErr_SetString(py_tdb_error, strerror(errno));
|
---|
69 | return NULL;
|
---|
70 | }
|
---|
71 |
|
---|
72 | obj->tdb = NULL;
|
---|
73 |
|
---|
74 | Py_INCREF(Py_None);
|
---|
75 | return Py_None;
|
---|
76 | }
|
---|
77 |
|
---|
78 | PyObject *py_tdb_open(PyObject *self, PyObject *args, PyObject *kw)
|
---|
79 | {
|
---|
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;
|
---|
85 |
|
---|
86 | if (!PyArg_ParseTupleAndKeywords(
|
---|
87 | args, kw, "s|iiii", kwlist, &name, &hash_size, &flags,
|
---|
88 | &open_flags, &open_mode))
|
---|
89 | return NULL;
|
---|
90 |
|
---|
91 | /* Default open_flags to read/write */
|
---|
92 |
|
---|
93 | if (open_flags == -1) {
|
---|
94 | if (access(name, W_OK) == -1)
|
---|
95 | open_flags = O_RDONLY;
|
---|
96 | else
|
---|
97 | open_flags = O_RDWR;
|
---|
98 | }
|
---|
99 |
|
---|
100 | if (!(tdb = tdb_open(name, hash_size, flags, open_flags, open_mode))) {
|
---|
101 | PyErr_SetString(py_tdb_error, strerror(errno));
|
---|
102 | return NULL;
|
---|
103 | }
|
---|
104 |
|
---|
105 | return new_tdb_hnd_object(tdb);
|
---|
106 | }
|
---|
107 |
|
---|
108 | /*
|
---|
109 | * Allow a tdb to act as a python mapping (dictionary)
|
---|
110 | */
|
---|
111 |
|
---|
112 | static int tdb_traverse_count(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA value,
|
---|
113 | void *state)
|
---|
114 | {
|
---|
115 | /* Do nothing - tdb_traverse will return the number of records
|
---|
116 | traversed. */
|
---|
117 |
|
---|
118 | return 0;
|
---|
119 | }
|
---|
120 |
|
---|
121 | static int tdb_hnd_length(tdb_hnd_object *obj)
|
---|
122 | {
|
---|
123 | int result;
|
---|
124 |
|
---|
125 | result = tdb_traverse(obj->tdb, tdb_traverse_count, NULL);
|
---|
126 |
|
---|
127 | return result;
|
---|
128 | }
|
---|
129 |
|
---|
130 | static PyObject *tdb_hnd_subscript(tdb_hnd_object *obj, PyObject *key)
|
---|
131 | {
|
---|
132 | TDB_DATA drec, krec;
|
---|
133 | PyObject *result;
|
---|
134 |
|
---|
135 | if (!PyArg_Parse(key, "s#", &krec.dptr, &krec.dsize))
|
---|
136 | return NULL;
|
---|
137 |
|
---|
138 | drec = tdb_fetch(obj->tdb, krec);
|
---|
139 |
|
---|
140 | if (!drec.dptr) {
|
---|
141 | PyErr_SetString(PyExc_KeyError,
|
---|
142 | PyString_AsString(key));
|
---|
143 | return NULL;
|
---|
144 | }
|
---|
145 |
|
---|
146 | result = PyString_FromStringAndSize(drec.dptr, drec.dsize);
|
---|
147 | free(drec.dptr);
|
---|
148 |
|
---|
149 | return result;
|
---|
150 | }
|
---|
151 |
|
---|
152 | static int tdb_ass_subscript(tdb_hnd_object *obj, PyObject *key, PyObject *value)
|
---|
153 | {
|
---|
154 | TDB_DATA krec, drec;
|
---|
155 |
|
---|
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;
|
---|
160 | }
|
---|
161 |
|
---|
162 | if (!obj->tdb) {
|
---|
163 | PyErr_SetString(
|
---|
164 | py_tdb_error, "tdb object has been closed");
|
---|
165 | return -1;
|
---|
166 | }
|
---|
167 |
|
---|
168 | if (!value) {
|
---|
169 |
|
---|
170 | /* Delete value */
|
---|
171 |
|
---|
172 | if (tdb_delete(obj->tdb, krec) == -1) {
|
---|
173 | PyErr_SetString(PyExc_KeyError,
|
---|
174 | PyString_AsString(value));
|
---|
175 | return -1;
|
---|
176 | }
|
---|
177 |
|
---|
178 | } else {
|
---|
179 |
|
---|
180 | /* Set value */
|
---|
181 |
|
---|
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;
|
---|
186 | }
|
---|
187 |
|
---|
188 | errno = 0;
|
---|
189 |
|
---|
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));
|
---|
197 |
|
---|
198 | return -1;
|
---|
199 | }
|
---|
200 | }
|
---|
201 |
|
---|
202 | return 0;
|
---|
203 | }
|
---|
204 |
|
---|
205 | static PyMappingMethods tdb_mapping = {
|
---|
206 | (inquiry) tdb_hnd_length,
|
---|
207 | (binaryfunc) tdb_hnd_subscript,
|
---|
208 | (objobjargproc) tdb_ass_subscript
|
---|
209 | };
|
---|
210 |
|
---|
211 | /*
|
---|
212 | * Utility methods
|
---|
213 | */
|
---|
214 |
|
---|
215 | /* Return non-zero if a given key exists in the tdb */
|
---|
216 |
|
---|
217 | PyObject *py_tdb_hnd_has_key(PyObject *self, PyObject *args)
|
---|
218 | {
|
---|
219 | tdb_hnd_object *obj = (tdb_hnd_object *)self;
|
---|
220 | TDB_DATA key;
|
---|
221 |
|
---|
222 | if (!PyArg_ParseTuple(args, "s#", &key.dptr, &key.dsize))
|
---|
223 | return NULL;
|
---|
224 |
|
---|
225 | if (!obj->tdb) {
|
---|
226 | PyErr_SetString(
|
---|
227 | py_tdb_error, "tdb object has been closed");
|
---|
228 | return NULL;
|
---|
229 | }
|
---|
230 |
|
---|
231 | return PyInt_FromLong(tdb_exists(obj->tdb, key));
|
---|
232 | }
|
---|
233 |
|
---|
234 | /* Return a list of keys in the tdb */
|
---|
235 |
|
---|
236 | static int tdb_traverse_keys(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA value,
|
---|
237 | void *state)
|
---|
238 | {
|
---|
239 | PyObject *key_list = (PyObject *)state;
|
---|
240 |
|
---|
241 | PyList_Append(key_list,
|
---|
242 | PyString_FromStringAndSize(key.dptr, key.dsize));
|
---|
243 |
|
---|
244 | return 0;
|
---|
245 | }
|
---|
246 |
|
---|
247 | PyObject *py_tdb_hnd_keys(PyObject *self, PyObject *args)
|
---|
248 | {
|
---|
249 | tdb_hnd_object *obj = (tdb_hnd_object *)self;
|
---|
250 | PyObject *key_list = PyList_New(0);
|
---|
251 |
|
---|
252 | if (!obj->tdb) {
|
---|
253 | PyErr_SetString(py_tdb_error, "tdb object has been closed");
|
---|
254 | return NULL;
|
---|
255 | }
|
---|
256 |
|
---|
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;
|
---|
261 | }
|
---|
262 |
|
---|
263 | return key_list;
|
---|
264 | }
|
---|
265 |
|
---|
266 | PyObject *py_tdb_hnd_first_key(PyObject *self, PyObject *args)
|
---|
267 | {
|
---|
268 | tdb_hnd_object *obj = (tdb_hnd_object *)self;
|
---|
269 | TDB_DATA key;
|
---|
270 |
|
---|
271 | if (!obj->tdb) {
|
---|
272 | PyErr_SetString(py_tdb_error, "tdb object has been closed");
|
---|
273 | return NULL;
|
---|
274 | }
|
---|
275 |
|
---|
276 | key = tdb_firstkey(obj->tdb);
|
---|
277 |
|
---|
278 | return Py_BuildValue("s#", key.dptr, key.dsize);
|
---|
279 | }
|
---|
280 |
|
---|
281 | PyObject *py_tdb_hnd_next_key(PyObject *self, PyObject *py_oldkey)
|
---|
282 | {
|
---|
283 | tdb_hnd_object *obj = (tdb_hnd_object *)self;
|
---|
284 | TDB_DATA key, oldkey;
|
---|
285 |
|
---|
286 | if (!obj->tdb) {
|
---|
287 | PyErr_SetString(py_tdb_error, "tdb object has been closed");
|
---|
288 | return NULL;
|
---|
289 | }
|
---|
290 |
|
---|
291 | if (!PyArg_Parse(py_oldkey, "s#", &oldkey.dptr, &oldkey.dsize))
|
---|
292 | return NULL;
|
---|
293 |
|
---|
294 | key = tdb_nextkey(obj->tdb, oldkey);
|
---|
295 |
|
---|
296 | return Py_BuildValue("s#", key.dptr, key.dsize);
|
---|
297 | }
|
---|
298 |
|
---|
299 | /*
|
---|
300 | * Locking routines
|
---|
301 | */
|
---|
302 |
|
---|
303 | PyObject *py_tdb_hnd_lock_all(PyObject *self, PyObject *args)
|
---|
304 | {
|
---|
305 | tdb_hnd_object *obj = (tdb_hnd_object *)self;
|
---|
306 | int result;
|
---|
307 |
|
---|
308 | if (!obj->tdb) {
|
---|
309 | PyErr_SetString(py_tdb_error, "tdb object has been closed");
|
---|
310 | return NULL;
|
---|
311 | }
|
---|
312 |
|
---|
313 | result = tdb_lockall(obj->tdb);
|
---|
314 |
|
---|
315 | return PyInt_FromLong(result != -1);
|
---|
316 | }
|
---|
317 |
|
---|
318 | PyObject *py_tdb_hnd_unlock_all(PyObject *self, PyObject *args)
|
---|
319 | {
|
---|
320 | tdb_hnd_object *obj = (tdb_hnd_object *)self;
|
---|
321 |
|
---|
322 | if (!obj->tdb) {
|
---|
323 | PyErr_SetString(py_tdb_error, "tdb object has been closed");
|
---|
324 | return NULL;
|
---|
325 | }
|
---|
326 |
|
---|
327 | tdb_unlockall(obj->tdb);
|
---|
328 |
|
---|
329 | Py_INCREF(Py_None);
|
---|
330 | return Py_None;
|
---|
331 | }
|
---|
332 |
|
---|
333 | /* Return an array of keys from a python object which must be a string or a
|
---|
334 | list of strings. */
|
---|
335 |
|
---|
336 | static BOOL make_lock_list(PyObject *py_keys, TDB_DATA **keys, int *num_keys)
|
---|
337 | {
|
---|
338 | /* Are we a list or a string? */
|
---|
339 |
|
---|
340 | if (!PyList_Check(py_keys) && !PyString_Check(py_keys)) {
|
---|
341 | PyErr_SetString(PyExc_TypeError, "arg must be list of string");
|
---|
342 | return False;
|
---|
343 | }
|
---|
344 |
|
---|
345 | if (PyList_Check(py_keys)) {
|
---|
346 | int i;
|
---|
347 |
|
---|
348 | /* Turn python list into array of keys */
|
---|
349 |
|
---|
350 | *num_keys = PyList_Size(py_keys);
|
---|
351 | *keys = (TDB_DATA *)SMB_XMALLOC_ARRAY(TDB_DATA, (*num_keys));
|
---|
352 |
|
---|
353 | for (i = 0; i < *num_keys; i++) {
|
---|
354 | PyObject *key = PyList_GetItem(py_keys, i);
|
---|
355 |
|
---|
356 | if (!PyString_Check(key)) {
|
---|
357 | PyErr_SetString(
|
---|
358 | PyExc_TypeError,
|
---|
359 | "list elements must be strings");
|
---|
360 | return False;
|
---|
361 | }
|
---|
362 |
|
---|
363 | PyArg_Parse(key, "s#", &(*keys)[i].dptr,
|
---|
364 | &(*keys)[i].dsize);
|
---|
365 | }
|
---|
366 |
|
---|
367 | } else {
|
---|
368 |
|
---|
369 | /* Turn python string into a single key */
|
---|
370 |
|
---|
371 | *keys = (TDB_DATA *)SMB_XMALLOC_P(TDB_DATA);
|
---|
372 | *num_keys = 1;
|
---|
373 | PyArg_Parse(py_keys, "s#", &(*keys)->dptr, &(*keys)->dsize);
|
---|
374 | }
|
---|
375 |
|
---|
376 | return True;
|
---|
377 | }
|
---|
378 |
|
---|
379 | /*
|
---|
380 | * tdb traversal
|
---|
381 | */
|
---|
382 |
|
---|
383 | struct traverse_info {
|
---|
384 | PyObject *callback;
|
---|
385 | PyObject *state;
|
---|
386 | };
|
---|
387 |
|
---|
388 | static int tdb_traverse_traverse(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA value,
|
---|
389 | void *state)
|
---|
390 | {
|
---|
391 | struct traverse_info *info = state;
|
---|
392 | PyObject *arglist, *py_result;
|
---|
393 | int result;
|
---|
394 |
|
---|
395 | arglist = Py_BuildValue("(s#s#O)", key.dptr, key.dsize, value.dptr,
|
---|
396 | value.dsize, info->state);
|
---|
397 |
|
---|
398 | py_result = PyEval_CallObject(info->callback, arglist);
|
---|
399 |
|
---|
400 | Py_DECREF(arglist);
|
---|
401 |
|
---|
402 | if (!PyInt_Check(py_result)) {
|
---|
403 | result = 1; /* Hmm - non-integer object returned by callback */
|
---|
404 | goto done;
|
---|
405 | }
|
---|
406 |
|
---|
407 | result = PyInt_AsLong(py_result);
|
---|
408 |
|
---|
409 | done:
|
---|
410 | Py_DECREF(py_result);
|
---|
411 | return result;
|
---|
412 | }
|
---|
413 |
|
---|
414 | PyObject *py_tdb_hnd_traverse(PyObject *self, PyObject *args, PyObject *kw)
|
---|
415 | {
|
---|
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;
|
---|
421 |
|
---|
422 | if (!PyArg_ParseTupleAndKeywords(
|
---|
423 | args, kw, "O|O", kwlist, &callback, &state))
|
---|
424 | return NULL;
|
---|
425 |
|
---|
426 | if (!PyCallable_Check(callback)) {
|
---|
427 | PyErr_SetString(PyExc_TypeError, "parameter must be callable");
|
---|
428 | return NULL;
|
---|
429 | }
|
---|
430 |
|
---|
431 | Py_INCREF(callback);
|
---|
432 | Py_INCREF(state);
|
---|
433 |
|
---|
434 | info.callback = callback;
|
---|
435 | info.state = state;
|
---|
436 |
|
---|
437 | result = tdb_traverse(obj->tdb, tdb_traverse_traverse, &info);
|
---|
438 |
|
---|
439 | Py_DECREF(callback);
|
---|
440 | Py_DECREF(state);
|
---|
441 |
|
---|
442 | return PyInt_FromLong(result);
|
---|
443 | }
|
---|
444 |
|
---|
445 | PyObject *py_tdb_hnd_chainlock(PyObject *self, PyObject *args)
|
---|
446 | {
|
---|
447 | tdb_hnd_object *obj = (tdb_hnd_object *)self;
|
---|
448 | TDB_DATA key;
|
---|
449 | int result;
|
---|
450 |
|
---|
451 | if (!obj->tdb) {
|
---|
452 | PyErr_SetString(py_tdb_error, "tdb object has been closed");
|
---|
453 | return NULL;
|
---|
454 | }
|
---|
455 |
|
---|
456 | if (!PyArg_ParseTuple(args, "s#", &key.dptr, &key.dsize))
|
---|
457 | return NULL;
|
---|
458 |
|
---|
459 | result = tdb_chainlock(obj->tdb, key);
|
---|
460 |
|
---|
461 | return PyInt_FromLong(result != -1);
|
---|
462 | }
|
---|
463 |
|
---|
464 | PyObject *py_tdb_hnd_chainunlock(PyObject *self, PyObject *args)
|
---|
465 | {
|
---|
466 | tdb_hnd_object *obj = (tdb_hnd_object *)self;
|
---|
467 | TDB_DATA key;
|
---|
468 | int result;
|
---|
469 |
|
---|
470 | if (!obj->tdb) {
|
---|
471 | PyErr_SetString(py_tdb_error, "tdb object has been closed");
|
---|
472 | return NULL;
|
---|
473 | }
|
---|
474 |
|
---|
475 | if (!PyArg_ParseTuple(args, "s#", &key.dptr, &key.dsize))
|
---|
476 | return NULL;
|
---|
477 |
|
---|
478 | result = tdb_chainunlock(obj->tdb, key);
|
---|
479 |
|
---|
480 | return PyInt_FromLong(result != -1);
|
---|
481 | }
|
---|
482 |
|
---|
483 | PyObject *py_tdb_hnd_lock_bystring(PyObject *self, PyObject *args)
|
---|
484 | {
|
---|
485 | tdb_hnd_object *obj = (tdb_hnd_object *)self;
|
---|
486 | int result, timeout = 30;
|
---|
487 | char *s;
|
---|
488 |
|
---|
489 | if (!obj->tdb) {
|
---|
490 | PyErr_SetString(py_tdb_error, "tdb object has been closed");
|
---|
491 | return NULL;
|
---|
492 | }
|
---|
493 |
|
---|
494 | if (!PyArg_ParseTuple(args, "s|i", &s, &timeout))
|
---|
495 | return NULL;
|
---|
496 |
|
---|
497 | result = tdb_lock_bystring_with_timeout(obj->tdb, s, timeout);
|
---|
498 |
|
---|
499 | return PyInt_FromLong(result != -1);
|
---|
500 | }
|
---|
501 |
|
---|
502 | PyObject *py_tdb_hnd_unlock_bystring(PyObject *self, PyObject *args)
|
---|
503 | {
|
---|
504 | tdb_hnd_object *obj = (tdb_hnd_object *)self;
|
---|
505 | char *s;
|
---|
506 |
|
---|
507 | if (!obj->tdb) {
|
---|
508 | PyErr_SetString(py_tdb_error, "tdb object has been closed");
|
---|
509 | return NULL;
|
---|
510 | }
|
---|
511 |
|
---|
512 | if (!PyArg_ParseTuple(args, "s", &s))
|
---|
513 | return NULL;
|
---|
514 |
|
---|
515 | tdb_unlock_bystring(obj->tdb, s);
|
---|
516 |
|
---|
517 | Py_INCREF(Py_None);
|
---|
518 | return Py_None;
|
---|
519 | }
|
---|
520 |
|
---|
521 | /*
|
---|
522 | * Method dispatch table for this module
|
---|
523 | */
|
---|
524 |
|
---|
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 }
|
---|
529 | };
|
---|
530 |
|
---|
531 | /*
|
---|
532 | * Methods on a tdb object
|
---|
533 | */
|
---|
534 |
|
---|
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 }
|
---|
548 | };
|
---|
549 |
|
---|
550 | /* Deallocate a tdb handle object */
|
---|
551 |
|
---|
552 | static void tdb_hnd_dealloc(PyObject* self)
|
---|
553 | {
|
---|
554 | tdb_hnd_object *hnd = (tdb_hnd_object *)self;
|
---|
555 |
|
---|
556 | if (hnd->tdb) {
|
---|
557 | tdb_close(hnd->tdb);
|
---|
558 | hnd->tdb = NULL;
|
---|
559 | }
|
---|
560 | }
|
---|
561 |
|
---|
562 | /* Return tdb handle attributes */
|
---|
563 |
|
---|
564 | static PyObject *tdb_hnd_getattr(PyObject *self, char *attrname)
|
---|
565 | {
|
---|
566 | return Py_FindMethod(tdb_hnd_methods, self, attrname);
|
---|
567 | }
|
---|
568 |
|
---|
569 | static char tdb_hnd_type_doc[] =
|
---|
570 | "Python wrapper for tdb.";
|
---|
571 |
|
---|
572 | PyTypeObject tdb_hnd_type = {
|
---|
573 | PyObject_HEAD_INIT(NULL)
|
---|
574 | 0,
|
---|
575 | "tdb",
|
---|
576 | sizeof(tdb_hnd_object),
|
---|
577 | 0,
|
---|
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 */
|
---|
595 | };
|
---|
596 |
|
---|
597 | /* Constants */
|
---|
598 |
|
---|
599 | static struct const_vals {
|
---|
600 | char *name;
|
---|
601 | uint32 value;
|
---|
602 | } module_const_vals[] = {
|
---|
603 |
|
---|
604 | /* Flags for tdb_open() */
|
---|
605 |
|
---|
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 },
|
---|
613 |
|
---|
614 | { NULL },
|
---|
615 | };
|
---|
616 |
|
---|
617 | static void const_init(PyObject *dict)
|
---|
618 | {
|
---|
619 | struct const_vals *tmp;
|
---|
620 | PyObject *obj;
|
---|
621 |
|
---|
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);
|
---|
626 | }
|
---|
627 | }
|
---|
628 |
|
---|
629 | /* Module initialisation */
|
---|
630 |
|
---|
631 | void inittdb(void)
|
---|
632 | {
|
---|
633 | PyObject *module, *dict;
|
---|
634 |
|
---|
635 | /* Initialise module */
|
---|
636 |
|
---|
637 | module = Py_InitModule("tdb", tdb_methods);
|
---|
638 | dict = PyModule_GetDict(module);
|
---|
639 |
|
---|
640 | py_tdb_error = PyErr_NewException("tdb.error", NULL, NULL);
|
---|
641 | PyDict_SetItemString(dict, "error", py_tdb_error);
|
---|
642 |
|
---|
643 | /* Initialise policy handle object */
|
---|
644 |
|
---|
645 | tdb_hnd_type.ob_type = &PyType_Type;
|
---|
646 |
|
---|
647 | PyDict_SetItemString(dict, "tdb.hnd",
|
---|
648 | (PyObject *)&tdb_hnd_type);
|
---|
649 |
|
---|
650 | /* Initialise constants */
|
---|
651 |
|
---|
652 | const_init(dict);
|
---|
653 | }
|
---|