On a second thought, rename rpmfiDigest() to rpmfiFDigest() for consistency
[platform/upstream/rpm.git] / python / rpmfi-py.c
1 /** \ingroup py_c
2  * \file python/rpmfi-py.c
3  */
4
5 #include "system.h"
6
7 #include <rpm/rpmtypes.h>
8 #include <rpm/rpmpgp.h>
9
10 #include "header-py.h"
11 #include "rpmfi-py.h"
12
13 #include "debug.h"
14
15
16 static PyObject *
17 rpmfi_Debug(rpmfiObject * s, PyObject * args, PyObject * kwds)
18 {
19     char * kwlist[] = {"debugLevel", NULL};
20
21     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &_rpmfi_debug))
22         return NULL;
23
24     Py_INCREF(Py_None);
25     return Py_None;
26 }
27
28 static PyObject *
29 rpmfi_FC(rpmfiObject * s)
30 {
31     return Py_BuildValue("i", rpmfiFC(s->fi));
32 }
33
34 static PyObject *
35 rpmfi_FX(rpmfiObject * s)
36 {
37     return Py_BuildValue("i", rpmfiFX(s->fi));
38 }
39
40 static PyObject *
41 rpmfi_DC(rpmfiObject * s)
42 {
43     return Py_BuildValue("i", rpmfiDC(s->fi));
44 }
45
46 static PyObject *
47 rpmfi_DX(rpmfiObject * s)
48 {
49     return Py_BuildValue("i", rpmfiDX(s->fi));
50 }
51
52 static PyObject *
53 rpmfi_BN(rpmfiObject * s)
54 {
55     return Py_BuildValue("s", xstrdup(rpmfiBN(s->fi)));
56 }
57
58 static PyObject *
59 rpmfi_DN(rpmfiObject * s)
60 {
61     return Py_BuildValue("s", xstrdup(rpmfiDN(s->fi)));
62 }
63
64 static PyObject *
65 rpmfi_FN(rpmfiObject * s)
66 {
67     return Py_BuildValue("s", xstrdup(rpmfiFN(s->fi)));
68 }
69
70 static PyObject *
71 rpmfi_FFlags(rpmfiObject * s)
72 {
73     return Py_BuildValue("i", rpmfiFFlags(s->fi));
74 }
75
76 static PyObject *
77 rpmfi_VFlags(rpmfiObject * s)
78 {
79     return Py_BuildValue("i", rpmfiVFlags(s->fi));
80 }
81
82 static PyObject *
83 rpmfi_FMode(rpmfiObject * s)
84 {
85     return Py_BuildValue("i", rpmfiFMode(s->fi));
86 }
87
88 static PyObject *
89 rpmfi_FState(rpmfiObject * s)
90 {
91     return Py_BuildValue("i", rpmfiFState(s->fi));
92 }
93
94 /* XXX rpmfiFDigest */
95 static PyObject *
96 rpmfi_Digest(rpmfiObject * s)
97 {
98     const unsigned char *digest;
99     size_t diglen = 0;
100
101     digest = rpmfiFDigest(s->fi, NULL, &diglen);
102     if (digest) {
103         char *dig = pgpHexStr(digest, diglen);
104         return Py_BuildValue("s", dig);
105     } else {
106         Py_RETURN_NONE;
107     }
108 }
109
110 static PyObject *
111 rpmfi_FLink(rpmfiObject * s)
112 {
113     return Py_BuildValue("s", xstrdup(rpmfiFLink(s->fi)));
114 }
115
116 static PyObject *
117 rpmfi_FSize(rpmfiObject * s)
118 {
119     return Py_BuildValue("i", rpmfiFSize(s->fi));
120 }
121
122 static PyObject *
123 rpmfi_FRdev(rpmfiObject * s)
124 {
125     return Py_BuildValue("i", rpmfiFRdev(s->fi));
126 }
127
128 static PyObject *
129 rpmfi_FMtime(rpmfiObject * s)
130 {
131     return Py_BuildValue("i", rpmfiFMtime(s->fi));
132 }
133
134 static PyObject *
135 rpmfi_FUser(rpmfiObject * s)
136 {
137     return Py_BuildValue("s", xstrdup(rpmfiFUser(s->fi)));
138 }
139
140 static PyObject *
141 rpmfi_FGroup(rpmfiObject * s)
142 {
143     return Py_BuildValue("s", xstrdup(rpmfiFGroup(s->fi)));
144 }
145
146 static PyObject *
147 rpmfi_FColor(rpmfiObject * s)
148 {
149     return Py_BuildValue("i", rpmfiFColor(s->fi));
150 }
151
152 static PyObject *
153 rpmfi_FClass(rpmfiObject * s)
154 {
155     const char * FClass;
156
157     if ((FClass = rpmfiFClass(s->fi)) == NULL)
158         FClass = "";
159     return Py_BuildValue("s", xstrdup(FClass));
160 }
161
162 #if Py_TPFLAGS_HAVE_ITER
163 static PyObject *
164 rpmfi_iter(rpmfiObject * s)
165 {
166     Py_INCREF(s);
167     return (PyObject *)s;
168 }
169 #endif
170
171 static PyObject *
172 rpmfi_iternext(rpmfiObject * s)
173 {
174     PyObject * result = NULL;
175
176     /* Reset loop indices on 1st entry. */
177     if (!s->active) {
178         s->fi = rpmfiInit(s->fi, 0);
179         s->active = 1;
180     }
181
182     /* If more to do, return the file tuple. */
183     if (rpmfiNext(s->fi) >= 0) {
184         const char * FN = rpmfiFN(s->fi);
185         int FSize = rpmfiFSize(s->fi);
186         int FMode = rpmfiFMode(s->fi);
187         int FMtime = rpmfiFMtime(s->fi);
188         int FFlags = rpmfiFFlags(s->fi);
189         int FRdev = rpmfiFRdev(s->fi);
190         int FInode = rpmfiFInode(s->fi);
191         int FNlink = rpmfiFNlink(s->fi);
192         int FState = rpmfiFState(s->fi);
193         int VFlags = rpmfiVFlags(s->fi);
194         const char * FUser = rpmfiFUser(s->fi);
195         const char * FGroup = rpmfiFGroup(s->fi);
196
197         result = PyTuple_New(13);
198         if (FN == NULL) {
199             Py_INCREF(Py_None);
200             PyTuple_SET_ITEM(result, 0, Py_None);
201         } else
202             PyTuple_SET_ITEM(result,  0, Py_BuildValue("s", FN));
203         PyTuple_SET_ITEM(result,  1, PyInt_FromLong(FSize));
204         PyTuple_SET_ITEM(result,  2, PyInt_FromLong(FMode));
205         PyTuple_SET_ITEM(result,  3, PyInt_FromLong(FMtime));
206         PyTuple_SET_ITEM(result,  4, PyInt_FromLong(FFlags));
207         PyTuple_SET_ITEM(result,  5, PyInt_FromLong(FRdev));
208         PyTuple_SET_ITEM(result,  6, PyInt_FromLong(FInode));
209         PyTuple_SET_ITEM(result,  7, PyInt_FromLong(FNlink));
210         PyTuple_SET_ITEM(result,  8, PyInt_FromLong(FState));
211         PyTuple_SET_ITEM(result,  9, PyInt_FromLong(VFlags));
212         if (FUser == NULL) {
213             Py_INCREF(Py_None);
214             PyTuple_SET_ITEM(result, 10, Py_None);
215         } else
216             PyTuple_SET_ITEM(result, 10, Py_BuildValue("s", FUser));
217         if (FGroup == NULL) {
218             Py_INCREF(Py_None);
219             PyTuple_SET_ITEM(result, 11, Py_None);
220         } else
221             PyTuple_SET_ITEM(result, 11, Py_BuildValue("s", FGroup));
222         PyTuple_SET_ITEM(result, 12, rpmfi_Digest(s));
223
224     } else
225         s->active = 0;
226
227     return result;
228 }
229
230 static PyObject *
231 rpmfi_Next(rpmfiObject * s)
232 {
233     PyObject * result = NULL;
234
235     result = rpmfi_iternext(s);
236
237     if (result == NULL) {
238         Py_INCREF(Py_None);
239         return Py_None;
240     }
241
242     return result;
243 }
244
245 #ifdef  NOTYET
246 static PyObject *
247 rpmfi_NextD(rpmfiObject * s)
248 {
249         Py_INCREF(Py_None);
250         return Py_None;
251 }
252
253 static PyObject *
254 rpmfi_InitD(rpmfiObject * s)
255 {
256         Py_INCREF(Py_None);
257         return Py_None;
258 }
259 #endif
260
261 static struct PyMethodDef rpmfi_methods[] = {
262  {"Debug",      (PyCFunction)rpmfi_Debug,       METH_VARARGS|METH_KEYWORDS,
263         NULL},
264  {"FC",         (PyCFunction)rpmfi_FC,          METH_NOARGS,
265         NULL},
266  {"FX",         (PyCFunction)rpmfi_FX,          METH_NOARGS,
267         NULL},
268  {"DC",         (PyCFunction)rpmfi_DC,          METH_NOARGS,
269         NULL},
270  {"DX",         (PyCFunction)rpmfi_DX,          METH_NOARGS,
271         NULL},
272  {"BN",         (PyCFunction)rpmfi_BN,          METH_NOARGS,
273         NULL},
274  {"DN",         (PyCFunction)rpmfi_DN,          METH_NOARGS,
275         NULL},
276  {"FN",         (PyCFunction)rpmfi_FN,          METH_NOARGS,
277         NULL},
278  {"FFlags",     (PyCFunction)rpmfi_FFlags,      METH_NOARGS,
279         NULL},
280  {"VFlags",     (PyCFunction)rpmfi_VFlags,      METH_NOARGS,
281         NULL},
282  {"FMode",      (PyCFunction)rpmfi_FMode,       METH_NOARGS,
283         NULL},
284  {"FState",     (PyCFunction)rpmfi_FState,      METH_NOARGS,
285         NULL},
286  {"MD5",        (PyCFunction)rpmfi_Digest,      METH_NOARGS,
287         NULL},
288  {"Digest",     (PyCFunction)rpmfi_Digest,      METH_NOARGS,
289         NULL},
290  {"FLink",      (PyCFunction)rpmfi_FLink,       METH_NOARGS,
291         NULL},
292  {"FSize",      (PyCFunction)rpmfi_FSize,       METH_NOARGS,
293         NULL},
294  {"FRdev",      (PyCFunction)rpmfi_FRdev,       METH_NOARGS,
295         NULL},
296  {"FMtime",     (PyCFunction)rpmfi_FMtime,      METH_NOARGS,
297         NULL},
298  {"FUser",      (PyCFunction)rpmfi_FUser,       METH_NOARGS,
299         NULL},
300  {"FGroup",     (PyCFunction)rpmfi_FGroup,      METH_NOARGS,
301         NULL},
302  {"FColor",     (PyCFunction)rpmfi_FColor,      METH_NOARGS,
303         NULL},
304  {"FClass",     (PyCFunction)rpmfi_FClass,      METH_NOARGS,
305         NULL},
306  {"next",       (PyCFunction)rpmfi_Next,        METH_NOARGS,
307 "fi.next() -> (FN, FSize, FMode, FMtime, FFlags, FRdev, FInode, FNlink, FState, VFlags, FUser, FGroup, FDigest))\n\
308 - Retrieve next file info tuple.\n" },
309 #ifdef  NOTYET
310  {"NextD",      (PyCFunction)rpmfi_NextD,       METH_NOARGS,
311         NULL},
312  {"InitD",      (PyCFunction)rpmfi_InitD,       METH_NOARGS,
313         NULL},
314 #endif
315  {NULL,         NULL}           /* sentinel */
316 };
317
318 /* ---------- */
319
320 static void
321 rpmfi_dealloc(rpmfiObject * s)
322 {
323     if (s) {
324         s->fi = rpmfiFree(s->fi);
325         PyObject_Del(s);
326     }
327 }
328
329 static int
330 rpmfi_print(rpmfiObject * s, FILE * fp, int flags)
331 {
332     if (!(s && s->fi))
333         return -1;
334
335     s->fi = rpmfiInit(s->fi, 0);
336     while (rpmfiNext(s->fi) >= 0)
337         fprintf(fp, "%s\n", rpmfiFN(s->fi));
338     return 0;
339 }
340
341 static PyObject * rpmfi_getattro(PyObject * o, PyObject * n)
342 {
343     return PyObject_GenericGetAttr(o, n);
344 }
345
346 static int rpmfi_setattro(PyObject * o, PyObject * n, PyObject * v)
347 {
348     return PyObject_GenericSetAttr(o, n, v);
349 }
350
351 static int
352 rpmfi_length(rpmfiObject * s)
353 {
354     return rpmfiFC(s->fi);
355 }
356
357 static PyObject *
358 rpmfi_subscript(rpmfiObject * s, PyObject * key)
359 {
360     int ix;
361
362     if (!PyInt_Check(key)) {
363         PyErr_SetString(PyExc_TypeError, "integer expected");
364         return NULL;
365     }
366
367     ix = (int) PyInt_AsLong(key);
368     rpmfiSetFX(s->fi, ix);
369     return Py_BuildValue("s", xstrdup(rpmfiFN(s->fi)));
370 }
371
372 static PyMappingMethods rpmfi_as_mapping = {
373         (lenfunc) rpmfi_length,         /* mp_length */
374         (binaryfunc) rpmfi_subscript,   /* mp_subscript */
375         (objobjargproc)0,               /* mp_ass_subscript */
376 };
377
378 /** \ingroup py_c
379  */
380 static int rpmfi_init(rpmfiObject * s, PyObject *args, PyObject *kwds)
381 {
382     hdrObject * ho = NULL;
383     PyObject * to = NULL;
384     rpmts ts = NULL;    /* XXX FIXME: fiFromHeader should be a ts method. */
385     rpmTag tagN = RPMTAG_BASENAMES;
386     int flags = 0;
387     char * kwlist[] = {"header", "tag", "flags", NULL};
388
389 if (_rpmfi_debug < 0)
390 fprintf(stderr, "*** rpmfi_init(%p,%p,%p)\n", s, args, kwds);
391
392     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|Oi:rpmfi_init", kwlist,
393             &hdr_Type, &ho, &to, &flags))
394         return -1;
395
396     if (to != NULL) {
397         tagN = tagNumFromPyObject(to);
398         if (tagN == -1) {
399             PyErr_SetString(PyExc_KeyError, "unknown header tag");
400             return -1;
401         }
402     }
403     s->fi = rpmfiNew(ts, hdrGetHeader(ho), tagN, flags);
404     s->active = 0;
405
406     return 0;
407 }
408
409 /** \ingroup py_c
410  */
411 static void rpmfi_free(rpmfiObject * s)
412 {
413 if (_rpmfi_debug)
414 fprintf(stderr, "%p -- fi %p\n", s, s->fi);
415     s->fi = rpmfiFree(s->fi);
416
417     PyObject_Del((PyObject *)s);
418 }
419
420 /** \ingroup py_c
421  */
422 static PyObject * rpmfi_alloc(PyTypeObject * subtype, int nitems)
423 {
424     PyObject * s = PyType_GenericAlloc(subtype, nitems);
425
426 if (_rpmfi_debug < 0)
427 fprintf(stderr, "*** rpmfi_alloc(%p,%d) ret %p\n", subtype, nitems, s);
428     return s;
429 }
430
431 /** \ingroup py_c
432  */
433 static PyObject * rpmfi_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
434 {
435     rpmfiObject * s = (void *) PyObject_New(rpmfiObject, subtype);
436
437     /* Perform additional initialization. */
438     if (rpmfi_init(s, args, kwds) < 0) {
439         rpmfi_free(s);
440         return NULL;
441     }
442
443 if (_rpmfi_debug)
444 fprintf(stderr, "%p ++ fi %p\n", s, s->fi);
445
446     return (PyObject *)s;
447 }
448
449 /**
450  */
451 static char rpmfi_doc[] =
452 "";
453
454 PyTypeObject rpmfi_Type = {
455         PyObject_HEAD_INIT(&PyType_Type)
456         0,                              /* ob_size */
457         "rpm.fi",                       /* tp_name */
458         sizeof(rpmfiObject),            /* tp_basicsize */
459         0,                              /* tp_itemsize */
460         /* methods */
461         (destructor) rpmfi_dealloc,     /* tp_dealloc */
462         (printfunc) rpmfi_print,        /* tp_print */
463         (getattrfunc)0,                 /* tp_getattr */
464         (setattrfunc)0,                 /* tp_setattr */
465         (cmpfunc)0,                     /* tp_compare */
466         (reprfunc)0,                    /* tp_repr */
467         0,                              /* tp_as_number */
468         0,                              /* tp_as_sequence */
469         &rpmfi_as_mapping,              /* tp_as_mapping */
470         (hashfunc)0,                    /* tp_hash */
471         (ternaryfunc)0,                 /* tp_call */
472         (reprfunc)0,                    /* tp_str */
473         (getattrofunc) rpmfi_getattro,  /* tp_getattro */
474         (setattrofunc) rpmfi_setattro,  /* tp_setattro */
475         0,                              /* tp_as_buffer */
476         Py_TPFLAGS_DEFAULT,             /* tp_flags */
477         rpmfi_doc,                      /* tp_doc */
478 #if Py_TPFLAGS_HAVE_ITER
479         0,                              /* tp_traverse */
480         0,                              /* tp_clear */
481         0,                              /* tp_richcompare */
482         0,                              /* tp_weaklistoffset */
483         (getiterfunc) rpmfi_iter,       /* tp_iter */
484         (iternextfunc) rpmfi_iternext,  /* tp_iternext */
485         rpmfi_methods,                  /* tp_methods */
486         0,                              /* tp_members */
487         0,                              /* tp_getset */
488         0,                              /* tp_base */
489         0,                              /* tp_dict */
490         0,                              /* tp_descr_get */
491         0,                              /* tp_descr_set */
492         0,                              /* tp_dictoffset */
493         (initproc) rpmfi_init,          /* tp_init */
494         (allocfunc) rpmfi_alloc,        /* tp_alloc */
495         (newfunc) rpmfi_new,            /* tp_new */
496         (freefunc) rpmfi_free,          /* tp_free */
497         0,                              /* tp_is_gc */
498 #endif
499 };
500
501 /* ---------- */
502
503 rpmfi fiFromFi(rpmfiObject * s)
504 {
505     return s->fi;
506 }
507
508 rpmfiObject *
509 rpmfi_Wrap(rpmfi fi)
510 {
511     rpmfiObject *s = PyObject_New(rpmfiObject, &rpmfi_Type);
512
513     if (s == NULL)
514         return NULL;
515     s->fi = fi;
516     s->active = 0;
517     return s;
518 }
519
520 rpmfiObject *
521 hdr_fiFromHeader(PyObject * s, PyObject * args, PyObject * kwds)
522 {
523     hdrObject * ho = (hdrObject *)s;
524     PyObject * to = NULL;
525     rpmts ts = NULL;    /* XXX FIXME: fiFromHeader should be a ts method. */
526     rpmTag tagN = RPMTAG_BASENAMES;
527     int flags = 0;
528     char * kwlist[] = {"tag", "flags", NULL};
529
530     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:fiFromHeader", kwlist,
531             &to, &flags))
532         return NULL;
533
534     if (to != NULL) {
535         tagN = tagNumFromPyObject(to);
536         if (tagN == -1) {
537             PyErr_SetString(PyExc_KeyError, "unknown header tag");
538             return NULL;
539         }
540     }
541     return rpmfi_Wrap( rpmfiNew(ts, hdrGetHeader(ho), tagN, flags) );
542 }