aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPer Øyvind Karlsen <peroyvind@mandriva.org>2011-03-09 06:39:31 +0000
committerPer Øyvind Karlsen <peroyvind@mandriva.org>2011-03-09 06:39:31 +0000
commitc3108621aea9515f86147866ac8d793b950557a4 (patch)
treedb5d1db62144e9e2a3a62b5049dcf324330a77dc
parentf2f0c3c6d11044cbb2e245d90092e15d00049e08 (diff)
downloadperl-URPM-c3108621aea9515f86147866ac8d793b950557a4.tar
perl-URPM-c3108621aea9515f86147866ac8d793b950557a4.tar.gz
perl-URPM-c3108621aea9515f86147866ac8d793b950557a4.tar.bz2
perl-URPM-c3108621aea9515f86147866ac8d793b950557a4.tar.xz
perl-URPM-c3108621aea9515f86147866ac8d793b950557a4.zip
add support for doing comparision against provides with distepoch to allow
fresh install of newer releases into chroots - convert suggests to compatible tags when loading package headers - fix incorrect arch returned for packages without any (ie. public keys) - eliminate disttag & distepoch when extracting name, version, release to handle upgrade
-rw-r--r--NEWS9
-rw-r--r--URPM.pm2
-rw-r--r--URPM.xs323
3 files changed, 308 insertions, 26 deletions
diff --git a/NEWS b/NEWS
index 5c44487..930f2bc 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,12 @@
+Version 3.33.1 - 9 March 2011, by Per Øyvind Karlsen
+
+- add support for doing comparision against provides with distepoch to allow
+ fresh install of newer releases into chroots
+- convert suggests to compatible tags when loading package headers
+- fix incorrect arch returned for packages without any (ie. public keys)
+- eliminate disttag & distepoch when extracting name, version, release to
+ handle upgrade
+
Version 3.33 - 5 October 2009, by Christophe Fergeau
- fix lookup of existing pubkeys (#53710) (by Pascal Terjan)
diff --git a/URPM.pm b/URPM.pm
index 0e5a9dc..734c335 100644
--- a/URPM.pm
+++ b/URPM.pm
@@ -10,7 +10,7 @@ use URPM::Resolve;
use URPM::Signature;
our @ISA = qw(DynaLoader);
-our $VERSION = '3.33';
+our $VERSION = '3.33.1';
URPM->bootstrap($VERSION);
diff --git a/URPM.xs b/URPM.xs
index ff6af0f..a4ca2da 100644
--- a/URPM.xs
+++ b/URPM.xs
@@ -127,6 +127,25 @@ int rpmError_callback() {
static int rpm_codeset_is_utf8 = 0;
+static struct s_backup {
+ char *ptr;
+ char chr;
+} char_backups[32];
+
+static int BI = 0;
+
+static void
+backup_char(char *c) {
+ char_backups[BI].chr = *c,
+ *(char_backups[BI++].ptr = &(*c)) = 0; /* mark end of string to enable searching backwards */
+}
+
+static void
+restore_chars() {
+ for(; BI > 0; char_backups[BI].ptr = NULL)
+ BI--, *char_backups[BI].ptr = char_backups[BI].chr;
+}
+
static SV*
newSVpv_utf8(const char *s, STRLEN len)
{
@@ -138,12 +157,47 @@ newSVpv_utf8(const char *s, STRLEN len)
static void
get_fullname_parts(URPM__Package pkg, char **name, char **version, char **release, char **arch, char **eos) {
char *_version = NULL, *_release = NULL, *_arch = NULL, *_eos = NULL;
+ int distepoch = 0;
+ char *tmp;
+ /* search through provides for distepoch */
+ if ((tmp = pkg->provides)) {
+ do {
+ if((_eos = strchr(tmp, '@')))
+ *_eos = 0;
+
+ if((tmp = strchr(tmp, '[')) &&
+ (tmp = strchr(tmp, '-')) &&
+ (tmp = strchr(tmp, ':')))
+ distepoch = 1;
+ if(_eos) {
+ *_eos++ = '@';
+ tmp = _eos;
+ }
+ } while(!distepoch && _eos != NULL);
+ /* XXX: filename at end of line, don't bother to support it, just make sure
+ * for it not to cause crash...
+ */
+ if ((tmp = strrchr(pkg->info, '.')) && !strcmp(tmp, ".rpm"))
+ distepoch = 0;
+ }
if ((_eos = strchr(pkg->info, '@')) != NULL) {
*_eos = 0; /* mark end of string to enable searching backwards */
if ((_arch = strrchr(pkg->info, '.')) != NULL) {
*_arch = 0;
if ((release != NULL || version != NULL || name != NULL) && (_release = strrchr(pkg->info, '-')) != NULL) {
+ if (distepoch) {
+ tmp = _release;
+ while(tmp != _arch) {
+ backup_char(tmp++);
+ }
+ if((tmp = strrchr(pkg->info, '-'))) {
+ _release = tmp;
+ } else {
+ restore_chars();
+ croak("failed while eliminating distepoch, this should never happen! :(");
+ }
+ }
*_release = 0;
if ((version != NULL || name != NULL) && (_version = strrchr(pkg->info, '-')) != NULL) {
if (name != NULL) *name = pkg->info;
@@ -178,6 +232,156 @@ get_int(Header header, int32_t tag) {
return ep ? *ep : 0;
}
+static void
+strip_distepoch(Header header, int32_t tag) {
+ struct rpmtd_s val;
+
+ headerGet(header, tag, &val, HEADERGET_DEFAULT);
+ char **list = val.data;
+ for (val.ix = 0; val.ix < (int)val.count; val.ix++) {
+ char *tmp = strchr(list[val.ix], '-');
+ if(tmp) {
+ tmp = strchr(tmp, ':');
+ if(tmp) {
+ memset(tmp, 0, strlen(tmp));
+ }
+ }
+ }
+ headerMod(header, &val);
+}
+
+static void
+pretend_distepoch(Header header, int32_t names_tag, int32_t flags_tag, int32_t versions_tag) {
+ struct rpmtd_s names, flags, versions;
+ char *EVR = headerFormat(header, "%|EPOCH?{%{EPOCH}:}|%{VERSION}-%{RELEASE}", NULL);
+
+ headerGet(header, flags_tag, &flags, HEADERGET_DEFAULT);
+ headerGet(header, versions_tag, &versions, HEADERGET_DEFAULT);
+
+ char **name = NULL;
+ char **name2 = NULL;
+ int32_t *flag = flags.data;
+ int32_t *flag2 = NULL;
+ char **version = versions.data;
+ char **version2 = NULL;
+
+ for (flags.ix = 0; flags.ix < (int)flags.count; flags.ix++) {
+ if(!(flag[flags.ix] & ((RPMSENSE_LESS|RPMSENSE_GREATER|~RPMSENSE_EQUAL))) && version[flags.ix] && *version[flags.ix] && !strcmp(EVR, version[flags.ix])) {
+ if(!name) {
+ headerGet(header, names_tag, &names, HEADERGET_DEFAULT);
+
+ name = names.data;
+ name2 = malloc(++names.count * sizeof(*name));
+ names.data = memcpy(name2, name, sizeof(*name)*names.count);
+ flag2 = malloc(names.count * sizeof(flag));
+ flags.data = memcpy(flag2, flag, sizeof(flag)*names.count);
+ version2 = malloc(names.count * sizeof(*version));
+ versions.data = memcpy(version2, version, sizeof(*version)*names.count);
+ } else {
+ names.data = name2 = realloc(name2, sizeof(*name) * ++names.count);
+ flags.data = flag2 = realloc(flag2, sizeof(flag) * names.count);
+ versions.data = version2 = realloc(version2, sizeof(*version) * names.count);
+ }
+ name2[names.count-1] = name[flags.ix];
+ flag2[names.count-1] = (flag[flags.ix] | RPMSENSE_LESS) & ~RPMSENSE_EQUAL;
+ flag2[flags.ix] |= RPMSENSE_GREATER;
+ version2[names.count-1] = strdup(version[flags.ix]);
+ char *v = version2[names.count-1];
+ (*(&v[strlen(v)-1]))++;
+ }
+ }
+ if(name) {
+ flags.count = versions.count = names.count;
+ headerMod(header, &names);
+ headerMod(header, &flags);
+ headerMod(header, &versions);
+ /*rpmtdFree(&names);*/
+ }
+ /*rpmtdFree(&flags);
+ rpmtdFree(&versions);*/
+}
+
+static void
+remap_suggests(Header header) {
+ struct rpmtd_s list, flags, list_evr;
+
+ if (headerGet(header, RPMTAG_REQUIREFLAGS, &flags, HEADERGET_DEFAULT)) {
+ rpm_count_t count = 0;
+ for(flags.ix = 0; flags.ix < (int)flags.count; flags.ix++)
+ if(((uint32_t*)flags.data)[flags.ix] & RPMSENSE_MISSINGOK)
+ count++;
+
+ if(count) {
+ if(headerGet(header, RPMTAG_REQUIRENAME, &list, HEADERGET_DEFAULT)) {
+ headerGet(header, RPMTAG_REQUIREVERSION, &list_evr, HEADERGET_DEFAULT);
+ struct rpmtd_s list_sug, flags_sug, list_evr_sug;
+
+ list_sug.tag = RPMTAG_SUGGESTSNAME;
+ flags_sug.tag = RPMTAG_SUGGESTSFLAGS;
+ list_evr_sug.tag = RPMTAG_SUGGESTSVERSION;
+ list_sug.count = flags_sug.count = list_evr_sug.count = count;
+ list_sug.type = list.type;
+ flags_sug.type = flags_sug.type;
+ list_evr_sug.type = list_evr_sug.type;
+ list_sug.flags = list.flags;
+ flags_sug.flags = flags.flags;
+ list_evr_sug.flags = list_evr.flags;
+ list_sug.data = malloc(count * sizeof(char*));
+ flags_sug.data = malloc(count * sizeof(uint32_t));
+ list_evr_sug.data = malloc(count * sizeof(char*));
+
+ for(list.ix = flags.ix = flags_sug.ix = 0; flags.ix < (int)flags.count; flags.ix++) {
+ if(((uint32_t*)flags.data)[flags.ix] & RPMSENSE_MISSINGOK) {
+ ((char**)list_sug.data)[flags_sug.ix] = ((char**)list.data)[flags.ix];
+ ((uint32_t*)flags_sug.data)[flags_sug.ix] = ((uint32_t*)flags.data)[flags.ix];
+ ((char**)list_evr_sug.data)[flags_sug.ix] = ((char**)list_evr.data)[flags.ix];
+
+ flags_sug.ix++;
+ list.count--;
+ }
+ else {
+ ((char**)list.data)[list.ix] = ((char**)list.data)[flags.ix];
+ ((uint32_t*)flags.data)[list.ix] = ((uint32_t*)flags.data)[flags.ix];
+ ((char**)list_evr.data)[list.ix] = ((char**)list_evr.data)[flags.ix];
+ list.ix++;
+ }
+ }
+ flags.count = list_evr.count = list.count;
+
+ headerMod(header, &list);
+ headerMod(header, &flags);
+ headerMod(header, &list_evr);
+ headerPut(header, &list_sug, HEADERPUT_DEFAULT);
+ /* XXX: unused
+ headerPut(header, &flags_sug, HEADERPUT_DEFAULT);
+ headerPut(header, &list_evr_sug, HEADERPUT_DEFAULT);
+ */
+
+ rpmtdFreeData(&list);
+ rpmtdFreeData(&list_evr);
+
+ rpmtdFreeData(&list_sug);
+ rpmtdFreeData(&flags_sug);
+ rpmtdFreeData(&list_evr_sug);
+ }
+ rpmtdFreeData(&flags);
+ }
+ }
+}
+
+static void
+convert_header(Header header) {
+ if (header) {
+ if (headerIsEntry(header, RPMTAG_DISTEPOCH)) {
+ strip_distepoch(header, RPMTAG_PROVIDEVERSION);
+ strip_distepoch(header, RPMTAG_REQUIREVERSION);
+ strip_distepoch(header, RPMTAG_OBSOLETEVERSION);
+ strip_distepoch(header, RPMTAG_CONFLICTVERSION);
+ }
+ remap_suggests(header);
+ }
+}
+
static int
sigsize_to_filesize(int sigsize) {
return sigsize + 440; /* 440 is the rpm header size (?) empirical, but works */
@@ -222,7 +426,7 @@ ranges_overlap(uint32_t aflags, char *sa, uint32_t bflags, char *sb, int b_nopro
int sense = 0;
char *eosa = strchr(sa, ']');
char *eosb = strchr(sb, ']');
- char *ea, *va, *ra, *eb, *vb, *rb;
+ char *ea, *va, *ra, *da, *eb, *vb, *rb, *db;
if (eosa) *eosa = 0;
if (eosb) *eosb = 0;
@@ -236,6 +440,9 @@ ranges_overlap(uint32_t aflags, char *sa, uint32_t bflags, char *sb, int b_nopro
ea = NULL;
}
if ((ra = strrchr(sa, '-'))) *ra++ = 0;
+ if (ra && (da = strchr(ra, ':'))) *da++ = 0;
+ else da = NULL;
+
/* parse sb as an [epoch:]version[-release] */
for (eb = sb; *sb >= '0' && *sb <= '9'; ++sb);
if (*sb == ':') {
@@ -246,6 +453,8 @@ ranges_overlap(uint32_t aflags, char *sa, uint32_t bflags, char *sb, int b_nopro
eb = NULL;
}
if ((rb = strrchr(sb, '-'))) *rb++ = 0;
+ if (rb && (db = strchr(rb, ':'))) *db++ = 0;
+ else db = NULL;
/* now compare epoch */
if (ea && eb)
sense = rpmvercmp(*ea ? ea : "0", *eb ? eb : "0");
@@ -260,6 +469,8 @@ ranges_overlap(uint32_t aflags, char *sa, uint32_t bflags, char *sb, int b_nopro
sense = rpmvercmp(ra, rb);
}
/* restore all character that have been modified inline */
+ if (db) db[-1] = ':';
+ if (da) da[-1] = ':';
if (rb) rb[-1] = '-';
if (ra) ra[-1] = '-';
if (eb) vb[-1] = ':';
@@ -405,11 +616,28 @@ return_list_str(char *s, Header header, int32_t tag_name, int32_t tag_flags, int
if (tag_flags && tag_version) {
while(ps != NULL) {
++count;
- if (f(s, ps-s, NULL, 0, NULL, param)) return -count;
+ char *tmp, *ps2 = NULL;
+ if((tmp = strchr(s, '[')) &&
+ (tmp = strchr(tmp, '-')) &&
+ (tmp = strchr(tmp, ':')) &&
+ tmp < ps) {
+ backup_char(tmp);
+ *tmp = ']';
+ ps2 = ++tmp;
+ }
+ if (f(s, ps2 ? ps2-s : ps-s, NULL, 0, NULL, param)) { restore_chars(); return -count; }
+ restore_chars();
s = ps + 1; ps = strchr(s, '@');
}
++count;
- if (f(s, 0, NULL, 0, NULL, param)) return -count;
+ if((ps = strchr(s, '[')) &&
+ (ps = strchr(ps, '-')) &&
+ (ps = strchr(ps, ':'))) {
+ backup_char(ps);
+ *ps++ = ']';
+ }
+ if (f(s, ps ? ps-s : 0, NULL, 0, NULL, param)) { restore_chars(); return -count; }
+ restore_chars();
} else {
char *eos;
while(ps != NULL) {
@@ -425,6 +653,9 @@ return_list_str(char *s, Header header, int32_t tag_name, int32_t tag_flags, int
}
} else if (header) {
struct rpmtd_s list, flags, list_evr;
+ memset(&list, 0, sizeof(list));
+ memset(&flags, 0, sizeof(flags));
+ memset(&list_evr, 0, sizeof(list_evr));
if (headerGet(header, tag_name, &list, HEADERGET_DEFAULT)) {
if (tag_flags) headerGet(header, tag_flags, &flags, HEADERGET_DEFAULT);
@@ -622,13 +853,14 @@ return_list_tag(URPM__Package pkg, int32_t tag_name) {
case RPMTAG_ARCH:
{
get_fullname_parts(pkg, &name, &version, &release, &arch, &eos);
- XPUSHs(sv_2mortal(newSVpv(arch, eos-arch)));
+ XPUSHs(sv_2mortal(newSVpv(arch == eos ? "" : arch, eos-arch)));
}
break;
case RPMTAG_SUMMARY:
XPUSHs(sv_2mortal(newSVpv(pkg->summary, 0)));
break;
}
+ restore_chars();
}
PUTBACK;
}
@@ -797,15 +1029,17 @@ pack_header(URPM__Package pkg) {
if (pkg->info == NULL) {
char buff[1024];
char *p = buff;
- char *name = get_name(pkg->h, RPMTAG_NAME);
- char *version = get_name(pkg->h, RPMTAG_VERSION);
- char *release = get_name(pkg->h, RPMTAG_RELEASE);
- char *arch = headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? get_name(pkg->h, RPMTAG_ARCH) : "src";
-
- p += 1 + snprintf(buff, sizeof(buff), "%s-%s-%s.%s@%d@%d@%s", name, version, release, arch,
+ const char *group = get_name(pkg->h, RPMTAG_GROUP);
+ const char *nvra = headerFormat(pkg->h,
+ "%{NAME}-%{VERSION}-%{RELEASE}%|DISTTAG?{-%{DISTTAG}%|DISTEPOCH?"
+ "{%{DISTEPOCH}}|}|.%|ARCH?{%|SOURCERPM?{%{ARCH}}:{src}|}:{}|",
+ NULL
+ );
+ p += 1 + snprintf(buff, sizeof(buff), "%s@%d@%d@%s", nvra,
get_int(pkg->h, RPMTAG_EPOCH), get_int(pkg->h, RPMTAG_SIZE),
- get_name(pkg->h, RPMTAG_GROUP));
+ group);
pkg->info = memcpy(malloc(p-buff), buff, p-buff);
+ _free(nvra);
}
if (pkg->filesize == 0) pkg->filesize = sigsize_to_filesize(get_int(pkg->h, RPMTAG_SIGSIZE));
if (pkg->requires == NULL && pkg->suggests == NULL)
@@ -1269,6 +1503,7 @@ update_header(char *filename, URPM__Package pkg, __attribute__((unused)) int kee
if (fd != NULL) {
if (pkg->h && !(pkg->flag & FLAG_NO_HEADER_FREE)) pkg->h = headerFree(pkg->h);
pkg->h = headerRead(fd, HEADER_MAGIC_YES);
+
pkg->flag &= ~FLAG_NO_HEADER_FREE;
Fclose(fd);
return 1;
@@ -1459,6 +1694,7 @@ Pkg_name(pkg)
get_fullname_parts(pkg, &name, &version, NULL, NULL, NULL);
if (version - name < 1) croak("invalid fullname");
XPUSHs(sv_2mortal(newSVpv(name, version-name-1)));
+ restore_chars();
} else if (pkg->h) {
XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_NAME), 0)));
}
@@ -1474,6 +1710,7 @@ Pkg_version(pkg)
get_fullname_parts(pkg, NULL, &version, &release, NULL, NULL);
if (release - version < 1) croak("invalid fullname");
XPUSHs(sv_2mortal(newSVpv(version, release-version-1)));
+ restore_chars();
} else if (pkg->h) {
XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_VERSION), 0)));
}
@@ -1489,6 +1726,7 @@ Pkg_release(pkg)
get_fullname_parts(pkg, NULL, NULL, &release, &arch, NULL);
if (arch - release < 1) croak("invalid fullname");
XPUSHs(sv_2mortal(newSVpv(release, arch-release-1)));
+ restore_chars();
} else if (pkg->h) {
XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_RELEASE), 0)));
}
@@ -1502,7 +1740,8 @@ Pkg_arch(pkg)
char *eos;
get_fullname_parts(pkg, NULL, NULL, NULL, &arch, &eos);
- XPUSHs(sv_2mortal(newSVpv(arch, eos-arch)));
+ XPUSHs(sv_2mortal(newSVpv(arch == eos ? "" : arch, eos-arch)));
+ restore_chars();
} else if (pkg->h) {
XPUSHs(sv_2mortal(newSVpv(headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? get_name(pkg->h, RPMTAG_ARCH) : "src", 0)));
}
@@ -1539,6 +1778,7 @@ Pkg_is_arch_compat__XS(pkg)
#else
RETVAL = rpmMachineScore(RPM_MACHTABLE_INSTARCH, arch);
#endif
+ restore_chars();
} else {
RETVAL = 0;
}
@@ -1571,6 +1811,7 @@ Pkg_is_platform_compat(pkg)
RETVAL = rpmPlatformScore(platform, NULL, 0);
*eos = '@';
_free(platform);
+ restore_chars();
} else {
#else
croak("is_platform_compat() is available only since rpm 4.4.8");
@@ -1717,7 +1958,8 @@ Pkg_fullname(pkg)
PUSHs(sv_2mortal(newSVpv(name, version-name-1)));
PUSHs(sv_2mortal(newSVpv(version, release-version-1)));
PUSHs(sv_2mortal(newSVpv(release, arch-release-1)));
- PUSHs(sv_2mortal(newSVpv(arch, eos-arch)));
+ PUSHs(sv_2mortal(newSVpv(arch == eos ? "" : arch, eos-arch)));
+ restore_chars();
}
} else if (pkg->h) {
char *name = get_name(pkg->h, RPMTAG_NAME);
@@ -1726,7 +1968,13 @@ Pkg_fullname(pkg)
char *arch = headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? get_name(pkg->h, RPMTAG_ARCH) : "src";
if (gimme == G_SCALAR) {
- XPUSHs(sv_2mortal(newSVpvf("%s-%s-%s.%s", name, version, release, arch)));
+ const char *nvra = headerFormat(pkg->h,
+ "%{NAME}-%{VERSION}-%{RELEASE}%|DISTTAG?{-%{DISTTAG}%|DISTEPOCH?"
+ "{%{DISTEPOCH}}|}|.%|ARCH?{%|SOURCERPM?{%{ARCH}}:{src}|}:{}|",
+ NULL
+ );
+ XPUSHs(sv_2mortal(newSVpvf("%s", nvra)));
+ _free(nvra);
} else if (gimme == G_ARRAY) {
EXTEND(SP, 4);
PUSHs(sv_2mortal(newSVpv(name, 0)));
@@ -1820,6 +2068,7 @@ Pkg_compare_pkg(lpkg, rpkg)
lrelease[-1] = '-';
larch[-1] = '.';
}
+ restore_chars();
croak("undefined package");
}
compare = lepoch - repoch;
@@ -1865,6 +2114,7 @@ Pkg_compare_pkg(lpkg, rpkg)
rrelease[-1] = '-';
rarch[-1] = '.';
}
+ restore_chars();
RETVAL = compare;
}
OUTPUT:
@@ -1938,6 +2188,7 @@ Pkg_compare(pkg, evr)
if (pkg->info) {
_release[-1] = '-';
_eos[-1] = '.';
+ restore_chars();
}
RETVAL = compare;
OUTPUT:
@@ -2005,12 +2256,14 @@ Pkg_filename(pkg)
memcpy(eon, savbuf, 4);
}
} else if (pkg->h) {
- char *name = get_name(pkg->h, RPMTAG_NAME);
- char *version = get_name(pkg->h, RPMTAG_VERSION);
- char *release = get_name(pkg->h, RPMTAG_RELEASE);
- char *arch = headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? get_name(pkg->h, RPMTAG_ARCH) : "src";
-
- XPUSHs(sv_2mortal(newSVpvf("%s-%s-%s.%s.rpm", name, version, release, arch)));
+ const char *nvra = headerFormat(pkg->h,
+ "%{NAME}-%{VERSION}-%{RELEASE}%|DISTTAG?{-%{DISTTAG}%|DISTEPOCH?"
+ "{%{DISTEPOCH}}|}|.%|ARCH?{%|SOURCERPM?{%{ARCH}}:{src}|}:{}|",
+ NULL
+ );
+
+ XPUSHs(sv_2mortal(newSVpvf("%s.rpm", nvra)));
+ _free(nvra);
}
# deprecated
@@ -2027,13 +2280,17 @@ Pkg_header_filename(pkg)
} else if (pkg->h) {
char buff[1024];
char *p = buff;
- char *name = get_name(pkg->h, RPMTAG_NAME);
- char *version = get_name(pkg->h, RPMTAG_VERSION);
- char *release = get_name(pkg->h, RPMTAG_RELEASE);
- char *arch = headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? get_name(pkg->h, RPMTAG_ARCH) : "src";
- p += snprintf(buff, sizeof(buff), "%s-%s-%s.%s", name, version, release, arch);
+ const char *nvra = headerFormat(pkg->h,
+ "%{NAME}-%{VERSION}-%{RELEASE}%|DISTTAG?{-%{DISTTAG}%|DISTEPOCH?"
+ "{%{DISTEPOCH}}|}|.%|ARCH?{%|SOURCERPM?{%{ARCH}}:{src}|}:{}|",
+ NULL
+ );
+
+ p += snprintf(buff, sizeof(buff), "%s", nvra);
XPUSHs(sv_2mortal(newSVpv(buff, p-buff)));
+ _free(nvra);
+
}
void
@@ -3050,7 +3307,18 @@ Trans_add(trans, pkg, ...)
}
}
}
+
+ if(headerIsEntry(pkg->h, RPMTAG_DISTEPOCH)) {
+ pretend_distepoch(pkg->h, RPMTAG_REQUIRENAME, RPMTAG_REQUIREFLAGS, RPMTAG_REQUIREVERSION);
+ }
+
RETVAL = rpmtsAddInstallElement(trans->ts, pkg->h, (fnpyKey)(1+(long)(pkg->flag & FLAG_ID)), update, relocations) == 0;
+
+ rpmte te = rpmtsElement(trans->ts, 0);
+ headerLink(pkg->h);
+ rpmteSetHeader(te, pkg->h);
+ headerUnlink(pkg->h);
+
/* free allocated memory, check rpm is copying it just above, at least in 4.0.4 */
#ifndef RPM_ORG
rpmfiFreeRelocations(relocations);
@@ -3525,6 +3793,8 @@ Urpm_parse_hdlist__XS(urpm, filename, ...)
struct s_Package pkg, *_pkg;
SV *sv_pkg;
+ convert_header(header);
+
memset(&pkg, 0, sizeof(struct s_Package));
pkg.flag = 1 + av_len(depslist);
pkg.h = header;
@@ -3885,6 +4155,9 @@ Urpm_stream2header(fp)
pkg->h = headerRead(fd, HEADER_MAGIC_YES);
if (pkg->h) {
SV *sv_pkg;
+
+ convert_header(pkg->h);
+
EXTEND(SP, 1);
sv_pkg = sv_newmortal();
sv_setref_pv(sv_pkg, "URPM::Package", (void*)pkg);