RPM4

 view release on metacpan or  search on metacpan

src/RPM4.xs  view on Meta::CPAN

    /* return 1 if match */
}

int _headername_vs_dep(Header h, rpmds dep, int nopromote) {
    char *name;
    int rc = 0;
    CHECK_RPMDS_IX(dep);
    struct rpmtd_s val;

    headerGet(h, RPMTAG_NAME, &val, HEADERGET_MINMEM);
    name = (char *) rpmtdGetString(&val);
    if (strcmp(name, rpmdsN(dep)) != 0)
        rc = 0;
    else
        rc = rpmdsNVRMatchesDep(h, dep, nopromote);
    rpmtdFreeData(&val);
    return rc;
    /* return 1 if match */
}

/* Hight level function */
int rpmsign(char *passphrase, const char *rpm) {
#if defined(RPM4_12_90) | defined(PATCHED_rpmPkgSign)
    return rpmPkgSign(rpm, NULL);
#else
    return rpmPkgSign(rpm, NULL, passphrase);
#endif
}

MODULE = RPM4 PACKAGE = RPM4

BOOT:
if (rpmReadConfigFiles(NULL, NULL) != 0)
    croak("Can't read configuration");
#ifdef HDLISTDEBUG
rpmSetVerbosity(RPMLOG_DEBUG);
#else
rpmSetVerbosity(RPMLOG_NOTICE);
#endif
#ifdef HDRPMDEBUG
_rpmds_debug = -1;
_rpmdb_debug = -1;
_rpmts_debug = -1;
_rpmfi_debug = -1;
_rpmte_debug = -1;
#endif

int
isdebug()
    CODE:
#ifdef HDLISTDEBUG
    RETVAL = 1;
#else
    RETVAL = 0;
#endif
    OUTPUT:
    RETVAL

void
moduleinfo()
    PPCODE:
    mXPUSHs(newSVpv("Hack", 0));
#ifdef HHACK
    mXPUSHs(newSVpv("Yes", 0));
#else
    mXPUSHs(newSVpv("No", 0));
#endif
    
    mXPUSHs(newSVpv("RPMVERSION", 0));
    mXPUSHs(newSVpv(RPMVERSION, 0));
    
    mXPUSHs(newSVpv("RPM4VERSION", 0));
    mXPUSHs(newSVpv(VERSION, 0));
    
    mXPUSHs(newSVpv("RPMNAME", 0));
    mXPUSHs(newSVpv(rpmNAME, 0));
    
    mXPUSHs(newSVpv("RPMEVR", 0));
    mXPUSHs(newSVpv(rpmEVR, 0));

# Functions to control log/verbosity
    
void
setverbosity(svlevel)
    SV * svlevel
    CODE:
    rpmSetVerbosity(sv2loglevel(svlevel));

void
setlogcallback(function)
    SV * function
    CODE:
    if (function == NULL || !SvOK(function)) {
        rpmlogSetCallback(NULL, NULL);
    } else if (SvTYPE(SvRV(function)) == SVt_PVCV) {
        log_callback_function = newSVsv(function);
        rpmlogSetCallback(logcallback, NULL);
    } else
        croak("First arg is not a code reference");

void
lastlogmsg()
    PPCODE:
    mXPUSHs(newSViv(rpmlogCode()));
    mXPUSHs(newSVpv((char *) rpmlogMessage(), 0));

int
setlogfile(filename)
    char * filename
    PREINIT:
    FILE * ofp = NULL;
    FILE * fp = NULL;
    CODE:
    if (filename && *filename != 0) {
        if ((fp = fopen(filename, "a+")) == NULL) {
            XSprePUSH; PUSHi((IV)0);
            XSRETURN(1);
        }
    }
    if((ofp = rpmlogSetFile(fp)) != NULL)
        fclose(ofp);
    RETVAL=1;
    OUTPUT:
    RETVAL
    
int
readconfig(rcfile = NULL, target = NULL)
    char * rcfile
    char * target
    CODE:
    RETVAL = rpmReadConfigFiles(rcfile && rcfile[0] ? rcfile : NULL, target);
    OUTPUT:
    RETVAL

void
rpmlog(svcode, msg)
    SV * svcode
    char * msg
    CODE:
    rpmlog(sv2loglevel(svcode), "%s", msg);
    
# Return hash of know tag
# Name => internal key (if available)

void
querytag()
    PREINIT:
    CODE:

int
tagtypevalue(svtagtype)
    SV * svtagtype
    CODE:
    RETVAL = sv2tagtype(svtagtype);
    OUTPUT:
    RETVAL

int
tagValue(tagname)
    char * tagname
    CODE:
    RETVAL = rpmTagGetValue((const char *) tagname);
    OUTPUT:
    RETVAL

void
tagName(tag)
    int tag
    PREINIT:
    const char *r  = NULL;
    PPCODE:
    r = rpmTagGetName(tag);
    mXPUSHs(newSVpv(r, 0));

void
flagvalue(flagtype, sv_value)
    char * flagtype
    SV * sv_value
    PPCODE:
    if (strcmp(flagtype, "loglevel") == 0) {
        mXPUSHs(newSViv(sv2constant(sv_value, "rpmlog")));
    } else if (strcmp(flagtype, "deptag") == 0) { /* Who will use this ?? */
        mXPUSHs(newSViv(sv2deptag(sv_value)));
    } else if (strcmp(flagtype, "vsf") == 0) {
        mXPUSHs(newSViv(sv2constant(sv_value, "rpmverifyflags")));
    } else if (strcmp(flagtype, "trans") == 0) {
        mXPUSHs(newSViv(sv2transflags(sv_value)));
    } else if (strcmp(flagtype, "dbquery") == 0) {
        mXPUSHs(newSViv(sv2dbquerytag(sv_value)));
    } else if (strcmp(flagtype, "build") == 0) {
        mXPUSHs(newSViv(sv2rpmbuildflags(sv_value)));
    } else if (strcmp(flagtype, "fileattr") == 0) {
        mXPUSHs(newSViv(sv2fileattr(sv_value)));
    } else if (strcmp(flagtype, "sense") == 0) {
        mXPUSHs(newSViv(sv2senseflags(sv_value)));
    } else if (strcmp(flagtype, "tagtype") == 0) {
        mXPUSHs(newSViv(sv2tagtype(sv_value)));
    } else if (strcmp(flagtype, "list") == 0) {
        mXPUSHs(newSVpv("loglevel", 0));
        mXPUSHs(newSVpv("deptag",   0));
        mXPUSHs(newSVpv("vsf",      0));
        mXPUSHs(newSVpv("trans",    0));
        mXPUSHs(newSVpv("dbquery",  0));
        mXPUSHs(newSVpv("build",    0));
        mXPUSHs(newSVpv("fileattr", 0));
        mXPUSHs(newSVpv("tagtype",  0));
    }

# Macros functions:

void
expand(name)
    char * name
    PPCODE:
    const char * value = rpmExpand(name, NULL);
    mXPUSHs(newSVpv(value, 0));
    free((char *) value);

void
expandnumeric(name)
    char *name
    PPCODE:
    int value = rpmExpandNumeric(name);
    mXPUSHs(newSViv(value));
    
void
addmacro(macro)
    char * macro
    CODE:
    rpmDefineMacro(NULL, macro, RMIL_DEFAULT);

void
delmacro(name)
    char * name
    CODE:
    delMacro(NULL, name);

void
loadmacrosfile(filename)
    char * filename
    PPCODE:
    rpmInitMacros(NULL, filename);

void
resetmacros()
    PPCODE:
    rpmFreeMacros(NULL);

void
resetrc()
    PPCODE:
    rpmFreeRpmrc();
    
void
getosname()
    PREINIT:
    const char *v = NULL;
    PPCODE:
    rpmGetOsInfo(&v, NULL);
    mXPUSHs(newSVpv(v, 0));

void
getarchname()
    PREINIT:
    const char *v = NULL;
    PPCODE:
    rpmGetArchInfo(&v, NULL);
    mXPUSHs(newSVpv(v, 0));

int
osscore(data, build = 0)
    char * data;
    int build;
    ALIAS:
        archscore = 1
    PREINIT:
    int machtable;
    CODE:
    if (ix == 0)
         machtable = build ? RPM_MACHTABLE_BUILDOS   : RPM_MACHTABLE_INSTOS;
    else
         machtable = build ? RPM_MACHTABLE_BUILDARCH : RPM_MACHTABLE_INSTARCH;
    RETVAL = rpmMachineScore(machtable, data);
    OUTPUT:
    RETVAL
    
