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