diff options
Diffstat (limited to 'URPM.xs')
-rw-r--r-- | URPM.xs | 167 |
1 files changed, 89 insertions, 78 deletions
@@ -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 |