void
buildhost()
    PREINIT:
    PPCODE:
    static char hostname[1024];
    static int oneshot = 0;
    struct hostent *hbn;
    
    if (! oneshot) {
        (void) gethostname(hostname, sizeof(hostname));
       hbn = gethostbyname(hostname);
       if (hbn)
           strcpy(hostname, hbn->h_name);
       else
           rpmlog(RPMLOG_WARNING,
                       _("Could not canonicalize hostname: %s\n"), hostname);
       oneshot = 1;
    }
    mXPUSHs(newSVpv(hostname,0));
    
# Dump to file functions:
void
dumprc(fp)
    FILE *fp
    CODE:
    rpmShowRC(fp);

void
dumpmacros(fp)
    FILE *fp
    CODE:
    rpmDumpMacroTable(NULL, fp);

int
rpmvercmp(one, two)
    char *one
    char *two

# create a new empty header
# Is this usefull

void
headernew()
    PREINIT:
    Header h = headerNew();
    PPCODE:
    mXPUSHs(sv_setref_pv(newSVpvs(""), bless_header, (void *)h));
#ifdef HDRPMMEM
    PRINTF_NEW(bless_header, h, h->nrefs);
#endif


# Read data from file pointer and return next header object
# Return undef if failed
# fedora use HEADER_MAGIC_NO, too bad, set no_header_magic make the function
# compatible
void
stream2header(fp, no_header_magic = 0, callback = NULL)
    FILE *fp
    int no_header_magic
    SV * callback
    PREINIT:
    FD_t fd;
    Header header;
    PPCODE:
    if (fp && (fd = fdDup(fileno(fp)))) {
#ifdef HDLISTDEBUG
        PRINTF_CALL;
#endif
        if (callback != NULL && SvROK(callback)) {
            while ((header = headerRead(fd, no_header_magic ? HEADER_MAGIC_NO : HEADER_MAGIC_YES))) {
                ENTER;
                SAVETMPS;
                PUSHMARK(SP);
                mXPUSHs(sv_setref_pv(newSVpvs(""), bless_header, (void *)header));
#ifdef HDRPMMEM
                PRINTF_NEW(bless_header, header, header->nrefs);
#endif
                PUTBACK;
                call_sv(callback, G_DISCARD | G_SCALAR);
                SPAGAIN;
                FREETMPS;
                LEAVE;
            }
        } else {
            header = headerRead(fd, no_header_magic ? HEADER_MAGIC_NO : HEADER_MAGIC_YES);
            if (header) {
                mXPUSHs(sv_setref_pv(newSVpvs(""), bless_header, (void *)header));
#ifdef HDRPMMEM
                PRINTF_NEW(bless_header, header, header->nrefs);
#endif

            }
#ifdef HDLISTDEBUG
            else fprintf(stderr, "HDEBUG: No header found from fp: %d\n", fileno(fp));
#endif
        }
        Fclose(fd);
    }

# Read a rpm and return a Header
# Return undef if failed
void
rpm2header(filename, sv_vsflags = NULL)
    char * filename
    SV * sv_vsflags
    PREINIT:
    rpmts ts = rpmtsCreate();
    rpmVSFlags vsflags = RPMVSF_DEFAULT; 
    PPCODE:
    if (sv_vsflags == NULL) /* Nothing has been passed, default is no signature */
        vsflags |= _RPMVSF_NOSIGNATURES;
    else
        vsflags = sv2vsflags(sv_vsflags);
    rpmtsSetVSFlags(ts, vsflags);
    _rpm2header(ts, filename, 0);
    SPAGAIN;
    ts = rpmtsFree(ts);

int
rpmresign(passphrase, rpmfile)
    char * passphrase
    char * rpmfile
    CODE:
    RETVAL = rpmsign(passphrase, (const char *) rpmfile);
    OUTPUT:
    RETVAL
    
void
installsrpm(filename, sv_vsflags = NULL)
    char * filename
    SV * sv_vsflags
    PREINIT:
    rpmts ts = rpmtsCreate();
    rpmVSFlags vsflags = RPMVSF_DEFAULT;
    PPCODE:
    vsflags = sv2vsflags(sv_vsflags);
    rpmtsSetVSFlags(ts, vsflags);
    PUTBACK;
    _installsrpms(ts, filename);
    SPAGAIN;
    ts = rpmtsFree(ts);

MODULE = RPM4		PACKAGE = RPM4::Header	PREFIX = Header_

void
Header_DESTROY(h)
    Header h
    CODE:
#ifdef HDRPMMEM
    PRINTF_FREE(bless_header, h, h->nrefs);
#endif
    headerFree(h);

# Write rpm header into file pointer
# fedora use HEADER_MAGIC_NO, too bad, set no_header_magic make the function
# compatible
int
Header_write(h, fp, no_header_magic = 0)
    Header h
    FILE * fp
    int no_header_magic
    PREINIT:
    FD_t fd;
    CODE:
    RETVAL = 0;
#ifdef HDLISTDEBUG
    PRINTF_CALL;
#endif
    if (h) {
        if ((fd = fdDup(fileno(fp))) != NULL) {
            headerWrite(fd, h, no_header_magic ? HEADER_MAGIC_NO : HEADER_MAGIC_YES);
            Fclose(fd);
            RETVAL = 1;
        }
    }
    OUTPUT:
    RETVAL

void
Header_hsize(h, no_header_magic = 0)
    Header h
    int no_header_magic
    PPCODE:
    mXPUSHs(newSViv(headerSizeof(h, no_header_magic ? HEADER_MAGIC_NO : HEADER_MAGIC_YES)));
    
void
Header_copy(h)
    Header h
    PREINIT:
    Header hcopy;
    PPCODE:
    hcopy = headerCopy(h);
    mXPUSHs(sv_setref_pv(newSVpvs(""), bless_header, (void *)hcopy));
#ifdef HDRPMMEM
    PRINTF_NEW(bless_header, hcopy, hcopy->nrefs);
#endif

void
Header_string(h, no_header_magic = 0)
    Header h
    int no_header_magic
    PREINIT:
    char * string = NULL;
    char * ptr = NULL;
#if defined(RPM4_18_0)
    unsigned int hsize = 0;
#else
    int hsize = 0;
#endif
    PPCODE:
#if defined(RPM4_18_0)
    string = headerExport(h, &hsize);
#else
    hsize = headerSizeof(h, no_header_magic ? HEADER_MAGIC_NO : HEADER_MAGIC_YES);
    string = headerUnload(h);
#endif
    if (! no_header_magic) {
#if defined(RPM4_18_0)
        hsize +=sizeof(header_magic); // Adjust for header_magic
#endif
        ptr = malloc(hsize);
        memcpy(ptr, header_magic, 8);
        memcpy(ptr + 8, string, hsize - 8);
    }
    mXPUSHs(newSVpv(ptr ? ptr : string, hsize));
    free(string);
    free(ptr);

int
Header_removetag(h, sv_tag)
    Header h
    SV * sv_tag
    PREINIT:
    rpmTag tag = -1;
    CODE:
    if (SvIOK(sv_tag)) {
        tag = SvIV(sv_tag);
    } else if (SvPOK(sv_tag)) {
        tag = rpmTagGetValue(SvPV_nolen(sv_tag));
    }
    if (tag > 0)
        RETVAL = headerDel(h, tag);
    else
        RETVAL = 1;
    OUTPUT:
    RETVAL

int
Header_addtag(h, sv_tag, sv_tagtype, ...)
    Header h
    SV * sv_tag
    SV * sv_tagtype
    PREINIT:
    char * value;
    int ivalue;
    int i;
    rpmTag tag = -1;
    rpmTagType tagtype = RPM_NULL_TYPE;
    STRLEN len;
    CODE:
    if (SvIOK(sv_tag)) {
        tag = SvIV(sv_tag);
    } else if (SvPOK(sv_tag)) {
        tag = rpmTagGetValue(SvPV_nolen(sv_tag));
    }
    tagtype = sv2tagtype(sv_tagtype);
    if (tag > 0)
        RETVAL = 1;
    else
        RETVAL = 0;
    /* if (tag == RPMTAG_OLDFILENAMES)
        expandFilelist(h); */
    for (i = 3; (i < items) && RETVAL; i++) {
       struct rpmtd_s td = {
           .tag = tag,
           .type = tagtype,
           .data = (void *) &value,
           .count = 1,
        };
        switch (tagtype) {
            case RPM_CHAR_TYPE:
            case RPM_INT8_TYPE:
            case RPM_INT16_TYPE:
            case RPM_INT32_TYPE:
                ivalue = SvUV(ST(i));
                td.data = (void *) &ivalue;
                RETVAL = headerPut(h, &td, HEADERPUT_APPEND);
                break;
            case RPM_STRING_TYPE:
            case RPM_BIN_TYPE:
                value = (char *)SvPV(ST(i), len);
                RETVAL = headerPutString(h, tag, value);
                break;
            case RPM_STRING_ARRAY_TYPE:
                value = SvPV_nolen(ST(i));
                RETVAL = headerPut(h, &td, HEADERPUT_APPEND);
                break;
            default:
                value = SvPV_nolen(ST(i));
                RETVAL = headerPut(h, &td, HEADERPUT_APPEND);
                break;
        }
    }
    /* if (tag == RPMTAG_OLDFILENAMES) {
        compressFilelist(h); 
    } */
    OUTPUT:
    RETVAL
    
