rpm  5.2.1
rpmmodule.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 
7 #include <rpmio_internal.h>
8 #include <rpmcb.h>
9 #include <rpmsq.h>
10 #include <argv.h>
11 
12 #define _RPMTAG_INTERNAL
13 #include <rpmtag.h>
14 #define _RPMEVR_INTERNAL
15 #include <rpmevr.h>
16 #include <rpmdb.h>
17 #include <rpmcli.h> /* XXX for rpmCheckSig */
18 
19 #include "legacy.h"
20 #include "misc.h"
21 
22 #include "header-py.h"
23 #include "rpmal-py.h"
24 #include "rpmds-py.h"
25 #include "rpmfd-py.h"
26 #include "rpmfts-py.h"
27 #include "rpmfi-py.h"
28 #include "rpmkeyring-py.h"
29 #include "rpmmacro-py.h"
30 #include "rpmmi-py.h"
31 #include "rpmps-py.h"
32 #include "rpmtd-py.h"
33 #include "rpmte-py.h"
34 #include "rpmts-py.h"
35 #include "spec-py.h"
36 
37 #include "debug.h"
38 
39 #ifdef __LCLINT__
40 #undef PyObject_HEAD
41 #define PyObject_HEAD int _PyObjectHead
42 #endif
43 
48 
51 PyObject * pyrpmError;
52 
53 extern sigset_t rpmsqCaught;
54 
57 static PyObject * archScore(PyObject * s, PyObject * args,
58  PyObject * kwds)
59 {
60  char * arch;
61  char * platform;
62  int score;
63  char * kwlist[] = {"arch", NULL};
64 
65  if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &arch))
66  return NULL;
67 
68 #if defined(RPM_VENDOR_WINDRIVER)
69  platform = rpmExpand(arch, "-%{_host_vendor}", "-%{_host_os}%{?_gnu}", NULL);
70 #else
71  platform = rpmExpand(arch, "-", "%{_vendor}", "-", "%{_os}", NULL);
72 #endif
73  score = rpmPlatformScore(platform, NULL, 0);
74  platform = _free(platform);
75 
76  return Py_BuildValue("i", score);
77 }
78 
81 static PyObject * platformScore(PyObject * s, PyObject * args,
82  PyObject * kwds)
83 {
84  char * platform;
85  int score;
86  char * kwlist[] = {"platform", NULL};
87 
88  if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &platform))
89  return NULL;
90 
91  score = rpmPlatformScore(platform, NULL, 0);
92 
93  return Py_BuildValue("i", score);
94 }
95 
98 static PyObject * signalsCaught(PyObject * s, PyObject * check)
99 {
100  PyObject *caught, *o;
101  Py_ssize_t llen;
102  int signum, i;
103  sigset_t newMask, oldMask;
104 
105  if (!PyList_Check(check)) {
106  PyErr_SetString(PyExc_TypeError, "list expected");
107  return NULL;
108  }
109 
110  llen = PyList_Size(check);
111  caught = PyList_New(0);
112 
113  /* block signals while checking for them */
114  (void) sigfillset(&newMask);
115  (void) sigprocmask(SIG_BLOCK, &newMask, &oldMask);
116 
117  for (i = 0; i < llen; i++) {
118  o = PyList_GetItem(check, i);
119  signum = PyInt_AsLong(o);
120  if (sigismember(&rpmsqCaught, signum)) {
121  PyList_Append(caught, o);
122  }
123  }
124  (void) sigprocmask(SIG_SETMASK, &oldMask, NULL);
125 
126  return caught;
127 }
128 
131 static PyObject * checkSignals(PyObject * s, PyObject * args)
132 {
133  if (!PyArg_ParseTuple(args, ":checkSignals")) return NULL;
135  Py_INCREF(Py_None);
136  return Py_None;
137 }
138 
141 static PyObject * setLogFile (PyObject * s, PyObject * args,
142  PyObject *kwds)
143 {
144  PyObject * fop = NULL;
145  FILE * fp = NULL;
146  char * kwlist[] = {"fileObject", NULL};
147 
148  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:logSetFile", kwlist, &fop))
149  return NULL;
150 
151  if (fop) {
152  if (!PyFile_Check(fop)) {
153  PyErr_SetString(pyrpmError, "requires file object");
154  return NULL;
155  }
156  fp = PyFile_AsFile(fop);
157  }
158 
159  (void) rpmlogSetFile(fp);
160 
161  Py_INCREF(Py_None);
162  return (PyObject *) Py_None;
163 }
164 
167 static PyObject *
168 setVerbosity (PyObject * s, PyObject * args, PyObject *kwds)
169 {
170  int level;
171  char * kwlist[] = {"level", NULL};
172 
173  if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &level))
174  return NULL;
175 
176  rpmSetVerbosity(level);
177 
178  Py_INCREF(Py_None);
179  return (PyObject *) Py_None;
180 }
181 
184 static PyObject *
185 setEpochPromote (PyObject * s, PyObject * args, PyObject * kwds)
186 {
187  char * kwlist[] = {"promote", NULL};
188 
189  if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist,
191  return NULL;
192 
193  Py_INCREF(Py_None);
194  return (PyObject *) Py_None;
195 }
196 
199 static PyObject * setStats (PyObject * s, PyObject * args,
200  PyObject * kwds)
201 {
202  char * kwlist[] = {"stats", NULL};
203 
204  if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &_rpmts_stats))
205  return NULL;
206 
207  Py_INCREF(Py_None);
208  return (PyObject *) Py_None;
209 }
214 static PyMethodDef rpmModuleMethods[] = {
215  { "TransactionSet", (PyCFunction) rpmts_Create, METH_VARARGS|METH_KEYWORDS,
216 "rpm.TransactionSet([rootDir, [db]]) -> ts\n\
217 - Create a transaction set.\n" },
218 
219  { "addMacro", (PyCFunction) rpmmacro_AddMacro, METH_VARARGS|METH_KEYWORDS,
220  NULL },
221  { "delMacro", (PyCFunction) rpmmacro_DelMacro, METH_VARARGS|METH_KEYWORDS,
222  NULL },
223  { "expandMacro", (PyCFunction)rpmmacro_ExpandMacro, METH_VARARGS|METH_KEYWORDS,
224  NULL },
225  { "getMacros", (PyCFunction) rpmmacro_GetMacros, METH_VARARGS|METH_KEYWORDS,
226  NULL },
227 
228  { "archscore", (PyCFunction) archScore, METH_VARARGS|METH_KEYWORDS,
229  NULL },
230  { "platformscore", (PyCFunction) platformScore, METH_VARARGS|METH_KEYWORDS,
231  NULL },
232 
233  { "signalsCaught", (PyCFunction) signalsCaught, METH_O,
234  NULL },
235  { "checkSignals", (PyCFunction) checkSignals, METH_VARARGS,
236  NULL },
237 
238  { "headerLoad", (PyCFunction) hdrLoad, METH_VARARGS|METH_KEYWORDS,
239  NULL },
240 
241  { "readHeaderListFromFD", (PyCFunction) rpmHeaderFromFD, METH_VARARGS|METH_KEYWORDS,
242  NULL },
243  { "readHeaderListFromFile", (PyCFunction) rpmHeaderFromFile, METH_VARARGS|METH_KEYWORDS,
244  NULL },
245  { "readHeaderFromFD", (PyCFunction) rpmSingleHeaderFromFD, METH_VARARGS|METH_KEYWORDS,
246  NULL },
247  { "writeHeaderListToFD", (PyCFunction) rpmHeaderToFD, METH_VARARGS|METH_KEYWORDS,
248  NULL },
249  { "writeHeaderListToFile", (PyCFunction) rpmHeaderToFile, METH_VARARGS|METH_KEYWORDS,
250  NULL },
251 
252  { "setLogFile", (PyCFunction) setLogFile, METH_VARARGS|METH_KEYWORDS,
253  NULL },
254 
255  { "versionCompare", (PyCFunction) versionCompare, METH_VARARGS|METH_KEYWORDS,
256  NULL },
257  { "labelCompare", (PyCFunction) labelCompare, METH_VARARGS|METH_KEYWORDS,
258  NULL },
259  { "setVerbosity", (PyCFunction) setVerbosity, METH_VARARGS|METH_KEYWORDS,
260  NULL },
261  { "setEpochPromote", (PyCFunction) setEpochPromote, METH_VARARGS|METH_KEYWORDS,
262  NULL },
263  { "setStats", (PyCFunction) setStats, METH_VARARGS|METH_KEYWORDS,
264  NULL },
265 
266  { "dsSingle", (PyCFunction) rpmds_Single, METH_VARARGS|METH_KEYWORDS,
267 "rpm.dsSingle(TagN, N, [EVR, [Flags]] -> ds\n\
268 - Create a single element dependency set.\n" },
269  { NULL }
270 } ;
271 
272 /*
273  * Force clean up of open iterators and dbs on exit.
274  */
275 static void rpm_exithook(void)
276 {
278 }
279 
280 /*
281  * Add rpm tag dictionaries to the module
282  */
283 static void addRpmTags(PyObject *module)
284 {
285  PyObject * dict = PyDict_New();
286 
287 #ifdef NOTYET
288 
289  PyObject *pyval, *pyname;
290  rpmtd names = rpmtdNew();
291  rpmTagGetNames(names, 1);
292  const char *tagname, *shortname;
293  rpmTag tagval;
294 
295  while ((tagname = rpmtdNextString(names))) {
296  shortname = tagname + strlen("RPMTAG_");
297  tagval = rpmTagGetValue(shortname);
298 
299  PyModule_AddIntConstant(module, tagname, tagval);
300  pyval = PyInt_FromLong(tagval);
301  pyname = PyString_FromString(shortname);
302  PyDict_SetItem(dict, pyval, pyname);
303  Py_DECREF(pyval);
304  Py_DECREF(pyname);
305  }
306  PyModule_AddObject(module, "tagnames", dict);
307  rpmtdFreeData(names);
308  rpmtdFree(names);
309 
310 #else
311 
312  PyObject * d = PyModule_GetDict(module);
313  PyObject * o;
314 
315  { const struct headerTagTableEntry_s * t;
316  PyObject * to;
317  for (t = rpmTagTable; t && t->name; t++) {
318  PyDict_SetItemString(d, (char *) t->name, to=PyInt_FromLong(t->val));
319  Py_DECREF(to);
320  PyDict_SetItem(dict, to, o=PyString_FromString(t->name + 7));
321  Py_DECREF(o);
322  }
323  }
324 
327  PyObject * to;
328  int extNum;
329  for (ext = exts, extNum = 0; ext != NULL && ext->type != HEADER_EXT_LAST;
330  ext = (ext->type == HEADER_EXT_MORE ? *ext->u.more : ext+1), extNum++)
331  {
332  if (ext->name == NULL || ext->type != HEADER_EXT_TAG)
333  continue;
334  PyDict_SetItemString(d, (char *) ext->name, to=PyCObject_FromVoidPtr((void *)ext, NULL));
335  Py_DECREF(to);
336  PyDict_SetItem(dict, to, o=PyString_FromString(ext->name + 7));
337  Py_DECREF(o);
338  }
339  }
340 
341  PyDict_SetItemString(d, "tagnames", dict);
342  Py_DECREF(dict);
343 
344 #endif
345 }
346 
349 static char rpm__doc__[] =
350 "";
351 
352 void init_rpm(void); /* XXX eliminate gcc warning */
355 void init_rpm(void)
356 {
357  PyObject * d, * o, * m;
358 
359 #if Py_TPFLAGS_HAVE_ITER /* XXX backport to python-1.5.2 */
360  if (PyType_Ready(&hdr_Type) < 0) return;
361  if (PyType_Ready(&rpmal_Type) < 0) return;
362  if (PyType_Ready(&rpmds_Type) < 0) return;
363  if (PyType_Ready(&rpmfd_Type) < 0) return;
364  if (PyType_Ready(&rpmfts_Type) < 0) return;
365  if (PyType_Ready(&rpmfi_Type) < 0) return;
366  if (PyType_Ready(&rpmmi_Type) < 0) return;
367  if (PyType_Ready(&rpmps_Type) < 0) return;
368 
369  if (PyType_Ready(&rpmtd_Type) < 0) return;
370  if (PyType_Ready(&rpmKeyring_Type) < 0) return;
371  if (PyType_Ready(&rpmPubkey_Type) < 0) return;
372 
373  if (PyType_Ready(&rpmte_Type) < 0) return;
374  if (PyType_Ready(&rpmts_Type) < 0) return;
375  if (PyType_Ready(&spec_Type) < 0) return;
376 #endif
377 
378  m = Py_InitModule3("_rpm", rpmModuleMethods, rpm__doc__);
379  if (m == NULL)
380  return;
381 
382  /*
383  * treat error to register rpm cleanup hook as fatal, tracebacks
384  * can and will leave stale locks around if we can't clean up
385  */
386  if (Py_AtExit(rpm_exithook) == -1)
387  return;
388 
389  rpmReadConfigFiles(NULL, NULL);
390 
391  d = PyModule_GetDict(m);
392 
393 #ifdef HACK
394  pyrpmError = PyString_FromString("_rpm.error");
395  PyDict_SetItemString(d, "error", pyrpmError);
396  Py_DECREF(pyrpmError);
397 #else
398  pyrpmError = PyErr_NewException("_rpm.error", NULL, NULL);
399  if (pyrpmError != NULL)
400  PyDict_SetItemString(d, "error", pyrpmError);
401 #endif
402 
403 #if Py_TPFLAGS_HAVE_ITER /* XXX backport to python-1.5.2 */
404  Py_INCREF(&hdr_Type);
405  PyModule_AddObject(m, "hdr", (PyObject *) &hdr_Type);
406 
407  Py_INCREF(&rpmal_Type);
408  PyModule_AddObject(m, "al", (PyObject *) &rpmal_Type);
409 
410  Py_INCREF(&rpmds_Type);
411  PyModule_AddObject(m, "ds", (PyObject *) &rpmds_Type);
412 
413  Py_INCREF(&rpmfd_Type);
414  PyModule_AddObject(m, "fd", (PyObject *) &rpmfd_Type);
415 
416  Py_INCREF(&rpmfts_Type);
417  PyModule_AddObject(m, "fts", (PyObject *) &rpmfts_Type);
418 
419  Py_INCREF(&rpmfi_Type);
420  PyModule_AddObject(m, "fi", (PyObject *) &rpmfi_Type);
421 
422  Py_INCREF(&rpmKeyring_Type);
423  PyModule_AddObject(m, "Keyring", (PyObject *) &rpmKeyring_Type);
424  Py_INCREF(&rpmPubkey_Type);
425  PyModule_AddObject(m, "Pubkey", (PyObject *) &rpmPubkey_Type);
426 
427  Py_INCREF(&rpmmi_Type);
428  PyModule_AddObject(m, "mi", (PyObject *) &rpmmi_Type);
429 
430  Py_INCREF(&rpmps_Type);
431  PyModule_AddObject(m, "ps", (PyObject *) &rpmps_Type);
432 
433  Py_INCREF(&rpmtd_Type);
434  PyModule_AddObject(m, "td", (PyObject *) &rpmtd_Type);
435 
436  Py_INCREF(&rpmte_Type);
437  PyModule_AddObject(m, "te", (PyObject *) &rpmte_Type);
438 
439  Py_INCREF(&rpmts_Type);
440  PyModule_AddObject(m, "ts", (PyObject *) &rpmts_Type);
441 
442  Py_INCREF(&spec_Type);
443  PyModule_AddObject(m, "spec", (PyObject *) &spec_Type);
444 #else
445  hdr_Type.ob_type = &PyType_Type;
446  rpmal_Type.ob_type = &PyType_Type;
447  rpmds_Type.ob_type = &PyType_Type;
448  rpmfd_Type.ob_type = &PyType_Type;
449  rpmfts_Type.ob_type = &PyType_Type;
450  rpmfi_Type.ob_type = &PyType_Type;
451  rpmmi_Type.ob_type = &PyType_Type;
452  rpmps_Type.ob_type = &PyType_Type;
453  rpmte_Type.ob_type = &PyType_Type;
454  rpmts_Type.ob_type = &PyType_Type;
455  spec_Type.ob_type = &PyType_Type;
456 #endif
457 
458  addRpmTags(m);
459 
460 #define REGISTER_ENUM(val) \
461  PyDict_SetItemString(d, #val, o=PyInt_FromLong( val )); \
462  Py_DECREF(o);
463 
469 
481 
484 
489  REGISTER_ENUM(RPMSENSE_FIND_REQUIRES);
490 
501 
521 
531 
549 
562 
565 
574 
579 
595 
598 
600 
602 }