diff options
Diffstat (limited to 'rpmtools.xs')
-rw-r--r-- | rpmtools.xs | 573 |
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"); |