aboutsummaryrefslogtreecommitdiffstats
path: root/URPM.xs
diff options
context:
space:
mode:
Diffstat (limited to 'URPM.xs')
-rw-r--r--URPM.xs167
1 files changed, 89 insertions, 78 deletions
diff --git a/URPM.xs b/URPM.xs
index e553153..e1ba971 100644
--- a/URPM.xs
+++ b/URPM.xs
@@ -44,19 +44,20 @@ typedef struct rpmSpec_s * Spec;
#include <rpm/rpmcli.h>
#include <rpm/rpmbuild.h>
#include <rpm/rpmlog.h>
+#include <rpm/rpmstrpool.h>
struct s_Package {
Header h;
int filesize;
unsigned flag;
- char *info;
- char *requires;
- char *suggests;
- char *obsoletes;
- char *conflicts;
- char *provides;
- char *rflags;
- char *summary;
+ rpmsid info;
+ rpmsid requires;
+ rpmsid suggests;
+ rpmsid obsoletes;
+ rpmsid conflicts;
+ rpmsid provides;
+ rpmsid rflags;
+ rpmsid summary;
};
struct s_Transaction {
@@ -150,6 +151,7 @@ static inline void _header_free(URPM__Package pkg) {
}
static int rpm_codeset_is_utf8 = 0;
+rpmstrPool pool;
static SV*
newSVpv_utf8(const char *s, STRLEN len)
@@ -165,14 +167,15 @@ get_fullname_parts(URPM__Package pkg, char **name, char **version, char **releas
if (!pkg->info)
return;
- if ((_eos = strchr(pkg->info, '@')) != NULL) {
+ const char *str_info = rpmstrPoolStr(pool, pkg->info);
+ if ((_eos = strchr(str_info, '@')) != NULL) {
*_eos = 0; /* mark end of string to enable searching backwards */
- if ((_arch = strrchr(pkg->info, '.')) != NULL) {
+ if ((_arch = strrchr(str_info, '.')) != NULL) {
*_arch = 0;
- if ((release != NULL || version != NULL || name != NULL) && (_release = strrchr(pkg->info, '-')) != NULL) {
+ if ((release != NULL || version != NULL || name != NULL) && (_release = strrchr(str_info, '-')) != NULL) {
*_release = 0;
- if ((version != NULL || name != NULL) && (_version = strrchr(pkg->info, '-')) != NULL) {
- if (name != NULL) *name = pkg->info;
+ if ((version != NULL || name != NULL) && (_version = strrchr(str_info, '-')) != NULL) {
+ if (name != NULL) *name = str_info;
if (version != NULL) *version = _version + 1;
}
if (release != NULL) *release = _release + 1;
@@ -577,7 +580,7 @@ return_list_tag(const URPM__Package pkg, rpmTag tag_name) {
}
break;
case RPMTAG_SUMMARY:
- mXPUSHs(newSVpv(pkg->summary, 0));
+ mXPUSHs(newSVpv(rpmstrPoolStr(pool, pkg->summary), 0));
break;
default:
croak("unexpected tag %s", tag_name);
@@ -749,7 +752,7 @@ pack_list(const Header header, rpmTag tag_name, rpmTag tag_flags, rpmTag tag_ver
static void
pack_header(const URPM__Package pkg) {
if (pkg->h) {
- if (pkg->info == NULL) {
+ if (!pkg->info) {
char buff[1024];
const char *p = buff;
const char *nvr = headerGetAsString(pkg->h, RPMTAG_NVR);
@@ -758,24 +761,24 @@ pack_header(const URPM__Package pkg) {
p += 1 + snprintf(buff, sizeof(buff), "%s.%s@%d@%d@%s", nvr, arch,
get_int(pkg->h, RPMTAG_EPOCH), get_int(pkg->h, RPMTAG_SIZE),
get_name(pkg->h, RPMTAG_GROUP));
- pkg->info = memcpy(malloc(p-buff), buff, p-buff);
+ pkg->info = rpmstrPoolId(pool, memcpy(malloc(p-buff), buff, p-buff), 1);
}
if (pkg->filesize == 0) pkg->filesize = get_filesize(pkg->h);
- if (pkg->requires == NULL)
- pkg->requires = pack_list(pkg->h, RPMTAG_REQUIRENAME, RPMTAG_REQUIREFLAGS, RPMTAG_REQUIREVERSION);
- if (pkg->suggests == NULL)
- pkg->suggests = pack_list(pkg->h, RPMTAG_SUGGESTSNAME, 0, 0);
- if (pkg->obsoletes == NULL)
- pkg->obsoletes = pack_list(pkg->h, RPMTAG_OBSOLETENAME, RPMTAG_OBSOLETEFLAGS, RPMTAG_OBSOLETEVERSION);
- if (pkg->conflicts == NULL)
- pkg->conflicts = pack_list(pkg->h, RPMTAG_CONFLICTNAME, RPMTAG_CONFLICTFLAGS, RPMTAG_CONFLICTVERSION);
- if (pkg->provides == NULL)
- pkg->provides = pack_list(pkg->h, RPMTAG_PROVIDENAME, RPMTAG_PROVIDEFLAGS, RPMTAG_PROVIDEVERSION);
- if (pkg->summary == NULL) {
+ if (!pkg->requires)
+ pkg->requires = rpmstrPoolId(pool, pack_list(pkg->h, RPMTAG_REQUIRENAME, RPMTAG_REQUIREFLAGS, RPMTAG_REQUIREVERSION), 1);
+ if (!pkg->suggests)
+ pkg->suggests = rpmstrPoolId(pool, pack_list(pkg->h, RPMTAG_SUGGESTSNAME, 0, 0), 1);
+ if (!pkg->obsoletes)
+ pkg->obsoletes = rpmstrPoolId(pool, pack_list(pkg->h, RPMTAG_OBSOLETENAME, RPMTAG_OBSOLETEFLAGS, RPMTAG_OBSOLETEVERSION), 1);
+ if (!pkg->conflicts)
+ pkg->conflicts = rpmstrPoolId(pool, pack_list(pkg->h, RPMTAG_CONFLICTNAME, RPMTAG_CONFLICTFLAGS, RPMTAG_CONFLICTVERSION), 1);
+ if (!pkg->provides)
+ pkg->provides = rpmstrPoolId(pool, pack_list(pkg->h, RPMTAG_PROVIDENAME, RPMTAG_PROVIDEFLAGS, RPMTAG_PROVIDEVERSION), 1);
+ if (!pkg->summary) {
char *summary = get_name(pkg->h, RPMTAG_SUMMARY);
int len = 1 + strlen(summary);
- pkg->summary = memcpy(malloc(len), summary, len);
+ pkg->summary = rpmstrPoolId(pool, memcpy(malloc(len), summary, len), 1);
}
_header_free(pkg);
@@ -839,9 +842,11 @@ update_provides(const URPM__Package pkg, HV *provides) {
}
}
} else {
- char *ps, *s, *es;
+ char *ps, *es;
+ const char *s;
- if ((s = pkg->requires) != NULL && *s != 0) {
+ s = rpmstrPoolStr(pool, pkg->requires);
+ if (s != NULL && *s != 0) {
ps = strchr(s, '@');
while(ps != NULL) {
if (s[0] == '/') {
@@ -856,7 +861,8 @@ update_provides(const URPM__Package pkg, HV *provides) {
}
}
- if ((s = pkg->provides) != NULL && *s != 0) {
+ s = rpmstrPoolStr(pool, pkg->provides);
+ if (s != NULL && *s != 0) {
char *es;
ps = strchr(s, '@');
@@ -883,9 +889,10 @@ update_obsoletes(const URPM__Package pkg, HV *obsoletes) {
update_hash_entry(obsoletes, rpmtdNextString(&td), 0, 1, 0, pkg);
}
} else {
- char *ps, *s;
+ char *ps;
+ const char *s = rpmstrPoolStr(pool, pkg->obsoletes);
- if ((s = pkg->obsoletes) != NULL && *s != 0) {
+ if (s != NULL && *s != 0) {
char *es;
ps = strchr(s, '@');
@@ -1035,7 +1042,7 @@ parse_line(AV *depslist, HV *provides, HV *obsoletes, URPM__Package pkg, char *b
*tag++ = *data++ = 0;
int data_len = 1+strlen(data);
if (!strcmp(tag, "info")) {
- pkg->info = memcpy(malloc(data_len), data, data_len);
+ pkg->info = rpmstrPoolId(pool, memcpy(malloc(data_len), data, data_len), 1);
pkg->flag &= ~FLAG_ID_MASK;
pkg->flag |= 1 + av_len(depslist);
URPM__Package _pkg = memcpy(malloc(sizeof(struct s_Package)), pkg, sizeof(struct s_Package));
@@ -1045,7 +1052,7 @@ parse_line(AV *depslist, HV *provides, HV *obsoletes, URPM__Package pkg, char *b
} else if (!strcmp(tag, "filesize"))
pkg->filesize = atoi(data);
else {
- char **ptr = NULL;
+ rpmsid *ptr = NULL;
if (!strcmp(tag, "requires"))
ptr = &pkg->requires;
else if (!strcmp(tag, "suggests"))
@@ -1060,7 +1067,7 @@ parse_line(AV *depslist, HV *provides, HV *obsoletes, URPM__Package pkg, char *b
ptr = &pkg->summary;
if (ptr)
- free(*ptr), *ptr = memcpy(malloc(data_len), data, data_len);
+ *ptr = rpmstrPoolId(pool, memcpy(malloc(data_len), data, data_len), 1);
}
return 1;
} else {
@@ -1348,8 +1355,9 @@ static int compare_evrs(int lepoch, char*lversion, char*lrelease, int repoch, ch
static int get_e_v_r(URPM__Package pkg, int *epoch, char **version, char **release, char **arch) {
if (pkg->info) {
char *s, *eos;
+ const char *str_info = rpmstrPoolStr(pool, pkg->info);
- if ((s = strchr(pkg->info, '@')) != NULL) {
+ if ((s = strchr(str_info, '@')) != NULL) {
if ((eos = strchr(s+1, '@')) != NULL)
*eos = 0; /* mark end of string to enable searching backwards */
*epoch = atoi(s+1);
@@ -1378,14 +1386,6 @@ void
Pkg_DESTROY(pkg)
URPM::Package pkg
CODE:
- free(pkg->info);
- free(pkg->requires);
- free(pkg->suggests);
- free(pkg->obsoletes);
- free(pkg->conflicts);
- free(pkg->provides);
- free(pkg->rflags);
- free(pkg->summary);
_header_free(pkg);
free(pkg);
@@ -1441,9 +1441,10 @@ Pkg_EVR(pkg)
if (pkg->info) {
char *s, *eos;
char *version, *arch;
+ const char *str_info = rpmstrPoolStr(pool, pkg->info);
int epoch;
- if ((s = strchr(pkg->info, '@')) != NULL) {
+ if ((s = strchr(str_info, '@')) != NULL) {
if ((eos = strchr(s+1, '@')) != NULL)
*eos = 0; /* mark end of string to enable searching backwards */
epoch = atoi(s+1);
@@ -1509,7 +1510,7 @@ Pkg_summary(pkg)
URPM::Package pkg
PPCODE:
if (pkg->summary) {
- mXPUSHs(newSVpv_utf8(pkg->summary, 0));
+ mXPUSHs(newSVpv_utf8(rpmstrPoolStr(pool, pkg->summary), 0));
} else if (pkg->h) {
mXPUSHs(newSVpv_utf8(get_name(pkg->h, RPMTAG_SUMMARY), 0));
}
@@ -1583,8 +1584,9 @@ Pkg_fullname(pkg)
if (pkg->info) {
if (gimme == G_SCALAR) {
char *eos;
- if ((eos = strchr(pkg->info, '@')) != NULL) {
- mXPUSHs(newSVpv(pkg->info, eos-pkg->info));
+ const char *str_info = rpmstrPoolStr(pool, pkg->info);
+ if ((eos = strchr(str_info, '@')) != NULL) {
+ mXPUSHs(newSVpv(str_info, eos-str_info));
}
} else if (gimme == G_ARRAY) {
char *name, *version, *release, *arch, *eos;
@@ -1619,8 +1621,9 @@ Pkg_epoch(pkg)
CODE:
if (pkg->info) {
char *s, *eos;
+ const char *str_info = rpmstrPoolStr(pool, pkg->info);
- if ((s = strchr(pkg->info, '@')) != NULL) {
+ if ((s = strchr(str_info, '@')) != NULL) {
if ((eos = strchr(s+1, '@')) != NULL)
*eos = 0; /* mark end of string to enable searching backwards */
RETVAL = atoi(s+1);
@@ -1742,8 +1745,9 @@ Pkg_size(pkg)
CODE:
if (pkg->info) {
char *s, *eos;
+ const char *str_info = rpmstrPoolStr(pool, pkg->info);
- if ((s = strchr(pkg->info, '@')) != NULL && (s = strchr(s+1, '@')) != NULL) {
+ if ((s = strchr(str_info, '@')) != NULL && (s = strchr(s+1, '@')) != NULL) {
if ((eos = strchr(s+1, '@')) != NULL)
*eos = 0; /* mark end of string to enable searching backwards */
RETVAL = atoi(s+1);
@@ -1782,8 +1786,9 @@ Pkg_group(pkg)
PPCODE:
if (pkg->info) {
char *s;
+ const char *str_info = rpmstrPoolStr(pool, pkg->info);
- if ((s = strchr(pkg->info, '@')) != NULL && (s = strchr(s+1, '@')) != NULL && (s = strchr(s+1, '@')) != NULL) {
+ if ((s = strchr(str_info, '@')) != NULL && (s = strchr(s+1, '@')) != NULL && (s = strchr(s+1, '@')) != NULL) {
char *eos = strchr(s+1, '@');
mXPUSHs(newSVpv_utf8(s+1, eos != NULL ? eos-s-1 : 0));
}
@@ -1796,12 +1801,13 @@ Pkg_filename(pkg)
PPCODE:
if (pkg->info) {
char *eon;
+ const char *str_info = rpmstrPoolStr(pool, pkg->info);
- if ((eon = strchr(pkg->info, '@')) != NULL && strlen(eon) >= 3) {
+ if ((eon = strchr(str_info, '@')) != NULL && strlen(eon) >= 3) {
char savbuf[4];
memcpy(savbuf, eon, 4); /* there should be at least epoch and size described so (@0@0 minimum) */
memcpy(eon, ".rpm", 4);
- mXPUSHs(newSVpv(pkg->info, eon-pkg->info+4));
+ mXPUSHs(newSVpv(str_info, eon-str_info+4));
memcpy(eon, savbuf, 4);
}
} else if (pkg->h) {
@@ -1840,14 +1846,14 @@ Pkg_obsoletes(pkg)
PPCODE:
PUTBACK;
rpmTag tag, flags, tag_version;
- char *s;
+ rpmsid s;
switch (ix) {
case 1: tag = RPMTAG_CONFLICTNAME; s = pkg->conflicts; flags = RPMTAG_CONFLICTFLAGS; tag_version = RPMTAG_CONFLICTVERSION; break;
case 2: tag = RPMTAG_PROVIDENAME; s = pkg->provides; flags = RPMTAG_PROVIDEFLAGS; tag_version = RPMTAG_PROVIDEVERSION; break;
case 3: tag = RPMTAG_REQUIRENAME; s = pkg->requires; flags = RPMTAG_REQUIREFLAGS; tag_version = RPMTAG_REQUIREVERSION; break;
default: tag = RPMTAG_OBSOLETENAME; s = pkg->obsoletes; flags = RPMTAG_OBSOLETEFLAGS; tag_version = RPMTAG_OBSOLETEVERSION; break;
}
- return_list_str(s, pkg->h, tag, flags, tag_version, callback_list_str_xpush, NULL);
+ return_list_str(rpmstrPoolStr(pool, s), pkg->h, tag, flags, tag_version, callback_list_str_xpush, NULL);
SPAGAIN;
void
@@ -1861,7 +1867,8 @@ Pkg_obsoletes_nosense(pkg)
PPCODE:
PUTBACK;
rpmTag tag;
- char *s;
+ rpmsid s;
+ const char *str;
switch (ix) {
case 1: tag = RPMTAG_CONFLICTNAME; s = pkg->conflicts; break;
case 2: tag = RPMTAG_PROVIDENAME; s = pkg->provides; break;
@@ -1869,7 +1876,8 @@ Pkg_obsoletes_nosense(pkg)
case 4: tag = RPMTAG_SUGGESTSNAME; s = pkg->suggests; break;
default: tag = RPMTAG_OBSOLETENAME; s = pkg->obsoletes; break;
}
- return_list_str(s, pkg->h, tag, 0, 0, callback_list_str_xpush, NULL);
+ str = rpmstrPoolStr(pool, s);
+ return_list_str(str, pkg->h, tag, 0, 0, callback_list_str_xpush, NULL);
SPAGAIN;
int
@@ -1920,7 +1928,8 @@ Pkg_obsoletes_overlap(pkg, s)
*eon = 0;
}
/* return_list_str returns a negative value is the callback has returned non-zero */
- RETVAL = return_list_str(ix == 0 ? pkg->obsoletes : pkg->provides, pkg->h, tag_name, tag_flags, tag_version,
+ const char *str = rpmstrPoolStr(pool, ix == 0 ? pkg->obsoletes : pkg->provides);
+ RETVAL = return_list_str(str, pkg->h, tag_name, tag_flags, tag_version,
callback_list_str_overlap, &os) < 0;
/* restore end of name */
if (eon) *eon = eonc;
@@ -2069,10 +2078,11 @@ Pkg_build_info(pkg, fileno, provides_files=NULL)
if (pkg->info) {
char buff[65536];
size_t size;
+ const char *s;
/* info line should be the last to be written */
- if (pkg->provides && *pkg->provides) {
- size = snprintf(buff, sizeof(buff), "@provides@%s\n", pkg->provides);
+ if ((s = rpmstrPoolStr(pool, pkg->provides)) && *s) {
+ size = snprintf(buff, sizeof(buff), "@provides@%s\n", s);
if (size < sizeof(buff)) {
if (provides_files && *provides_files) {
--size;
@@ -2081,31 +2091,32 @@ Pkg_build_info(pkg, fileno, provides_files=NULL)
write_nocheck(fileno, buff, size);
}
}
- if (pkg->conflicts && *pkg->conflicts) {
- size = snprintf(buff, sizeof(buff), "@conflicts@%s\n", pkg->conflicts);
+ if ((s = rpmstrPoolStr(pool, pkg->conflicts)) && *s) {
+ size = snprintf(buff, sizeof(buff), "@conflicts@%s\n", s);
if (size < sizeof(buff)) write_nocheck(fileno, buff, size);
}
- if (pkg->obsoletes && *pkg->obsoletes) {
- size = snprintf(buff, sizeof(buff), "@obsoletes@%s\n", pkg->obsoletes);
+ //FIXME: check what returns rpmsid for null string ("\0");
+ if ((s = rpmstrPoolStr(pool, pkg->conflicts)) && *s) {
+ size = snprintf(buff, sizeof(buff), "@obsoletes@%s\n", s);
if (size < sizeof(buff)) write_nocheck(fileno, buff, size);
}
- if (pkg->requires && *pkg->requires) {
- size = snprintf(buff, sizeof(buff), "@requires@%s\n", pkg->requires);
+ if ((s = rpmstrPoolStr(pool, pkg->conflicts)) && *s) {
+ size = snprintf(buff, sizeof(buff), "@requires@%s\n", s);
if (size < sizeof(buff)) write_nocheck(fileno, buff, size);
}
- if (pkg->suggests && *pkg->suggests) {
- size = snprintf(buff, sizeof(buff), "@suggests@%s\n", pkg->suggests);
+ if ((s = rpmstrPoolStr(pool, pkg->suggests)) && *s) {
+ size = snprintf(buff, sizeof(buff), "@suggests@%s\n", s);
if (size < sizeof(buff)) write_nocheck(fileno, buff, size);
}
- if (pkg->summary && *pkg->summary) {
- size = snprintf(buff, sizeof(buff), "@summary@%s\n", pkg->summary);
+ if ((s = rpmstrPoolStr(pool, pkg->summary)) && *s) {
+ size = snprintf(buff, sizeof(buff), "@summary@%s\n", s);
if (size < sizeof(buff)) write_nocheck(fileno, buff, size);
}
if (pkg->filesize) {
size = snprintf(buff, sizeof(buff), "@filesize@%d\n", pkg->filesize);
if (size < sizeof(buff)) write_nocheck(fileno, buff, size);
}
- size = snprintf(buff, sizeof(buff), "@info@%s\n", pkg->info);
+ size = snprintf(buff, sizeof(buff), "@info@%s\n", rpmstrPoolStr(pool, pkg->info));
write_nocheck(fileno, buff, size);
} else croak("no info available for package %s",
pkg->h ? get_name(pkg->h, RPMTAG_NAME) : "-");
@@ -2259,8 +2270,8 @@ Pkg_rflags(pkg)
PREINIT:
I32 gimme = GIMME_V;
PPCODE:
- if (gimme == G_ARRAY && pkg->rflags != NULL) {
- char *s = pkg->rflags;
+ if (gimme == G_ARRAY && pkg->rflags) {
+ const char *s = rpmstrPoolStr(pool, pkg->rflags);
char *eos;
while ((eos = strchr(s, '\t')) != NULL) {
mXPUSHs(newSVpv(s, eos-s));
@@ -2293,8 +2304,8 @@ Pkg_set_rflags(pkg, ...)
}
new_rflags[total_len - 1] = 0; /* but mark end-of-string correctly */
- if (gimme == G_ARRAY && pkg->rflags != NULL) {
- char *s = pkg->rflags;
+ if (gimme == G_ARRAY && pkg->rflags) {
+ const char *s = rpmstrPoolStr(pool, pkg->rflags);
char *eos;
while ((eos = strchr(s, '\t')) != NULL) {
mXPUSHs(newSVpv(s, eos-s));
@@ -2303,8 +2314,7 @@ Pkg_set_rflags(pkg, ...)
mXPUSHs(newSVpv(s, 0));
}
- free(pkg->rflags);
- pkg->rflags = new_rflags;
+ pkg->rflags = rpmstrPoolId(pool, new_rflags, 1);
MODULE = URPM PACKAGE = URPM::DB PREFIX = Db_
@@ -2733,6 +2743,7 @@ Trans_run(trans, data, ...)
MODULE = URPM PACKAGE = URPM PREFIX = Urpm_
BOOT:
+pool = rpmstrPoolCreate();
(void) read_config_files(0);
void