void
Header_listtag(h)
    Header h
    PREINIT:
    HeaderIterator iterator;
    struct rpmtd_s td;
    PPCODE:
    iterator = headerInitIterator(h);
    while (headerNext(iterator, &td)) {
        mXPUSHs(newSViv(rpmtdTag(&td)));
        rpmtdFreeData(&td);
    }
    rpmtdFreeData(&td);
    headerFreeIterator(iterator);
    
int
Header_hastag(h, sv_tag)
    Header h
    SV * sv_tag
    PREINIT:
    rpmTag tag = -1;
    CODE:
    if (SvIOK(sv_tag)) {
        tag = SvIV(sv_tag);
    } else if (SvPOK(sv_tag)) {
        tag = rpmTagGetValue(SvPV_nolen(sv_tag));
    }    
    if (tag > 0)
        RETVAL = headerIsEntry(h, tag);
    else
        RETVAL = -1;
    OUTPUT:
    RETVAL
 
# Return the tag value in headers
void
Header_tag(h, sv_tag)
    Header h
    SV * sv_tag
    PREINIT:
    rpmTag tag = -1;
    PPCODE:
    if (SvIOK(sv_tag)) {
        tag = SvIV(sv_tag);
    } else if (SvPOK(sv_tag)) {
        tag = rpmTagGetValue(SvPV_nolen(sv_tag));
    }
    if (tag > 0) {
        struct rpmtd_s val;
        if (headerGet(h, tag, &val, HEADERGET_DEFAULT)) {
            int type = rpmtdType(&val);
            int n = rpmtdCount(&val);

            switch(type) {
                case RPM_STRING_ARRAY_TYPE:
                    {
                        int i;

                        EXTEND(SP, n);
                        rpmtdInit(&val);
        
                        for (i = 0; i < n; i++)
                            mPUSHs(newSVpv(rpmtdNextString(&val), 0));
                    }
                break;
                case RPM_STRING_TYPE:
                    mPUSHs(newSVpv(rpmtdGetString(&val), 0));
                break;
                case RPM_CHAR_TYPE:
                case RPM_INT8_TYPE:
                case RPM_INT16_TYPE:
                case RPM_INT32_TYPE:
                    {
                        int i;

                        EXTEND(SP, n);
                        rpmtdInit(&val);

                        for (i = 0; i < n; i++) {
                            rpmtdNext(&val);
                            mPUSHs(newSViv(rpmtdGetNumber(&val)));
                        }
                    }
                break;
                case RPM_BIN_TYPE:
                    /* XXX HACK ALERT: element field abused as no. bytes of binary data. */
                    mPUSHs(newSVpv((char *)val.data, val.count));
                break;
                default:
                    croak("unknown rpm tag type %d", type);
            }
            rpmtdFreeData(&val);
        }
    }

unsigned int
Header_tagtype(h, sv_tag)
    Header h
    SV * sv_tag
    PREINIT:
    rpmTag tag = -1;
    struct rpmtd_s td;
    CODE:
    if (SvIOK(sv_tag)) {
        tag = SvIV(sv_tag);
    } else if (SvPOK(sv_tag)) {
        tag = rpmTagGetValue(SvPV_nolen(sv_tag));
    }
    RETVAL = RPM_NULL_TYPE;
    if (tag > 0)
        if (headerGet(h, tag, &td, HEADERGET_DEFAULT))
            RETVAL = rpmtdType(&td);
    rpmtdFreeData(&td);
    OUTPUT:
    RETVAL
    
void
Header_queryformat(h, query)
    Header h
    char * query
    PREINIT:
    char *s = NULL;
    PPCODE:
    s = headerFormat(h, query,
            NULL);
    mXPUSHs(newSVpv(s, 0));
    free(s);

void
Header_fullname(h)
    Header h
    ALIAS:
       nevr= 1
    PREINIT:
    I32 gimme = GIMME_V;
    PPCODE:
    if (h) {
        if (gimme == G_SCALAR) {
          char *nvr = headerGetAsString(h, RPMTAG_NVR);
          if (ix == 1) {
            mXPUSHs(newSVpv(nvr, 0));
          } else {
            mXPUSHs(newSVpvf("%s.%s", nvr, get_arch(h)));
          }
          free(nvr);
        } else if (gimme == G_ARRAY) {
            EXTEND(SP, 4);
            mPUSHs(newSVpv(get_name(h, RPMTAG_NAME), 0));
            mPUSHs(newSVpv(get_name(h, RPMTAG_VERSION), 0));
            mPUSHs(newSVpv(get_name(h, RPMTAG_RELEASE), 0));
            mPUSHs(newSVpv(get_arch(h), 0));
        }
    }

int
Header_issrc(h)
    Header h
    CODE:
    RETVAL = !headerIsEntry(h, RPMTAG_SOURCERPM);
    OUTPUT:
    RETVAL

# Dependancies versions functions

int
Header_compare(h1, h2)
    Header h1
    Header h2
    CODE:
    RETVAL = rpmVersionCompare(h1, h2);
    OUTPUT:
    RETVAL
    
void
Header_dep(header, type, scaremem = O_SCAREMEM)
    Header header
    SV * type
    int scaremem
    PREINIT:
    rpmds ds;
    rpmTag tag;
    PPCODE:
    tag = sv2deptag(type);
    ds = rpmdsNew(header, tag, scaremem);
    ds = rpmdsInit(ds);
    if (ds != NULL)
        if (rpmdsNext(ds) >= 0) {
            mXPUSHs(sv_setref_pv(newSVpvs(""), bless_rpmds, ds));
#ifdef HDRPMMEM
            PRINTF_NEW(bless_rpmds, ds, ds->nrefs);
#endif

        }

void
Header_files(header, scaremem = O_SCAREMEM)
    Header header
    int scaremem
    PREINIT:
    rpmfi Files = NULL;
    rpmts ts = NULL;  /* NULL;  setting this to NULL skip path relocation
                       * maybe a good deal is Header::Files(header, Dep = NULL) */
    PPCODE:
#ifdef HDLISTDEBUG
    PRINTF_CALL;
#endif 
    Files = rpmfiNew(ts, header, RPMTAG_BASENAMES, scaremem);
    if (Files != NULL && (Files = rpmfiInit(Files, 0)) != NULL && rpmfiNext(Files) >= 0) {
        SPAGAIN;
        XPUSHs(sv_setref_pv(sv_newmortal(), bless_rpmfi, (void *)Files));
#ifdef HDRPMMEM
        PRINTF_NEW(bless_rpmfi, Files, Files->nrefs);
#endif
    }

void
Header_hchkdep(h1, h2, type)
    Header h1
    Header h2
    SV * type
    PREINIT:
    rpmds ds = NULL;
    rpmds pro = NULL;
    rpmTag tag;
    PPCODE:
    tag = sv2deptag(type);
    ds = rpmdsNew(h1, tag, SCAREMEM);
    pro = rpmdsNew(h2, RPMTAG_PROVIDENAME, SCAREMEM);
#ifdef HDLISTDEBUG
    fprintf(stderr, "HDEBUG: Header::hchkdep %d: %s vs %s %p\n", tag, hGetNEVR(h1, NULL), hGetNEVR(h2, NULL), ds);
#endif
    if (ds != NULL) {
        rpmdsInit(ds);
        while (rpmdsNext(ds) >= 0) {
            rpmdsInit(pro);
            while (rpmdsNext(pro) >= 0) {
                if (rpmdsCompare(ds,pro)) {
                mXPUSHs(newSVpv(rpmdsDNEVR(ds), 0));
#ifdef HDLISTDEBUG
                fprintf(stderr, "HDEBUG: Header::hchkdep match %s %s p in %s\n", rpmdsDNEVR(ds), rpmdsDNEVR(pro), hGetNEVR(h2, NULL));
#endif
                break;
                }
            }
        }
    }
    pro = rpmdsFree(pro);
    ds = rpmdsFree(ds);

