RPM2
view release on metacpan or search on metacpan
lib/RPM2.xs view on Meta::CPAN
header_tags = perl_get_hv("RPM2::header_tag_map", TRUE);
_populate_header_tags(header_tags);
constants = perl_get_hv("RPM2::constants", TRUE);
/* not the 'standard' way of doing perl constants, but a lot easier to maintain */
REGISTER_CONSTANT(RPMVSF_DEFAULT);
REGISTER_CONSTANT(RPMVSF_NOHDRCHK);
REGISTER_CONSTANT(RPMVSF_NEEDPAYLOAD);
REGISTER_CONSTANT(RPMVSF_NOSHA1HEADER);
REGISTER_CONSTANT(RPMVSF_NODSAHEADER);
REGISTER_CONSTANT(RPMVSF_NORSAHEADER);
REGISTER_CONSTANT(RPMVSF_NOMD5);
REGISTER_CONSTANT(RPMVSF_NODSA);
REGISTER_CONSTANT(RPMVSF_NORSA);
REGISTER_CONSTANT(_RPMVSF_NODIGESTS);
REGISTER_CONSTANT(_RPMVSF_NOSIGNATURES);
REGISTER_CONSTANT(_RPMVSF_NOHEADER);
REGISTER_CONSTANT(_RPMVSF_NOPAYLOAD);
REGISTER_CONSTANT(TR_ADDED);
REGISTER_CONSTANT(TR_REMOVED);
}
double
rpm_api_version(pkg)
char * pkg
CODE:
(void)pkg; /* Not used */
int major = RPM2_API / 1000;
double minor = (int)RPM2_API % 1000;
while (minor >= 1) { minor /= 10; }
RETVAL = major + minor;
OUTPUT:
RETVAL
void
add_macro(pkg, name, val)
char * pkg
char * name
char * val
CODE:
(void)pkg; /* Not used */
addMacro(NULL, name, NULL, val, RMIL_DEFAULT);
void
delete_macro(pkg, name)
char * pkg
char * name
CODE:
(void)pkg; /* Not used */
delMacro(NULL, name);
void
expand_macro(pkg, str)
char * pkg
char * str
PREINIT:
char *ret;
PPCODE:
(void)pkg; /* Not used */
ret = rpmExpand(str, NULL);
PUSHs(sv_2mortal(newSVpv(ret, 0)));
free(ret);
int
rpmvercmp(one, two)
char* one
char* two
void
_read_package_info(fp, vsflags)
FILE *fp
int vsflags
PREINIT:
rpmts ts;
Header ret;
rpmRC rc;
FD_t fd;
PPCODE:
ts = rpmtsCreate();
/* XXX Determine type of signature verification when reading
vsflags |= _RPMTS_VSF_NOLEGACY;
vsflags |= _RPMTS_VSF_NODIGESTS;
vsflags |= _RPMTS_VSF_NOSIGNATURES;
xx = rpmtsSetVerifySigFlags(ts, vsflags);
*/
fd = fdDup(fileno(fp));
rpmtsSetVSFlags(ts, vsflags);
rc = rpmReadPackageFile(ts, fd, "filename or other identifier", &ret);
Fclose(fd);
if (rc == RPMRC_OK) {
SV *h_sv;
EXTEND(SP, 1);
h_sv = sv_newmortal();
sv_setref_pv(h_sv, "RPM2::C::Header", (void *)ret);
PUSHs(h_sv);
}
else {
croak("error reading package");
}
ts = rpmtsFree(ts);
void
_create_transaction(vsflags)
int vsflags
PREINIT:
rpmts ret;
SV *h_sv;
PPCODE:
/* Looking at librpm, it does not look like this ever
returns error (though maybe it should).
*/
ret = rpmtsCreate();
/* Should I save the old vsflags aside? */
rpmtsSetVSFlags(ret, vsflags);
/* Convert and throw the results on the stack */
EXTEND(SP, 1);
h_sv = sv_newmortal();
sv_setref_pv(h_sv, "RPM2::C::Transaction", (void *)ret);
PUSHs(h_sv);
void
_read_from_file(fp)
FILE *fp
PREINIT:
SV *h_sv;
FD_t fd;
Header h;
PPCODE:
fd = fdDup(fileno(fp));
h = headerRead(fd, HEADER_MAGIC_YES);
if (h) {
EXTEND(SP, 1);
h_sv = sv_newmortal();
sv_setref_pv(h_sv, "RPM2::C::Header", (void *)h);
PUSHs(h_sv);
}
Fclose(fd);
rpmts
_open_rpm_db(for_write)
int for_write
PREINIT:
rpmts ts;
CODE:
ts = rpmtsCreate();
if (rpmtsOpenDB(ts, for_write ? O_RDWR : O_RDONLY)) {
croak("rpmtsOpenDB failed");
RETVAL = NULL;
}
RETVAL = ts;
OUTPUT:
RETVAL
MODULE = RPM2 PACKAGE = RPM2::C::DB
void
DESTROY(ts)
rpmts ts
CODE:
rpmtsCloseDB(ts);
rpmtsFree(ts);
void
_close_rpm_db(self)
rpmts self
CODE:
rpmtsCloseDB(self);
rpmtsFree(self);
rpmdbMatchIterator
_init_iterator(ts, rpmtag, key, len)
rpmts ts
int rpmtag
char *key
size_t len
CODE:
/* See rpmtsInitIterator() code for explanation of this */
if (rpmtag == RPMDBI_PACKAGES) {
len = strlen (key);
}
RETVAL = rpmtsInitIterator(ts, rpmtag, len ? key : NULL, len);
OUTPUT:
RETVAL
MODULE = RPM2 PACKAGE = RPM2::C::PackageIterator
Header
_iterator_next(i)
rpmdbMatchIterator i
PREINIT:
Header ret;
SV * h_sv;
unsigned int offset;
PPCODE:
ret = rpmdbNextIterator(i);
if (ret)
headerLink(ret);
if(ret != NULL)
offset = rpmdbGetIteratorOffset(i);
else
offset = 0;
EXTEND(SP, 2);
h_sv = sv_newmortal();
sv_setref_pv(h_sv, "RPM2::C::Header", (void *)ret);
PUSHs(h_sv);
PUSHs(sv_2mortal(newSViv(offset)));
RETVAL = ret;
void
DESTROY(i)
rpmdbMatchIterator i
CODE:
rpmdbFreeIterator(i);
MODULE = RPM2 PACKAGE = RPM2::C::Header
void
DESTROY(h)
Header h
CODE:
headerFree(h);
void
tag_by_id(h, tag)
Header h
int tag
PREINIT:
rpmtd tagdata;
int ok;
PPCODE:
tagdata = rpmtdNew();
if (tagdata == NULL) {
croak("Out of memory");
}
ok = headerGet(h, tag, tagdata, HEADERGET_DEFAULT);
if (!ok) {
/* nop, empty stack */
}
else {
switch(tagdata->type)
{
case RPM_STRING_ARRAY_TYPE:
{
int i;
char **s;
EXTEND(SP, tagdata->count);
s = (char **)tagdata->data;
for (i = 0; i < tagdata->count; i++) {
PUSHs(sv_2mortal(newSVpv(s[i], 0)));
}
}
break;
case RPM_STRING_TYPE:
PUSHs(sv_2mortal(newSVpv((char *)tagdata->data, 0)));
break;
case RPM_CHAR_TYPE:
{
int i;
char *r;
EXTEND(SP, tagdata->count);
r = (char *)tagdata->data;
for (i = 0; i < tagdata->count; i++) {
PUSHs(sv_2mortal(newSViv(r[i])));
}
}
break;
case RPM_INT8_TYPE:
{
int i;
uint8_t *r;
EXTEND(SP, tagdata->count);
r = (uint8_t *)tagdata->data;
for (i = 0; i < tagdata->count; i++) {
PUSHs(sv_2mortal(newSViv(r[i])));
}
}
break;
case RPM_INT16_TYPE:
{
int i;
uint16_t *r;
EXTEND(SP, tagdata->count);
r = (uint16_t *)tagdata->data;
for (i = 0; i < tagdata->count; i++) {
PUSHs(sv_2mortal(newSViv(r[i])));
}
}
break;
case RPM_INT32_TYPE:
{
int i;
uint32_t *r;
EXTEND(SP, tagdata->count);
r = (uint32_t *)tagdata->data;
for (i = 0; i < tagdata->count; i++) {
PUSHs(sv_2mortal(newSViv(r[i])));
}
}
break;
default:
croak("unknown rpm tag type %d", tagdata->type);
}
}
rpmtdFreeData(tagdata);
int
_header_compare(h1, h2)
Header h1
Header h2
CODE:
RETVAL = rpmVersionCompare(h1, h2);
OUTPUT:
RETVAL
int
_header_is_source(h)
Header h
CODE:
RETVAL = headerIsEntry(h, RPMTAG_SOURCEPACKAGE);
OUTPUT:
RETVAL
void
_header_sprintf(h, format)
Header h
char * format
PREINIT:
char * s;
PPCODE:
s = headerFormat(h, format, NULL);
PUSHs(sv_2mortal(newSVpv((char *)s, 0)));
/* By the way, the #if below is completely useless, free() would work for both */
free(s);
MODULE = RPM2 PACKAGE = RPM2::C::Transaction
void
DESTROY(t)
rpmts t
CODE:
t = rpmtsFree(t);
# XXX: Add relocations some day.
int
_add_install(t, h, fn, upgrade)
rpmts t
Header h
char * fn
int upgrade
PREINIT:
rpmRC rc = 0;
CODE:
rc = rpmtsAddInstallElement(t, h, (fnpyKey) fn, upgrade, NULL);
RETVAL = (rc == RPMRC_OK) ? 1 : 0;
OUTPUT:
RETVAL
int
_add_delete(t, h, offset)
rpmts t
Header h
unsigned int offset
PREINIT:
rpmRC rc = 0;
CODE:
rc = rpmtsAddEraseElement(t, h, offset);
RETVAL = (rc == RPMRC_OK) ? 1 : 0;
OUTPUT:
RETVAL
int
_element_count(t)
rpmts t
PREINIT:
int ret;
CODE:
ret = rpmtsNElements(t);
RETVAL = ret;
OUTPUT:
RETVAL
int
_close_db(t)
rpmts t
PREINIT:
int ret;
CODE:
ret = rpmtsCloseDB(t);
RETVAL = (ret == 0) ? 1 : 0;
OUTPUT:
RETVAL
int
_check(t)
rpmts t
PREINIT:
int ret;
CODE:
ret = rpmtsCheck(t);
RETVAL = (ret == 0) ? 1 : 0;
OUTPUT:
RETVAL
int
_order(t)
rpmts t
PREINIT:
int ret;
CODE:
ret = rpmtsOrder(t);
/* XXX: May want to do something different here. It actually
returns the number of non-ordered elements...maybe we
want this?
*/
RETVAL = (ret == 0) ? 1 : 0;
OUTPUT:
RETVAL
void
_elements(t, type)
rpmts t;
rpmElementType type;
PREINIT:
rpmtsi i;
rpmte te;
const char * NEVR;
PPCODE:
i = rpmtsiInit(t);
if(i == NULL) {
printf("Did not get a thing!\n");
return;
} else {
while((te = rpmtsiNext(i, type)) != NULL) {
NEVR = rpmteNEVR(te);
XPUSHs(sv_2mortal(newSVpv(NEVR, 0)));
}
i = rpmtsiFree(i);
}
int
_run(t, ok_probs, prob_filter)
rpmts t
rpmprobFilterFlags prob_filter
PREINIT:
int ret;
CODE:
/* Make sure we could run this transactions */
ret = rpmtsCheck(t);
if (ret != 0) {
RETVAL = 0;
return;
}
ret = rpmtsOrder(t);
if (ret != 0) {
RETVAL = 0;
return;
}
/* XXX: Should support callbacks eventually */
(void) rpmtsSetNotifyCallback(t, _null_callback, (void *) ((long)0));
ret = rpmtsRun(t, NULL, prob_filter);
RETVAL = (ret == 0) ? 1 : 0;
OUTPUT:
RETVAL
( run in 2.376 seconds using v1.01-cache-2.11-cpan-5511b514fd6 )