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