int
Header_matchdep(header, Dep, sv_nopromote = NULL)
    Header header
    SV * sv_nopromote
    rpmds Dep
    PREINIT:
    int nopromote = 0;
    CODE:
    if (sv_nopromote != NULL)
        nopromote = SvIV(sv_nopromote);    
    RETVAL = _header_vs_dep(header, Dep, nopromote);
    OUTPUT:
    RETVAL

int
Header_namematchdep(header, Dep, sv_nopromote = NULL)
    Header header
    rpmds Dep
    SV * sv_nopromote
    PREINIT:
    int nopromote = 0;
    CODE:
    if (sv_nopromote != NULL)
        nopromote = SvIV(sv_nopromote);
    RETVAL = _headername_vs_dep(header, Dep, nopromote); /* return 1 if match */
    OUTPUT:
    RETVAL
    
# DB functions
MODULE = RPM4     PACKAGE = RPM4
    
int
rpmdbinit(rootdir = NULL)
    char * rootdir
    PREINIT:
    rpmts ts = rpmtsCreate();
    CODE:
    if (rootdir)
        rpmtsSetRootDir(ts, rootdir);
    /* rpm{db,ts}init is deprecated, we open a database with create flags
     *  and close it */
    /* 0 on success */
    RETVAL = rpmtsInitDB(ts, 0644);
    ts = rpmtsFree(ts);
    OUTPUT:
    RETVAL

int
rpmdbverify(rootdir = NULL)
    char * rootdir
    PREINIT:
    rpmts ts = rpmtsCreate();
    CODE:
    if (rootdir)
        rpmtsSetRootDir(ts, rootdir);
    /* 0 on success */
    RETVAL = rpmtsVerifyDB(ts);
    ts = rpmtsFree(ts);
    OUTPUT:
    RETVAL

int
rpmdbrebuild(rootdir = NULL)
    char * rootdir
    PREINIT:
    rpmts ts = rpmtsCreate();
    CODE:
    if (!rootdir) rootdir="/";
    if (rootdir) {
        rpmtsSetRootDir(ts, rootdir);
    }
    /* 0 on success */
    RETVAL = rpmtsRebuildDB(ts);
    ts = rpmtsFree(ts);
    OUTPUT:
    RETVAL

#ifdef HHACK
void
emptydb()
    PREINIT:
    rpmts ts = rpmtsCreate();
    PPCODE:
    mXPUSHs(sv_setref_pv(newSVpvs(""), bless_rpmts, (void *)ts));
#ifdef HDRPMMEM
    PRINTF_NEW(bless_rpmts, ts, ts->nrefs);
#endif


#endif
    
void
newdb(write = 0, rootdir = NULL)
    int write
    char * rootdir
    PREINIT:
    rpmts ts = rpmtsCreate();
    PPCODE:
    if (rootdir)
        rpmtsSetRootDir(ts, rootdir);
    
    rpmtsSetVSFlags(ts, RPMTRANS_FLAG_NONE);
    /* is O_CREAT a good idea here ? */
    /* is the rpmtsOpenDB really need ? */
    if (rpmtsOpenDB(ts, write ? O_RDWR | O_CREAT : O_RDONLY) == 0) {
        mXPUSHs(sv_setref_pv(newSVpvs(""), bless_rpmts, (void *)ts));
#ifdef HDRPMMEM
        PRINTF_NEW(bless_rpmts, ts, ts->nrefs);
#endif
    } else {
        ts = rpmtsFree(ts);
    }

MODULE = RPM4     PACKAGE = RPM4::Transaction    PREFIX = Ts_

void
Ts_new(perlclass, rootdir = NULL)
    char * perlclass
    char * rootdir
    PREINIT:
    rpmts ts = rpmtsCreate();
    PPCODE:
    rpmtsSetRootDir(ts, rootdir);
    mXPUSHs(sv_setref_pv(newSVpvs(""), perlclass, (void *)ts));
 
void
Ts_DESTROY(ts)
    rpmts ts
    CODE:
#ifdef HDRPMMEM
    PRINTF_FREE(bless_rpmts, ts, ts->nrefs);
#endif
    ts = rpmtsFree(ts);

# Function to control RPM4::Transaction behaviour

int
Ts_vsflags(ts, sv_vsflags = NULL)
    rpmts ts
    SV * sv_vsflags
    PREINIT:
    rpmVSFlags vsflags; 
    CODE:
    if (sv_vsflags != NULL) {
        vsflags = sv2vsflags(sv_vsflags);
        RETVAL = rpmtsSetVSFlags(ts, vsflags);
    } else {
        RETVAL = rpmtsVSFlags(ts);
    }
    OUTPUT:
    RETVAL

int
Ts_transflag(ts, sv_transflag = NULL)
    rpmts ts
    SV * sv_transflag
    PREINIT:
    rpmtransFlags transflags;
    CODE:
    if (sv_transflag != NULL) {
        transflags = sv2transflags(sv_transflag);
        RETVAL = rpmtsSetFlags(ts, transflags);
    } else {
        RETVAL = rpmtsFlags(ts);
    }
    OUTPUT:
    RETVAL
    
int
Ts_traverse(ts, callback = NULL, sv_tagname = NULL, sv_tagvalue = NULL, keylen = 0, sv_exclude = NULL)
    rpmts ts
    SV * callback
    SV * sv_tagname
    SV * sv_tagvalue
    SV * sv_exclude
    int keylen
    PREINIT:
    rpmDbiTagVal tag;
    void * value = NULL;
    rpmdbMatchIterator mi;
    Header header;
    int rc = 1;

src/RPM4.xs  view on Meta::CPAN

                i = SvIV(sv_tagvalue);
                value = &i;
                keylen = sizeof(i);
        } else {
                value = (void *) SvPV_nolen(sv_tagvalue);
        }
    }
    
    RETVAL = 0;
    if (tag >= 0) {
        mi = rpmtsInitIterator(ts, tag, value, keylen);
        if (sv_exclude != NULL && SvOK(sv_exclude) && SvTYPE(SvRV(sv_exclude)) == SVt_PVAV) {
            av_exclude = (AV*)SvRV(sv_exclude);
            exclude = malloc((av_len(av_exclude)+1) * sizeof(int));
            for (i = 0; i <= av_len(av_exclude); i++) {
                SV **isv = av_fetch(av_exclude, i, 0);
                exclude[i] = SvUV(*isv);
            }
            //FIXME: rpmtsPrunedIterator() is rpmlib internal only:
            //rpmtsPrunedIterator(ts, exclude, av_len(av_exclude) + 1);
        }
        while (rc && ((header = rpmdbNextIterator(mi)) != NULL)) {
            RETVAL++;
            if (callback != NULL && SvROK(callback)) {
                ENTER;
                SAVETMPS;
                PUSHMARK(SP);
                mXPUSHs(sv_setref_pv(newSVpvs(""), bless_header, headerLink(header)));
#ifdef HDRPMMEM
                PRINTF_NEW(bless_header, header, header->nrefs);
#endif
                mXPUSHs(newSVuv(rpmdbGetIteratorOffset(mi)));
                PUTBACK;
                count = call_sv(callback, G_SCALAR);
                SPAGAIN;
                if (tag == RPMDBI_PACKAGES && value != NULL) {
                    rc = 0;
                } else if (count == 1) {
                    rc = POPi;
                }
                FREETMPS;
                LEAVE;
                
            }
        }
        if (exclude != NULL) free(exclude);
        rpmdbFreeIterator(mi);
    } else
        RETVAL = -1;
    ts = rpmtsFree(ts);
    OUTPUT:
    RETVAL

void
Ts_get_header(ts, off)
    rpmts ts
    int off
    PREINIT:
    rpmdbMatchIterator mi;
    Header header;
    PPCODE:
    mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, &off, sizeof(off));
    if ((header = rpmdbNextIterator(mi)) != NULL) {
        mXPUSHs(sv_setref_pv(newSVpvs(""), bless_header, headerLink(header)));
#ifdef HDRPMMEM
        PRINTF_NEW(bless_header, header, header->nrefs);
#endif
    }
    rpmdbFreeIterator(mi);    

