summaryrefslogtreecommitdiff
path: root/lib/idtx.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/idtx.c')
-rw-r--r--lib/idtx.c190
1 files changed, 190 insertions, 0 deletions
diff --git a/lib/idtx.c b/lib/idtx.c
new file mode 100644
index 000000000..6f585416e
--- /dev/null
+++ b/lib/idtx.c
@@ -0,0 +1,190 @@
+
+#include "idtx.h"
+#include "rpmlib.h"
+#include "rpmdb.h"
+#include "rpmts.h"
+#include "rpmmacro.h"
+
+/*@unchecked@*/
+static int reverse = -1;
+
+/**
+ */
+static int IDTintcmp(const void * a, const void * b)
+ /*@*/
+{
+ /*@-castexpose@*/
+ return ( reverse * (((IDT)a)->val.u32 - ((IDT)b)->val.u32) );
+ /*@=castexpose@*/
+}
+
+IDTX IDTXfree(IDTX idtx)
+{
+ if (idtx) {
+ int i;
+ if (idtx->idt)
+ for (i = 0; i < idtx->nidt; i++) {
+ IDT idt = idtx->idt + i;
+ idt->h = headerFree(idt->h);
+ idt->key = _free(idt->key);
+ }
+ idtx->idt = _free(idtx->idt);
+ idtx = _free(idtx);
+ }
+ return NULL;
+}
+
+IDTX IDTXnew(void)
+{
+ IDTX idtx = xcalloc(1, sizeof(*idtx));
+ idtx->delta = 10;
+ idtx->size = sizeof(*((IDT)0));
+ return idtx;
+}
+
+IDTX IDTXgrow(IDTX idtx, int need)
+{
+ if (need < 0) return NULL;
+ if (idtx == NULL)
+ idtx = IDTXnew();
+ if (need == 0) return idtx;
+
+ if ((idtx->nidt + need) > idtx->alloced) {
+ while (need > 0) {
+ idtx->alloced += idtx->delta;
+ need -= idtx->delta;
+ }
+ idtx->idt = xrealloc(idtx->idt, (idtx->alloced * idtx->size) );
+ }
+ return idtx;
+}
+
+IDTX IDTXsort(IDTX idtx)
+{
+ if (idtx != NULL && idtx->idt != NULL && idtx->nidt > 0)
+ qsort(idtx->idt, idtx->nidt, idtx->size, IDTintcmp);
+ return idtx;
+}
+
+IDTX IDTXload(rpmts ts, rpmTag tag)
+{
+ IDTX idtx = NULL;
+ rpmdbMatchIterator mi;
+ HGE_t hge = (HGE_t) headerGetEntry;
+ Header h;
+
+ /*@-branchstate@*/
+ mi = rpmtsInitIterator(ts, tag, NULL, 0);
+#ifdef NOTYET
+ (void) rpmdbSetIteratorRE(mi, RPMTAG_NAME, RPMMIRE_DEFAULT, '!gpg-pubkey');
+#endif
+ while ((h = rpmdbNextIterator(mi)) != NULL) {
+ rpmTagType type = RPM_NULL_TYPE;
+ int_32 count = 0;
+ int_32 * tidp;
+
+ tidp = NULL;
+ if (!hge(h, tag, &type, (void **)&tidp, &count) || tidp == NULL)
+ continue;
+
+ if (type == RPM_INT32_TYPE && (*tidp == 0 || *tidp == -1))
+ continue;
+
+ idtx = IDTXgrow(idtx, 1);
+ if (idtx == NULL)
+ continue;
+ if (idtx->idt == NULL)
+ continue;
+
+ { IDT idt;
+ /*@-nullderef@*/
+ idt = idtx->idt + idtx->nidt;
+ /*@=nullderef@*/
+ idt->h = headerLink(h);
+ idt->key = NULL;
+ idt->instance = rpmdbGetIteratorOffset(mi);
+ idt->val.u32 = *tidp;
+ }
+ idtx->nidt++;
+ }
+ mi = rpmdbFreeIterator(mi);
+ /*@=branchstate@*/
+
+ return IDTXsort(idtx);
+}
+
+IDTX IDTXglob(rpmts ts, const char * globstr, rpmTag tag)
+{
+ IDTX idtx = NULL;
+ HGE_t hge = (HGE_t) headerGetEntry;
+ Header h;
+ int_32 * tidp;
+ FD_t fd;
+ const char ** av = NULL;
+ int ac = 0;
+ rpmRC rpmrc;
+ int xx;
+ int i;
+
+ av = NULL; ac = 0;
+ xx = rpmGlob(globstr, &ac, &av);
+
+ if (xx == 0)
+ for (i = 0; i < ac; i++) {
+ rpmTagType type;
+ int_32 count;
+ int isSource;
+
+ fd = Fopen(av[i], "r.ufdio");
+ if (fd == NULL || Ferror(fd)) {
+ rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), av[i],
+ Fstrerror(fd));
+ if (fd != NULL) (void) Fclose(fd);
+ continue;
+ }
+
+ rpmrc = rpmReadPackageFile(ts, fd, av[i], &h);
+ (void) Fclose(fd);
+ switch (rpmrc) {
+ default:
+ goto bottom;
+ /*@notreached@*/ /*@switchbreak@*/ break;
+ case RPMRC_NOTTRUSTED:
+ case RPMRC_NOKEY:
+ case RPMRC_OK:
+ isSource = headerIsEntry(h, RPMTAG_SOURCEPACKAGE);
+ if (isSource)
+ goto bottom;
+ /*@switchbreak@*/ break;
+ }
+
+ tidp = NULL;
+ /*@-branchstate@*/
+ if (hge(h, tag, &type, (void **) &tidp, &count) && tidp != NULL) {
+
+ idtx = IDTXgrow(idtx, 1);
+ if (idtx == NULL || idtx->idt == NULL)
+ goto bottom;
+
+ { IDT idt;
+ idt = idtx->idt + idtx->nidt;
+ idt->h = headerLink(h);
+ idt->key = av[i];
+ av[i] = NULL;
+ idt->instance = 0;
+ idt->val.u32 = *tidp;
+ }
+ idtx->nidt++;
+ }
+ /*@=branchstate@*/
+bottom:
+ h = headerFree(h);
+ }
+
+ for (i = 0; i < ac; i++)
+ av[i] = _free(av[i]);
+ av = _free(av); ac = 0;
+
+ return IDTXsort(idtx);
+}
+