aboutsummaryrefslogtreecommitdiffstats
path: root/rpmtools.xs
diff options
context:
space:
mode:
Diffstat (limited to 'rpmtools.xs')
-rw-r--r--rpmtools.xs573
1 files changed, 0 insertions, 573 deletions
diff --git a/rpmtools.xs b/rpmtools.xs
deleted file mode 100644
index 8363a7a..0000000
--- a/rpmtools.xs
+++ /dev/null
@@ -1,573 +0,0 @@
-#include "EXTERN.h"
-#include "perl.h"
-#include "XSUB.h"
-
-#include <sys/utsname.h>
-#include <sys/select.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#undef Fflush
-#undef Mkdir
-#undef Stat
-#include <rpm/rpmlib.h>
-#include <rpm/header.h>
-
-#define HDFLAGS_NAME 0x00000001
-#define HDFLAGS_VERSION 0x00000002
-#define HDFLAGS_RELEASE 0x00000004
-#define HDFLAGS_ARCH 0x00000008
-#define HDFLAGS_GROUP 0x00000010
-#define HDFLAGS_SIZE 0x00000020
-#define HDFLAGS_SERIAL 0x00000040
-#define HDFLAGS_SUMMARY 0x00000080
-#define HDFLAGS_DESCRIPTION 0x00000100
-#define HDFLAGS_SENSE 0x00080000
-#define HDFLAGS_REQUIRES 0x00100000
-#define HDFLAGS_PROVIDES 0x00200000
-#define HDFLAGS_OBSOLETES 0x00400000
-#define HDFLAGS_CONFLICTS 0x00800000
-#define HDFLAGS_FILES 0x01000000
-#define HDFLAGS_CONFFILES 0x02000000
-#define HDFLAGS_SOURCERPM 0x04000000
-
-
-/* duplicate definition for rpmvercmp (not needed on 4.0.3 but needed on 4.0) */
-int rpmvercmp(const char *a, const char *b);
-
-char *get_name(Header header, int_32 tag) {
- int_32 type, count;
- char *name;
-
- headerGetEntry(header, tag, &type, (void **) &name, &count);
- return name;
-}
-
-int get_int(Header header, int_32 tag) {
- int_32 type, count;
- int *i;
-
- headerGetEntry(header, tag, &type, (void **) &i, &count);
- return i ? *i : 0;
-}
-
-int get_bflag(AV* flag) {
- int bflag = 0;
- int flag_len;
- SV** ret;
- STRLEN len;
- char* str;
- int i;
-
- flag_len = av_len(flag);
- for (i = 0; i <= flag_len; ++i) {
- ret = av_fetch(flag, i, 0); if (!ret) continue;
- str = SvPV(*ret, len);
-
- switch (len) {
- case 4:
- if (!strncmp(str, "name", 4)) bflag |= HDFLAGS_NAME;
- else if (!strncmp(str, "arch", 4)) bflag |= HDFLAGS_ARCH;
- else if (!strncmp(str, "size", 4)) bflag |= HDFLAGS_SIZE;
- break;
- case 5:
- if (!strncmp(str, "group", 5)) bflag |= HDFLAGS_GROUP;
- else if (!strncmp(str, "sense", 5)) bflag |= HDFLAGS_SENSE;
- else if (!strncmp(str, "files", 5)) bflag |= HDFLAGS_FILES;
- break;
- case 6:
- if (!strncmp(str, "serial", 6)) bflag |= HDFLAGS_SERIAL;
- break;
- case 7:
- if (!strncmp(str, "version", 7)) bflag |= HDFLAGS_VERSION;
- else if (!strncmp(str, "release", 7)) bflag |= HDFLAGS_RELEASE;
- else if (!strncmp(str, "summary", 7)) bflag |= HDFLAGS_SUMMARY;
- break;
- case 8:
- if (!strncmp(str, "requires", 8)) bflag |= HDFLAGS_REQUIRES;
- else if (!strncmp(str, "provides", 8)) bflag |= HDFLAGS_PROVIDES;
- break;
- case 9:
- if (!strncmp(str, "obsoletes", 9)) bflag |= HDFLAGS_OBSOLETES;
- else if (!strncmp(str, "conflicts", 9)) bflag |= HDFLAGS_CONFLICTS;
- else if (!strncmp(str, "conffiles", 9)) bflag |= HDFLAGS_CONFFILES;
- else if (!strncmp(str, "sourcerpm", 9)) bflag |= HDFLAGS_SOURCERPM;
- break;
- case 11:
- if (!strncmp(str, "description", 11)) bflag |= HDFLAGS_DESCRIPTION;
- }
- }
- bflag |= HDFLAGS_NAME; /* this one should always be used */
-
- return bflag;
-}
-
-STRLEN get_fullname(Header header, char *fullname) {
- char *name = get_name(header, RPMTAG_NAME);
- char *version = get_name(header, RPMTAG_VERSION);
- char *release = get_name(header, RPMTAG_RELEASE);
- char *arch = headerIsEntry(header, RPMTAG_SOURCEPACKAGE) ? "src" : get_name(header, RPMTAG_ARCH);
- return sprintf(fullname, "%s-%s-%s.%s", name, version, release, arch);
-}
-
-void update_provides(int force, HV* provides, char *name, STRLEN len, Header header) {
- SV** isv;
-
- if (!len) len = strlen(name);
-
- if (provides) {
- if ((isv = hv_fetch(provides, name, len, force))) {
- if (isv && !SvROK(*isv) || SvTYPE(SvRV(*isv)) != SVt_PVHV) {
- SV* choice_set = (SV*)newHV();
- SvREFCNT_dec(*isv); /* drop the old as we are changing it */
- *isv = choice_set ? newRV_noinc(choice_set) : &PL_sv_undef;
- if (!*isv) *isv = &PL_sv_undef;
- }
- if (isv && *isv != &PL_sv_undef) {
- char fullname[1024];
- STRLEN fullname_len = get_fullname(header, fullname);
- hv_fetch((HV*)SvRV(*isv), fullname, fullname_len, 1);
- }
- }
- }
-}
-
-SV *get_table_sense(Header header, int_32 tag_name, int_32 tag_flags, int_32 tag_version, HV* iprovides) {
- AV* table_sense;
- int_32 type, count;
- char **list = NULL;
- int_32 *flags = NULL;
- char **list_evr = NULL;
- int i;
-
- char buff[4096];
- char *p;
- int len;
-
- headerGetEntry(header, tag_name, &type, (void **) &list, &count);
- if (tag_flags) headerGetEntry(header, tag_flags, &type, (void **) &flags, &count);
- if (tag_version) headerGetEntry(header, tag_version, &type, (void **) &list_evr, &count);
-
- if (list) {
- table_sense = newAV();
- if (!table_sense) {
- free(list);
- free(list_evr);
- return &PL_sv_undef;
- }
-
- for(i = 0; i < count; i++) {
- len = strlen(list[i]);
- if (len >= sizeof(buff) || !strncmp(list[i], "rpmlib(", 7)) continue;
- memcpy(p = buff, list[i], len + 1); p+= len;
-
- if (flags) {
- if (flags[i] & RPMSENSE_PREREQ) {
- if (p - buff + 3 >= sizeof(buff)) continue;
- memcpy(p, "[*]", 4); p += 3;
- }
- if (list_evr) {
- if (list_evr[i]) {
- len = strlen(list_evr[i]);
- if (len > 0) {
- if (p - buff + 6 + len >= sizeof(buff)) continue;
- *p++ = '[';
- if (flags[i] & RPMSENSE_LESS) *p++ = '<';
- if (flags[i] & RPMSENSE_GREATER) *p++ = '>';
- if (flags[i] & RPMSENSE_EQUAL) *p++ = '=';
- if ((flags[i] & (RPMSENSE_LESS|RPMSENSE_EQUAL|RPMSENSE_GREATER)) == RPMSENSE_EQUAL) *p++ = '=';
- *p++ = ' ';
- memcpy(p, list_evr[i], len); p+= len;
- *p++ = ']';
- }
- }
- }
- }
- *p = '\0'; /* make sure to mark null char, Is it really necessary ?
-
- /* for getting provides about required files */
- if (iprovides && buff[0] == '/')
- hv_fetch(iprovides, buff, p - buff, 1);
-
- av_push(table_sense, newSVpv(buff, p - buff));
- }
-
- free(list);
- free(list_evr);
- return newRV_noinc((SV*)table_sense);
- }
-
- free(list);
- free(list_evr);
- return &PL_sv_undef;
-}
-
-HV* get_info(Header header, int bflag, HV* provides) {
- int_32 type, count;
- int_32 *flags;
- SV** ret;
- STRLEN len;
- char* str;
- int i;
- HV* header_info = newHV();
-
- /* correct bflag according to provides hash else not really usefull */
- if (provides) bflag |= HDFLAGS_REQUIRES;
-
- hv_store(header_info, "name", 4, newSVpv(get_name(header, RPMTAG_NAME), 0), 0);
- if (bflag & HDFLAGS_VERSION)
- hv_store(header_info, "version", 7, newSVpv(get_name(header, RPMTAG_VERSION), 0), 0);
- if (bflag & HDFLAGS_RELEASE)
- hv_store(header_info, "release", 7, newSVpv(get_name(header, RPMTAG_RELEASE), 0), 0);
- if (bflag & HDFLAGS_ARCH)
- hv_store(header_info, "arch", 4, newSVpv(headerIsEntry(header, RPMTAG_SOURCEPACKAGE) ? "src" : get_name(header, RPMTAG_ARCH), 0), 0);
- if (bflag & HDFLAGS_GROUP)
- hv_store(header_info, "group", 5, newSVpv(get_name(header, RPMTAG_GROUP), 0), 0);
- if (bflag & HDFLAGS_SIZE)
- hv_store(header_info, "size", 4, newSViv(get_int(header, RPMTAG_SIZE)), 0);
- if (bflag & HDFLAGS_SERIAL)
- hv_store(header_info, "serial", 6, newSViv(get_int(header, RPMTAG_SERIAL)), 0);
- if (bflag & HDFLAGS_SUMMARY)
- hv_store(header_info, "summary", 7, newSVpv(get_name(header, RPMTAG_SUMMARY), 0), 0);
- if (bflag & HDFLAGS_DESCRIPTION)
- hv_store(header_info, "description", 11, newSVpv(get_name(header, RPMTAG_DESCRIPTION), 0), 0);
- if (bflag & HDFLAGS_REQUIRES)
- hv_store(header_info, "requires", 8, get_table_sense(header, RPMTAG_REQUIRENAME,
- bflag & HDFLAGS_SENSE ? RPMTAG_REQUIREFLAGS : 0,
- bflag & HDFLAGS_SENSE ? RPMTAG_REQUIREVERSION : 0, provides), 0);
- if (bflag & HDFLAGS_PROVIDES)
- hv_store(header_info, "provides", 8, get_table_sense(header, RPMTAG_PROVIDENAME,
- bflag & HDFLAGS_SENSE ? RPMTAG_PROVIDEFLAGS : 0,
- bflag & HDFLAGS_SENSE ? RPMTAG_PROVIDEVERSION : 0, 0), 0);
- if (bflag & HDFLAGS_OBSOLETES)
- hv_store(header_info, "obsoletes", 9, get_table_sense(header, RPMTAG_OBSOLETENAME,
- bflag & HDFLAGS_SENSE ? RPMTAG_OBSOLETEFLAGS : 0,
- bflag & HDFLAGS_SENSE ? RPMTAG_OBSOLETEVERSION : 0, 0), 0);
- if (bflag & HDFLAGS_CONFLICTS)
- hv_store(header_info, "conflicts", 9, get_table_sense(header, RPMTAG_CONFLICTNAME,
- bflag & HDFLAGS_SENSE ? RPMTAG_CONFLICTFLAGS : 0,
- bflag & HDFLAGS_SENSE ? RPMTAG_CONFLICTVERSION : 0, 0), 0);
- if (bflag & HDFLAGS_SOURCERPM)
- hv_store(header_info, "sourcerpm", 9, newSVpv(get_name(header, RPMTAG_SOURCERPM), 0), 0);
- if (provides || (bflag & (HDFLAGS_FILES | HDFLAGS_CONFFILES))) {
- /* at this point, there is a need to parse all files to update provides of needed files,
- or to store them. */
- AV* table_files = bflag & HDFLAGS_FILES ? newAV() : 0;
- AV* table_conffiles = bflag & HDFLAGS_CONFFILES ? newAV() : 0;
- char **list = NULL;
- char ** baseNames = NULL;
- char ** dirNames = NULL;
- int_32 * dirIndexes;
-
- headerGetEntry(header, RPMTAG_FILEFLAGS, &type, (void **) &flags, &count);
-
- headerGetEntry(header, RPMTAG_OLDFILENAMES, &type, (void **) &list, &count);
- if (list) {
- for (i = 0; i < count; i++) {
- len = strlen(list[i]);
-
- update_provides(0, provides, list[i], len, header);
-
- if (table_files)
- av_push(table_files, newSVpv(list[i], len));
- if (table_conffiles && flags && flags[i] & RPMFILE_CONFIG)
- av_push(table_conffiles, newSVpv(list[i], len));
- }
- free(list);
- }
-
- headerGetEntry(header, RPMTAG_BASENAMES, &type, (void **) &baseNames, &count);
- headerGetEntry(header, RPMTAG_DIRINDEXES, &type, (void **) &dirIndexes, NULL);
- headerGetEntry(header, RPMTAG_DIRNAMES, &type, (void **) &dirNames, NULL);
- if (baseNames && dirNames && dirIndexes) {
- char buff[4096];
- char *p;
-
- for(i = 0; i < count; i++) {
- SV** isv;
-
- len = strlen(dirNames[dirIndexes[i]]);
- if (len >= sizeof(buff)) continue;
- memcpy(p = buff, dirNames[dirIndexes[i]], len + 1); p += len;
- len = strlen(baseNames[i]);
- if (p - buff + len >= sizeof(buff)) continue;
- memcpy(p, baseNames[i], len + 1); p += len;
-
- update_provides(0, provides, buff, p - buff, header);
-
- if (table_files)
- av_push(table_files, newSVpv(buff, p - buff));
- if (table_conffiles && flags && flags[i] & RPMFILE_CONFIG)
- av_push(table_conffiles, newSVpv(buff, p - buff));
- }
- free(baseNames);
- free(dirNames);
- }
-
- if (table_files)
- hv_store(header_info, "files", 5, newRV_noinc((SV*)table_files), 0);
- if (table_conffiles)
- hv_store(header_info, "conffiles", 9, newRV_noinc((SV*)table_conffiles), 0);
- }
- if (provides) {
- char **list = NULL;
- /* we have to examine provides to update the hash here. */
- headerGetEntry(header, RPMTAG_PROVIDENAME, &type, (void **) &list, &count);
-
- if (list) {
- for (i = 0; i < count; i++) {
- update_provides(1, provides, list[i], 0, header); /* force extraction of provides */
- }
- free(list);
- }
- }
-
- return header_info;
-}
-
-void callback_empty(void) {}
-
-MODULE = rpmtools PACKAGE = rpmtools
-
-
-int
-rpmvercmp(a,b)
- char *a
- char *b
-
-char *
-arch()
- CODE:
- struct utsname u;
- if (uname(&u) == 0) RETVAL = u.machine; else RETVAL = NULL;
- OUTPUT:
- RETVAL
-
-void*
-db_open(prefix)
- char *prefix
- CODE:
- rpmdb db;
- rpmErrorCallBackType old_cb;
- old_cb = rpmErrorSetCallback(callback_empty);
- rpmSetVerbosity(RPMMESS_FATALERROR);
- RETVAL = rpmReadConfigFiles(NULL, NULL) == 0 && rpmdbOpen(prefix, &db, O_RDONLY, 0644) == 0 ? db : NULL;
- rpmErrorSetCallback(old_cb);
- rpmSetVerbosity(RPMMESS_NORMAL);
- OUTPUT:
- RETVAL
-
-void
-db_close(db)
- void *db
- CODE:
- rpmdbClose((rpmdb)db);
-
-void
-_exit(code)
- int code
-
-int
-db_traverse_tag(db, tag, names, flags, callback)
- void *db
- char *tag
- SV *names
- SV *flags
- SV *callback
- PREINIT:
- int count = 0;
- CODE:
- if (SvROK(flags) && SvTYPE(SvRV(flags)) == SVt_PVAV &&
- SvROK(names) && SvTYPE(SvRV(names)) == SVt_PVAV) {
- AV* flags_av = (AV*)SvRV(flags);
- AV* names_av = (AV*)SvRV(names);
- int bflag = get_bflag(flags_av);
- int len = av_len(names_av);
- HV* info;
- SV** isv;
- int i, rpmtag;
- STRLEN str_len;
- char *name;
- Header header;
- rpmdbMatchIterator mi;
-
- if (!strcmp(tag, "name"))
- rpmtag = RPMTAG_NAME;
- else if (!strcmp(tag, "whatprovides"))
- rpmtag = RPMTAG_PROVIDENAME;
- else if (!strcmp(tag, "whatrequires"))
- rpmtag = RPMTAG_REQUIRENAME;
- else if (!strcmp(tag, "group"))
- rpmtag = RPMTAG_GROUP;
- else if (!strcmp(tag, "triggeredby"))
- rpmtag = RPMTAG_BASENAMES;
- else if (!strcmp(tag, "path"))
- rpmtag = RPMTAG_BASENAMES;
- else {
- croak("unknown tag");
- len = 0;
- }
-
- for (i = 0; i <= len; ++i) {
- isv = av_fetch(names_av, i, 0);
- name = SvPV(*isv, str_len);
- mi = rpmdbInitIterator((rpmdb)db, rpmtag, name, str_len);
- while (header = rpmdbNextIterator(mi)) {
- count++;
- info = get_info(header, bflag, NULL);
-
- if (info != 0 && callback != &PL_sv_undef && SvROK(callback)) {
- dSP;
- ENTER;
- SAVETMPS;
- PUSHMARK(SP);
- XPUSHs(sv_2mortal(newRV_noinc((SV*)info)));
- XPUSHs(sv_2mortal(newSVpv(name, str_len)));
- PUTBACK;
- call_sv(callback, G_DISCARD | G_SCALAR);
- FREETMPS;
- LEAVE;
- }
- }
- rpmdbFreeIterator(mi);
- }
- } else croak("bad arguments list");
- RETVAL = count;
- OUTPUT:
- RETVAL
-
-int
-db_traverse(db, flags, callback)
- void *db
- SV *flags
- SV *callback
- PREINIT:
- int count = 0;
- CODE:
- if (SvROK(flags) && SvTYPE(SvRV(flags)) == SVt_PVAV) {
- AV* flags_av = (AV*)SvRV(flags);
- int bflag = get_bflag(flags_av);
- HV* info;
- Header header;
- rpmdbMatchIterator mi;
-
- mi = rpmdbInitIterator(db, RPMDBI_PACKAGES, NULL, 0);
- while (header = rpmdbNextIterator(mi)) {
- info = get_info(header, bflag, NULL);
-
- if (info != 0 && callback != &PL_sv_undef && SvROK(callback)) {
- dSP;
- ENTER;
- SAVETMPS;
- PUSHMARK(SP);
- XPUSHs(sv_2mortal(newRV_noinc((SV*)info)));
- PUTBACK;
- call_sv(callback, G_DISCARD | G_SCALAR);
- FREETMPS;
- LEAVE;
- }
- ++count;
- }
- rpmdbFreeIterator(mi);
- } else croak("bad arguments list");
- RETVAL = count;
- OUTPUT:
- RETVAL
-
-void
-_parse_(fileno_or_rpmfile, flag, info, ...)
- SV* fileno_or_rpmfile
- SV* flag
- SV* info
- PREINIT:
- SV* provides = &PL_sv_undef;
- PPCODE:
- if (items > 3)
- provides = ST(3);
- if (SvROK(flag) && SvROK(info) && (provides == &PL_sv_undef || SvROK(provides))) {
- FD_t fd;
- int fd_is_hdlist;
- Header header;
-
- int bflag;
- AV* iflag;
- HV* iinfo;
- HV* iprovides;
- SV** ret;
- I32 flag_len;
- STRLEN len;
- char* str;
- int i;
-
- if (SvIOK(fileno_or_rpmfile)) {
- int d = SvIV(fileno_or_rpmfile);
- fd_set readfds;
- struct timeval timeout;
-
- FD_ZERO(&readfds);
- FD_SET(d, &readfds);
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
- select(d+1, &readfds, NULL, NULL, &timeout);
-
- fd = fdDup(SvIV(fileno_or_rpmfile));
- fd_is_hdlist = 1;
- } else {
- fd = fdOpen(SvPV_nolen(fileno_or_rpmfile), O_RDONLY, 0666);
- if (fd < 0) croak("unable to open rpm file %s", SvPV_nolen(fileno_or_rpmfile));
- fd_is_hdlist = 0;
- }
-
- if ((SvTYPE(SvRV(flag)) != SVt_PVAV) ||
- (SvTYPE(SvRV(info)) != SVt_PVHV) ||
- provides != &PL_sv_undef && (SvTYPE(SvRV(provides)) != SVt_PVHV))
- croak("bad arguments list");
-
- iflag = (AV*)SvRV(flag);
- iinfo = (HV*)SvRV(info);
- iprovides = (HV*)(provides != &PL_sv_undef ? SvRV(provides) : 0);
-
- /* examine flag and set up iflag, which is faster to fecth out */
- bflag = get_bflag(iflag);
-
- /* start the big loop,
- parse all header from fileno, then extract information to store into iinfo and iprovides. */
- if (fd_is_hdlist) {
- while (fd_is_hdlist < 20 && (header=headerRead(fd, HEADER_MAGIC_YES)) == 0) {
- struct timeval timeout;
-
- timeout.tv_sec = 0;
- timeout.tv_usec = 10000;
- select(0, NULL, NULL, NULL, &timeout);
-
- ++fd_is_hdlist;
- }
- } else {
- if (rpmReadPackageHeader(fd, &header, &i, NULL, NULL) != 0)
- header = 0;
- }
- while (header != 0) {
- char fullname[1024];
- STRLEN fullname_len = get_fullname(header, fullname);
- HV* header_info = get_info(header, bflag, iprovides);
-
- hv_store(iinfo, fullname, fullname_len, newRV_noinc((SV*)header_info), 0);
-
- /* return fullname on stack */
- EXTEND(SP, 1);
- PUSHs(sv_2mortal(newSVpv(fullname, fullname_len)));
-
- /* dispose of some memory */
- headerFree(header);
-
- /* continue loop for hdlist */
- if (fd_is_hdlist)
- header=headerRead(fd, HEADER_MAGIC_YES);
- else
- header=0;
- }
- fdClose(fd);
- } else croak("bad arguments list");