int
Ts_transadd(ts, header, key = NULL, upgrade = 1, sv_relocation = NULL, force = 0)
    rpmts ts
    Header header
    char * key
    int upgrade
    SV * sv_relocation
    int force
    PREINIT:
    rpmRelocation * relocations = NULL;
    HV * hv_relocation;
    HE * he_relocation;
    int i = 0;
    I32 len;
    
    CODE:

    if (key != NULL)
        key = strdup(key);

    /* Relocation settings */
    if (sv_relocation && SvOK(sv_relocation) && !force) {
/*        if (! (headerGetEntry(eiu->h, RPMTAG_PREFIXES, &pft,
                       (void **) &paths, &c) && (c == 1))) { */
        if (! headerIsEntry(header, RPMTAG_PREFIXES)) {
            rpmlog(RPMLOG_ERR,
                   _("package %s is not relocatable\n"), "");
            XPUSHi((IV)1);
            XSRETURN(1);
        }
        if (SvTYPE(sv_relocation) == SVt_PV) {
            /* String value, assume a prefix */
            relocations = malloc(2 * sizeof(*relocations));
            relocations[0].oldPath = NULL;
            relocations[0].newPath = SvPV_nolen(sv_relocation);
            relocations[1].oldPath = relocations[1].newPath = NULL;
        } else if (SvTYPE(SvRV(sv_relocation)) == SVt_PVHV) {
            hv_relocation = (HV*)SvRV(sv_relocation);
            hv_iterinit(hv_relocation);
            while ((he_relocation = hv_iternext(hv_relocation)) != NULL) {
                relocations = realloc(relocations, sizeof(*relocations) * (++i));
                relocations[i-1].oldPath = NULL;
                relocations[i-1].newPath = NULL;
                relocations[i-1].oldPath = hv_iterkey(he_relocation, &len);
                relocations[i-1].newPath = SvPV_nolen(hv_iterval(hv_relocation, he_relocation));
            }
            /* latest relocation is identify by NULL setting */
            relocations = realloc(relocations, sizeof(*relocations) * (++i));
            relocations[i-1].oldPath = relocations[i-1].newPath = NULL;
        } else {
            croak("latest argument is set but is not an array ref or a string");

src/RPM4.xs  view on Meta::CPAN

            RETVAL ++;
        }
    }
    rpmdbFreeIterator(mi);
    OUTPUT:
    RETVAL

int
Ts_traverse_transaction(ts, callback, type = 0)
    rpmts ts
    SV * callback
    int type
    PREINIT:
    rpmtsi pi;
    rpmte  Te;
    CODE:
    ts = rpmtsLink(ts);
    pi = rpmtsiInit(ts);
    RETVAL = 0;
    while ((Te = rpmtsiNext(pi, type)) != NULL) {
        RETVAL++;
        if (callback != NULL && SvROK(callback)) {
            ENTER;
            SAVETMPS;
            PUSHMARK(SP);
#ifdef HDLISTDEBUG
            PRINTF_CALL;
#endif
            mXPUSHs(sv_setref_pv(newSVpvs(""), "RPM4::Db::Te", Te));
            PUTBACK;
            call_sv(callback, G_DISCARD | G_SCALAR);
            SPAGAIN;
            FREETMPS;
            LEAVE;
        }
    }
    pi = rpmtsiFree(pi);
    ts = rpmtsFree(ts);
    OUTPUT:
    RETVAL
        
int
Ts_transcheck(ts)
    rpmts ts
    CODE:
    RETVAL = rpmtsCheck(ts);
    OUTPUT:
    RETVAL

int
Ts_transorder(ts)
    rpmts ts
    CODE:
    RETVAL = rpmtsOrder(ts);
    OUTPUT:
    RETVAL

void
Ts_transclean(ts)
    rpmts ts
    PPCODE:
    rpmtsClean(ts);
        
int
Ts_transrun(ts, callback, ...)
    rpmts ts
    SV * callback
    PREINIT:
    int i;
    rpmprobFilterFlags probFilter = RPMPROB_FILTER_NONE;
    rpmInstallFlags install_flags = INSTALL_NONE;
    rpmps ps;
    CODE:
    ts = rpmtsLink(ts);
    if (!SvOK(callback)) { /* undef value */
        rpmtsSetNotifyCallback(ts,
                rpmShowProgress,
                (void *) ((long) INSTALL_LABEL | INSTALL_HASH | INSTALL_UPGRADE));
    } else if (SvTYPE(SvRV(callback)) == SVt_PVCV) { /* ref sub */
        rpmtsSetNotifyCallback(ts,
                transCallback, 
                (void *)
                    callback);
    } else if (SvTYPE(SvRV(callback)) == SVt_PVAV) { /* array ref */
        install_flags = sv2constant(callback, "rpminstallinterfaceflags");
        rpmtsSetNotifyCallback(ts,
                rpmShowProgress,
                (void *) ((long) install_flags));
    } else {
        croak("Wrong parameter given");
    }
    
    for (i = 2; i < items; i++)
        probFilter |= sv2constant(ST(i), "rpmprobfilterflags");

    ps = rpmtsProblems(ts);
    RETVAL = rpmtsRun(ts, ps, probFilter);
    ps = rpmpsFree(ps);
    ts = rpmtsFree(ts);
    OUTPUT:
    RETVAL

# get from transaction a problem set
void
Ts__transpbs(ts)
    rpmts ts
    PREINIT:
    rpmps ps;
    PPCODE:
    ps = rpmtsProblems(ts);
    if (ps && rpmpsNumProblems(ps)) /* if no problem, return undef */
        mXPUSHs(sv_setref_pv(newSVpvs(""), bless_rpmps, ps));
    
int
Ts_importpubkey(ts, filename)
    rpmts ts
    char * filename
    PREINIT:
    uint8_t *pkt = NULL;
    size_t pktlen = 0;
    int rc;
    CODE:
    rpmtsClean(ts);
    
    if ((rc = pgpReadPkts(filename, (uint8_t ** ) &pkt, &pktlen)) <= 0) {
        RETVAL = 1;
    } else if (rc != PGPARMOR_PUBKEY) {
        RETVAL = 1;
    } else if (rpmtsImportPubkey(ts, pkt, pktlen) != RPMRC_OK) {
        RETVAL = 1;
    } else {
        RETVAL = 0;
    }
    free(pkt);
    OUTPUT:
    RETVAL
   
void
Ts_checkrpm(ts, filename, sv_vsflags = NULL)
    rpmts ts
    char * filename
    SV * sv_vsflags
    PREINIT:
    rpmVSFlags vsflags = RPMVSF_DEFAULT;
    rpmVSFlags oldvsflags = RPMVSF_DEFAULT;
    PPCODE:
    oldvsflags = rpmtsVSFlags(ts); /* keep track of old settings */
    if (sv_vsflags != NULL) {
	    vsflags = sv2vsflags(sv_vsflags);
        rpmtsSetVSFlags(ts, vsflags);
    }
    PUTBACK;
    _rpm2header(ts, filename, 1); /* Rpmread header is not the most usefull, 
                                   * but no other function in rpmlib allow this :( */
    SPAGAIN;
    rpmtsSetVSFlags(ts, oldvsflags); /* resetting in case of change */
    
void
Ts_transreset(ts)
    rpmts ts
    PPCODE:
    rpmtsEmpty(ts);
    rpmtsSetRootDir(ts, "/");

# Remaping function:

# RPM4::rpm2header(filename); # Reusing existing RPM4::Transaction
void
Ts_rpm2header(ts, filename)
    rpmts ts
    char * filename
    PPCODE:
    _rpm2header(ts, filename, 0);
    SPAGAIN;

# RPM4::Spec::specbuild([ buildflags ]); Reusing existing RPM4::Transaction
int
Ts_specbuild(ts, spec, sv_buildflags)
    rpmts ts
    rpmSpec spec
    SV * sv_buildflags
    CODE:
    RETVAL = _specbuild(spec, sv_buildflags);
    OUTPUT:
    RETVAL

void
Ts_installsrpm(ts, filename)
    rpmts ts
    char * filename
    PPCODE:
    PUTBACK;
    _installsrpms(ts, filename);
    SPAGAIN;

MODULE = RPM4 	PACKAGE = RPM4::Db::Te  PREFIX = Te_

void
Te_DESTROY(Te)
    rpmte Te
    CODE:
#ifdef HDRPMMEM
/*    PRINTF_FREE(RPM4::Db::Te, -1); */
#endif
    /* Don't do that !  *
    Te = rpmteFree(Te); */

