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