int
Te_type(Te)
    rpmte Te
    CODE:
    RETVAL = rpmteType(Te);
    OUTPUT:
    RETVAL

void
Te_name(Te)
    rpmte Te
    PPCODE:
    mXPUSHs(newSVpv(rpmteN(Te), 0));

void
Te_version(Te)
    rpmte Te
    PPCODE:
    mXPUSHs(newSVpv(rpmteV(Te), 0));

void
Te_release(Te)
    rpmte Te
    PPCODE:
    mXPUSHs(newSVpv(rpmteR(Te), 0));

void
Te_epoch(Te)
    rpmte Te
    PPCODE:
    mXPUSHs(newSVpv(rpmteE(Te), 0));

void
Te_arch(Te)
    rpmte Te
    PPCODE:
    mXPUSHs(newSVpv(rpmteA(Te), 0));

void
Te_os(Te)
    rpmte Te
    PPCODE:
    mXPUSHs(newSVpv(rpmteO(Te), 0));

void
Te_fullname(Te)
    rpmte Te
    PREINIT:
    I32 gimme = GIMME_V;
    PPCODE:
    if (gimme == G_SCALAR) {
        mXPUSHs(newSVpvf("%s-%s-%s.%s",
            rpmteN(Te), rpmteV(Te), rpmteR(Te), rpmteA(Te)));
    } else {
        mXPUSHs(newSVpv(rpmteN(Te), 0));
        mXPUSHs(newSVpv(rpmteV(Te), 0));
        mXPUSHs(newSVpv(rpmteR(Te), 0));
        mXPUSHs(newSVpv(rpmteA(Te), 0));
    }

void
Te_size(Te)
    rpmte Te
    PPCODE:
    mXPUSHs(newSVuv(rpmtePkgFileSize(Te)));

void
Te_dep(Te, type)
    rpmte Te
    SV * type
    PREINIT:
    rpmds ds;
    rpmTag tag;
    PPCODE:
    tag = sv2deptag(type);
    ds = rpmteDS(Te, tag);
    if (ds != NULL)
        if (rpmdsNext(ds) >= 0) {
            mXPUSHs(sv_setref_pv(newSVpvs(""), bless_rpmds, ds));
#ifdef HDRPMMEM
            PRINTF_NEW(bless_rpmds, ds, ds->nrefs);
#endif
        }

void
Te_files(Te)
    rpmte Te
    PREINIT:
#if defined(RPM4_12_0)
    rpmfiles Files;
#endif
    rpmfi fi;
    PPCODE:
#if defined(RPM4_12_0)
    Files = rpmteFiles(Te);
    fi = rpmfilesIter(Files, RPMFI_ITER_FWD);
    if (fi != NULL && rpmfiNext(fi) >= 0) {
#else
    fi = rpmteFI(Te);
    if ((fi = rpmfiInit(fi, 0)) != NULL && rpmfiNext(fi) >= 0) {
#endif
        mXPUSHs(sv_setref_pv(newSVpvs(""), bless_rpmfi, fi));
#ifdef HDRPMMEM
        PRINTF_NEW(bless_rpmfi, Files, Files->nrefs);
#endif
    }
#if defined(RPM4_12_0)
    rpmfilesFree(Files);
#endif
    
MODULE = RPM4     PACKAGE = RPM4

# Return a new Dep object
void
newdep(sv_depTag, Name,  sv_sense = NULL, sv_evr = NULL)
    SV * sv_depTag
    char * Name
    SV * sv_evr
    SV * sv_sense
    PPCODE:
    PUTBACK;
    _newdep(sv_depTag, Name,  sv_sense, sv_evr);
    SPAGAIN;

void
rpmlibdep()
    PREINIT:
    rpmds Dep = NULL;
    PPCODE:
#if 0
    rpmds next;
    const char ** provNames;
    int * provFlags;
    const char ** provVersions;
    int num = 0;
    int i;
    num = rpmGetRpmlibProvides(&provNames, &provFlags, &provVersions);
    for (i = 0; i < num; i++) {
#ifdef HDLISTDEBUG
        fprintf(stderr, "HDEBUG: rpmlibdep %s %s %d\n", provNames[i], provVersions[i], provFlags[i]);
#endif
        next = rpmdsSingle(RPMTAG_PROVIDENAME, provNames[i], provVersions[i], provFlags[i]);
        rpmdsMerge(&Dep, next);
        next = rpmdsFree(next);
    }
    if (Dep != NULL) {
        Dep = rpmdsInit(Dep);
        if (rpmdsNext(Dep) >= 0) {
            mXPUSHs(sv_setref_pv(newSVpvs(""), bless_rpmds, Dep));
#ifdef HDRPMMEM
            PRINTF_NEW(bless_rpmds, Dep, Dep->nrefs);
#endif
        }
    }
#else
    if (!rpmdsRpmlib(&Dep, NULL))
        mXPUSHs(sv_setref_pv(newSVpvs(""), bless_rpmds, Dep));
#endif

MODULE = RPM4 	PACKAGE = RPM4::Header::Dependencies  PREFIX = Dep_

void
Dep_newsingle(perlclass, sv_tag, name, sv_sense = NULL, sv_evr = NULL)
    char * perlclass
    SV * sv_tag
    char * name
    SV * sv_sense
    SV * sv_evr
    PPCODE:
    PUTBACK;
    _newdep(sv_tag, name, sv_sense, sv_evr);
    SPAGAIN;

void
Dep_DESTROY(Dep)
    rpmds Dep
    CODE:
#ifdef HDRPMMEM
    PRINTF_FREE(bless_rpmds, Dep, Dep->nrefs);
#endif
    Dep = rpmdsFree(Dep);

int 
Dep_count(Dep)
    rpmds Dep
    CODE:
    RETVAL = rpmdsCount(Dep);
    OUTPUT:
    RETVAL

int
Dep_move(Dep, index = 0)
    rpmds Dep
    int index
    CODE:
    if (index == -1) /* -1 do nothing and give actual index */
        RETVAL = rpmdsIx(Dep);
    else
        RETVAL = rpmdsSetIx(Dep, index);
    OUTPUT:
    RETVAL

void
Dep_init(Dep)
    rpmds Dep
    CODE:
#ifdef HDLISTDEBUG
    PRINTF_CALL;
#endif
    rpmdsInit(Dep);
        
int
Dep_next(Dep)
    rpmds Dep
    CODE:
#ifdef HDLISTDEBUG
    PRINTF_CALL;
#endif
	RETVAL = rpmdsNext(Dep);
    OUTPUT:
    RETVAL

int
Dep_hasnext(Dep)
    rpmds Dep
    CODE:
    RETVAL = rpmdsNext(Dep) > -1;
    OUTPUT:
    RETVAL
        
int
Dep_color(Dep)
    rpmds Dep
    CODE:
    RETVAL = rpmdsColor(Dep);
    OUTPUT:
    RETVAL
        
int
Dep_find(Dep, depb)
    rpmds Dep
    rpmds depb
    CODE:
    RETVAL = rpmdsFind(Dep, depb);
    OUTPUT:
    RETVAL

int
Dep_merge(Dep, depb)
    rpmds Dep
    rpmds depb
    CODE:
    RETVAL = rpmdsMerge(&Dep, depb);
    OUTPUT:
    RETVAL
        
int
Dep_overlap(Dep1, Dep2)
    rpmds Dep1
    rpmds Dep2
    CODE:
    CHECK_RPMDS_IX(Dep1);
    CHECK_RPMDS_IX(Dep2);
    RETVAL = rpmdsCompare(Dep1, Dep2);
    OUTPUT:
    RETVAL

void
Dep_info(Dep)
    rpmds Dep
    PREINIT:
    rpmsenseFlags flag;
    I32 gimme = GIMME_V;
    PPCODE:
#ifdef HDLISTDEBUG
    PRINTF_CALL;
#endif
    CHECK_RPMDS_IX(Dep);
    if (gimme == G_SCALAR) {
        mXPUSHs(newSVpv(rpmdsDNEVR(Dep), 0));
    } else {
        switch (rpmdsTagN(Dep)) {
            case RPMTAG_PROVIDENAME:
                mXPUSHs(newSVpv("P", 0));
            break;
            case RPMTAG_REQUIRENAME:
                mXPUSHs(newSVpv("R", 0));
            break;
            case RPMTAG_CONFLICTNAME:
                mXPUSHs(newSVpv("C", 0));
            break;
            case RPMTAG_OBSOLETENAME:
                mXPUSHs(newSVpv("O", 0));
            break;
            case RPMTAG_TRIGGERNAME:
                mXPUSHs(newSVpv("T", 0));
            break;
            default:
            break;
        }
        mXPUSHs(newSVpv(rpmdsN(Dep), 0));
        flag = rpmdsFlags(Dep);
        mXPUSHs(newSVpvf("%s%s%s",
                        flag & RPMSENSE_LESS ? "<" : "",
                        flag & RPMSENSE_GREATER ? ">" : "",
                        flag & RPMSENSE_EQUAL ? "=" : ""));
        mXPUSHs(newSVpv(rpmdsEVR(Dep), 0));
    }

void
Dep_tag(Dep)
    rpmds Dep
    PPCODE:
    mXPUSHs(newSViv(rpmdsTagN(Dep)));
    
void
Dep_name(Dep)
    rpmds Dep
    PPCODE:
#ifdef HDLISTDEBUG
    PRINTF_CALL;
#endif
    CHECK_RPMDS_IX(Dep);
    mXPUSHs(newSVpv(rpmdsN(Dep), 0));

void
Dep_flags(Dep)
    rpmds Dep
    PPCODE:
    CHECK_RPMDS_IX(Dep);
    mXPUSHs(newSViv(rpmdsFlags(Dep)));

void
Dep_evr(Dep)
    rpmds Dep
    PPCODE:
    CHECK_RPMDS_IX(Dep);
    mXPUSHs(newSVpv(rpmdsEVR(Dep), 0));

#ifndef RPM4_19_0
int
Dep_nopromote(Dep, sv_nopromote = NULL)
    rpmds Dep
    SV * sv_nopromote
    CODE:
    if (sv_nopromote == NULL) {
        RETVAL = rpmdsNoPromote(Dep);
    } else {
        RETVAL = rpmdsSetNoPromote(Dep, SvIV(sv_nopromote));
    }
    OUTPUT:
    RETVAL

#endif
    
int
Dep_add(Dep, name,  sv_sense = NULL, sv_evr = NULL)
    rpmds Dep
    char * name
    SV * sv_evr
    SV * sv_sense
    PREINIT:
    rpmsenseFlags sense = RPMSENSE_ANY;
    rpmds Deptoadd;
    char * evr = NULL;
    CODE:
    RETVAL = 0;
    if (sv_sense && SvOK(sv_sense))
        sense = sv2sens(sv_sense);
    if (sv_evr && SvOK(sv_evr))
        evr = SvPV_nolen(sv_evr);
    Deptoadd = rpmdsSingle(rpmdsTagN(Dep), name, evr ? evr : "", sense);
    if (Deptoadd) {
        rpmdsMerge(&Dep, Deptoadd);
        Deptoadd = rpmdsFree(Deptoadd);
        RETVAL = 1;
    }
    OUTPUT:
    RETVAL
        
int
Dep_matchheader(Dep, header, sv_nopromote = NULL)
    Header header
    SV * sv_nopromote
    rpmds Dep
    PREINIT:
    int nopromote = 0;
    CODE:
    if (sv_nopromote != NULL)
        nopromote = SvIV(sv_nopromote);    
    RETVAL = _header_vs_dep(header, Dep, nopromote);
    OUTPUT:
    RETVAL

int
Dep_matchheadername(Dep, header, sv_nopromote = NULL)
    rpmds Dep
    Header header
    SV * sv_nopromote
    PREINIT:
    int nopromote = 0;
    CODE:
    if (sv_nopromote != NULL)
        nopromote = SvIV(sv_nopromote);
    RETVAL = _headername_vs_dep(header, Dep, nopromote);
    OUTPUT:
    RETVAL
        
MODULE = RPM4 	PACKAGE = RPM4::Header::Files  PREFIX = Files_

void
Files_DESTROY(Files)
    rpmfi Files
    PPCODE:
#ifdef HDRPMMEM
    PRINTF_FREE(bless_rpmfi, Files, Files->nrefs);
#endif
    Files = rpmfiFree(Files);

int
Files_compare(Files, Fb)
    rpmfi Files
    rpmfi Fb
    CODE:
    RETVAL = rpmfiCompare(Files, Fb);
    OUTPUT:
    RETVAL

int
Files_move(Files, index = 0)
    rpmfi Files;
    int index
    PREINIT:
    int i;
    CODE:
    index ++; /* keeping same behaviour than Header::Dep */
    rpmfiInit(Files, 0);
    RETVAL = 0;
    for (i=-1; i < index && (RETVAL = rpmfiNext(Files)) >= 0; i++) {}
    if (RETVAL == -1) {
        rpmfiInit(Files, 0);
        rpmfiNext(Files);
    }
    OUTPUT:
    RETVAL

int
Files_count(Files)
    rpmfi Files
    CODE:
    RETVAL = rpmfiFC(Files);
    OUTPUT:
    RETVAL

int
Files_countdir(Files)
    rpmfi Files
    CODE:
    RETVAL = rpmfiDC(Files);
    OUTPUT:
    RETVAL

void
Files_init(Files)
    rpmfi Files
    CODE:
#ifdef HDLISTDEBUG
    PRINTF_CALL;
#endif
    rpmfiInit(Files, 0);
        
#ifndef RPM4_19_0
void
Files_initdir(Files)
    rpmfi Files
    CODE:
#ifdef HDLISTDEBUG
    PRINTF_CALL;
#endif
    rpmfiInitD(Files, 0);

#endif

int
Files_next(Files)
    rpmfi Files
    CODE:
#ifdef HDLISTDEBUG
    PRINTF_CALL;
#endif
    RETVAL = rpmfiNext(Files);
    OUTPUT:
    RETVAL

int
Files_hasnext(Files)
    rpmfi Files
    CODE:
    RETVAL = rpmfiNext(Files) > -1;
    OUTPUT:
    RETVAL

#ifndef RPM4_19_0
int
Files_nextdir(Files)
    rpmfi Files
    CODE:
#ifdef HDLISTDEBUG
    PRINTF_CALL;
#endif
    RETVAL = rpmfiNextD(Files);
    OUTPUT:
    RETVAL

#endif

void
Files_filename(Files)
    rpmfi Files
    PPCODE:
#ifdef HDLISTDEBUG
    PRINTF_CALL;
    fprintf(stderr, "File %s", rpmfiFN(Files));
#endif
    mXPUSHs(newSVpv(rpmfiFN(Files), 0));

void
Files_dirname(Files)
    rpmfi Files
    PPCODE:
    mXPUSHs(newSVpv(rpmfiDN(Files), 0));

void
Files_basename(Files)
    rpmfi Files
    PPCODE:
    mXPUSHs(newSVpv(rpmfiBN(Files), 0));

void
Files_fflags(Files)
    rpmfi Files
    PPCODE:
    mXPUSHs(newSViv(rpmfiFFlags(Files)));

void
Files_mode(Files)
    rpmfi Files
    PPCODE:
    mXPUSHs(newSVuv(rpmfiFMode(Files)));

void
Files_md5(Files)
    rpmfi Files
    PREINIT:
    const char * md5;
    PPCODE:
    if ((md5 = 
        rpmfiFDigestHex(Files, NULL)
            ) != NULL && *md5 != 0 /* return undef if empty */) {
        mXPUSHs(newSVpv(md5, 0));
    }

void
Files_link(Files)
    rpmfi Files
    PREINIT:
    const char * link;
    PPCODE:
    if ((link = rpmfiFLink(Files)) != NULL && *link != 0 /* return undef if empty */) {
        mXPUSHs(newSVpv(link, 0));
    }

void
Files_user(Files)
    rpmfi Files
    PPCODE:
    mXPUSHs(newSVpv(rpmfiFUser(Files), 0));

void
Files_group(Files)
    rpmfi Files
    PPCODE:
    mXPUSHs(newSVpv(rpmfiFGroup(Files), 0));

void
Files_inode(Files)
    rpmfi Files
    PPCODE:
    mXPUSHs(newSViv(rpmfiFInode(Files)));
    
void
Files_size(Files)
    rpmfi Files
    PPCODE:
    mXPUSHs(newSViv(rpmfiFSize(Files)));

void
Files_dev(Files)
    rpmfi Files
    PPCODE:
    mXPUSHs(newSViv(rpmfiFRdev(Files)));

void
Files_color(Files)
    rpmfi Files
    PPCODE:
    mXPUSHs(newSViv(rpmfiFColor(Files)));

void
Files_class(Files)
    rpmfi Files
    PREINIT:
    const char * class;
    PPCODE:
    if ((class = rpmfiFClass(Files)) != NULL)
        mXPUSHs(newSVpv(rpmfiFClass(Files), 0));

void
Files_mtime(Files)
    rpmfi Files
    PPCODE:
    mXPUSHs(newSViv(rpmfiFMtime(Files)));

void
Files_nlink(Files)
    rpmfi Files
    PPCODE:
    mXPUSHs(newSViv(rpmfiFNlink(Files)));

MODULE = RPM4     PACKAGE = RPM4

void
newspec(filename = NULL, anyarch = NULL, force = NULL)
    char * filename 
    SV * anyarch
    SV * force
    PREINIT:
    rpmts ts = rpmtsCreate();
    PPCODE:
    PUTBACK;
    _newspec(ts, filename, anyarch, force);
    ts = rpmtsFree(ts);
    SPAGAIN;

MODULE = RPM4 	PACKAGE = RPM4::Spec  PREFIX = Spec_

void
Spec_new(perlclass, specfile = NULL, ...)
    char * perlclass
    char * specfile
    PREINIT:
    rpmts ts = NULL;
    SV * anyarch = 0;
    SV * force = 0;
    int i;
    PPCODE:
    for(i=2; i < items; i++) {
        if(strcmp(SvPV_nolen(ST(i)), "transaction") == 0) {
            i++;
            if (sv_isobject(ST(i)) && (SvTYPE(SvRV(ST(i))) == SVt_PVMG)) {
                ts = (rpmts)SvIV((SV*)SvRV(ST(i)));
                ts = rpmtsLink(ts);  
            } else {
                croak( "transaction is not a blessed SV reference" );
                XSRETURN_UNDEF;
            } 
        } else if (strcmp(SvPV_nolen(ST(i)), "force") == 0) {
            i++;
            force = ST(i);
        } else if (strcmp(SvPV_nolen(ST(i)), "anyarch") == 0) {
            i++;
            anyarch = ST(i);
        } else {
            warn("Unknown value in " bless_spec "->new, ignored");
            i++;
        }
    }
    if (!ts)
        ts = rpmtsCreate();
    PUTBACK;
    _newspec(ts, specfile, anyarch, force);
    SPAGAIN;
    ts = rpmtsFree(ts);
    
void
Spec_DESTROY(spec)
    rpmSpec spec
    CODE:
#ifdef HDRPMMEM
    PRINTF_FREE(bless_spec, spec, -1);
#endif
    rpmSpecFree(spec);

void
Spec_srcheader(spec)
    rpmSpec spec
    PPCODE:
    Header header = rpmSpecSourceHeader(spec);
    mXPUSHs(sv_setref_pv(newSVpvs(""), bless_header, (void *)headerLink(header)));

void
Spec_binheader(spec)
    rpmSpec spec
    PREINIT:
    Package pkg;
    PPCODE:
    rpmSpecPkgIter iter = rpmSpecPkgIterInit(spec);
    while ((pkg = rpmSpecPkgIterNext(iter)) != NULL)
        mXPUSHs(sv_setref_pv(newSVpvs(""), bless_header, (void *)headerLink(rpmSpecPkgHeader(pkg))));
 
void
Spec_srcrpm(spec)
    rpmSpec spec
    PREINIT:
    Header header = NULL;
    PPCODE:
    header = rpmSpecSourceHeader(spec);
    struct rpmtd_s td;
    int no_src = headerGet(header, RPMTAG_NOSOURCE, &td, HEADERGET_MINMEM);
    char *nvr = headerGetAsString(header, RPMTAG_NVR);
    mXPUSHs(newSVpvf("%s/%s.%ssrc.rpm",
        rpmGetPath("%{_srcrpmdir}", NULL),
        nvr, no_src ? "no" : ""));

void
Spec_binrpm(spec)
    rpmSpec spec
    PREINIT:
    Package pkg;
    char * binFormat;
    char * binRpm;
    char * path;
    Header header;
    PPCODE:
    rpmSpecPkgIter iter = rpmSpecPkgIterInit(spec);
    while ((pkg = rpmSpecPkgIterNext(iter)) != NULL) {
        /* headerCopyTags(h, pkg->header, copyTags); */
        binFormat = rpmGetPath("%{_rpmfilename}", NULL);
        header = rpmSpecSourceHeader(spec);
        binRpm = headerFormat(header, binFormat, NULL);
        free(binFormat);
        path = rpmGetPath("%{_rpmdir}/", binRpm, NULL);
        mXPUSHs(newSVpv(path, 0));
        free(path);
        free(binRpm);
    }

void
Spec_check(spec, ts = NULL)
    rpmSpec spec
    PREINIT:
    rpmts ts = rpmtsCreate();
    rpmps ps;
    PPCODE:
    PUTBACK;
    if (ts)
        ts = rpmtsLink(ts);
    else
        ts = rpmtsCreate();
    Header header = rpmSpecSourceHeader(spec);
    if (!headerIsEntry(header, RPMTAG_REQUIRENAME)
     && !headerIsEntry(header, RPMTAG_CONFLICTNAME))
        /* XSRETURN_UNDEF; */
        return;

    (void) rpmtsAddInstallElement(ts, header, NULL, 0, NULL);

    if(rpmtsCheck(ts))
        croak("Can't check rpmts"); /* any better idea ? */

    ps = rpmtsProblems(ts);
    if (ps && rpmpsNumProblems(ps)) /* if no problem, return undef */
        mXPUSHs(sv_setref_pv(newSVpvs(""), bless_rpmps, ps));
    ts = rpmtsFree(ts);
    SPAGAIN;
    
    
int
Spec_build(spec, sv_buildflags)
    rpmSpec spec
    SV * sv_buildflags
    PREINIT:
    CODE:
    RETVAL = _specbuild(spec, sv_buildflags);
    OUTPUT:
    RETVAL

void
Spec_sources(spec, is = 0)
    rpmSpec spec
    int is
    PREINIT:
    rpmSpecSrc srcPtr;
    PPCODE:
    rpmSpecSrcIter iter = rpmSpecSrcIterInit(spec);
    while ((srcPtr = rpmSpecSrcIterNext(iter)) != NULL) {
        if (is && !(rpmSpecSrcFlags(srcPtr) & is))
            continue;
        mXPUSHs(newSVpv(rpmSpecSrcFilename(srcPtr, 0), 0));
    }

void
Spec_sources_url(spec, is = 0)
    rpmSpec spec
    int is
    PREINIT:
    rpmSpecSrc srcPtr;
    PPCODE:
    rpmSpecSrcIter iter = rpmSpecSrcIterInit(spec);
    while ((srcPtr = rpmSpecSrcIterNext(iter)) != NULL) {
        if (is && !(rpmSpecSrcFlags(srcPtr) & is))
            continue;
        mXPUSHs(newSVpv(rpmSpecSrcFilename(srcPtr, 1), 0));
    }

MODULE = RPM4		PACKAGE = RPM4::Db::_Problems	PREFIX = ps_

void
ps_new(perlclass, ts)
    char * perlclass    
    rpmts ts
    PREINIT:
    rpmps ps;
    PPCODE:
    ps = rpmtsProblems(ts);
    if (ps && rpmpsNumProblems(ps)) /* if no problem, return undef */
        mXPUSHs(sv_setref_pv(newSVpvs(""), bless_rpmps, ps));
 
void
ps_DESTROY(ps)
    rpmps ps
    PPCODE:
    ps = rpmpsFree(ps);

int
ps_count(ps)
    rpmps ps
    CODE:
    RETVAL = rpmpsNumProblems(ps);
    OUTPUT:
    RETVAL

void
ps_print(ps, fp)
    rpmps ps    
    FILE *fp
    PPCODE:
    rpmpsPrint(fp, ps);

int
ps_isignore(ps, numpb)
    rpmps ps
    int numpb
    PREINIT:
    CODE:
    RETVAL = 0; /* ignoreProblem is obsolete and always false */
    OUTPUT:
    RETVAL

const char *
ps_fmtpb(ps, numpb)
    rpmps ps
    int numpb
    PREINIT:
    rpmProblem p;
    int i;
    CODE:
    rpmpsi psi = rpmpsInitIterator(ps);
    for (i = 0; i <= numpb; i++)
      if (rpmpsNextIterator(psi) < 0) break;

    p = rpmpsGetProblem(psi);
    if (p)
        RETVAL = rpmProblemString(p);
    else {
        RETVAL = NULL;
    }
    OUTPUT:
    RETVAL



( run in 2.306 seconds using v1.01-cache-2.11-cpan-5511b514fd6 )