diff options
author | Per Øyvind Karlsen <peroyvind@mandriva.org> | 2011-06-28 14:43:01 +0000 |
---|---|---|
committer | Per Øyvind Karlsen <peroyvind@mandriva.org> | 2011-06-28 14:43:01 +0000 |
commit | 2ab1c41aa1c488c9942fde9f793ac59b3d1c6706 (patch) | |
tree | 4e20aec8d34c4d5c68304c1a8ac0a017ebb71e4e | |
parent | 3864ff992fb4437f41269246ba61496f1511880f (diff) | |
download | perl-URPM-2ab1c41aa1c488c9942fde9f793ac59b3d1c6706.tar perl-URPM-2ab1c41aa1c488c9942fde9f793ac59b3d1c6706.tar.gz perl-URPM-2ab1c41aa1c488c9942fde9f793ac59b3d1c6706.tar.bz2 perl-URPM-2ab1c41aa1c488c9942fde9f793ac59b3d1c6706.tar.xz perl-URPM-2ab1c41aa1c488c9942fde9f793ac59b3d1c6706.zip |
* merge changes from 3.37.2 (distepoch & disttag support for upgrades) and retrofit it to rpm 4.4 API
-rw-r--r-- | NEWS | 12 | ||||
-rw-r--r-- | URPM.xs | 364 |
2 files changed, 348 insertions, 28 deletions
@@ -1,3 +1,15 @@ +Version 3.18.2 - 28 June 2011, by Per Øyvind Karlsen + +- support getting disttag & distepoch from synthesis +- fix URPM::Package->distepoch to actually work +- add disttag & distepoch at end of @ +- 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.18.1 - 14 October 2008, by Pascal "Pixel" Rigaux - $trans->run can now return both the translated errors, and some parsable @@ -127,6 +127,7 @@ typedef struct s_Package* URPM__Package; #define FILENAME_TAG 1000000 #define FILESIZE_TAG 1000001 +#define RPMTAG_DISTEPOCH 1218 #define FILTER_MODE_ALL_FILES 0 #define FILTER_MODE_CONF_FILES 2 @@ -136,6 +137,8 @@ typedef struct s_Package* URPM__Package; 1 for rpm 4.2 and better new approach. */ #define PROMOTE_EPOCH_SENSE 1 +static struct headerTagTableEntry_s *ourTagTable = NULL; + static ssize_t write_nocheck(int fd, const void *buf, size_t count) { return write(fd, buf, count); } @@ -159,6 +162,25 @@ void 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) { @@ -170,12 +192,35 @@ 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 i, disttag = 0; + char *tmp = pkg->info; + for (i = 0; i < 4 && tmp != NULL; i++) + tmp = strchr(++tmp, '@'); + if (tmp++ != NULL && *tmp != '@') + disttag = 1; + /* 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")) + disttag = 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 (disttag) { + 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; @@ -210,6 +255,136 @@ get_int(Header header, int_32 tag) { return i ? *i : 0; } +static void +strip_distepoch(Header header, int_32 tag) { + int_32 type, count; + char **list; + int ix; + + headerGetEntry(header, tag, &type, (void **) &list, &count); + for (ix = 0; ix < count; ix++) { + char *tmp = strchr(list[ix], '-'); + if(tmp) { + tmp = strchr(tmp, ':'); + if(tmp) { + memset(tmp, 0, strlen(tmp)); + } + } + } + headerModifyEntry(header, tag, RPM_STRING_ARRAY_TYPE, list, 1); +} + +static void +pretend_distepoch(Header header, int_32 names_tag, int_32 flags_tag, int_32 versions_tag) { + char **name = NULL, **name2 = NULL; + int_32 *flag, *flag2; + int_32 type, type2; + int_32 count, count2; + int_32 ix; + char **version = NULL, **version2 = NULL; + char *EVR = headerSprintf(header, "%|EPOCH?{%{EPOCH}:}|%{VERSION}-%{RELEASE}", ourTagTable, headerDefaultFormats, NULL); + + headerGetEntry(header, flags_tag, &type, (void **) &flag, &count); + headerGetEntry(header, versions_tag, &type2, (void **) &version, &count2); + + for (ix = 0; ix < (int)count; ix++) { + if(!(flag[ix] & ((RPMSENSE_LESS|RPMSENSE_GREATER|~RPMSENSE_EQUAL))) && version[ix] && *version[ix] && !strcmp(EVR, version[ix])) { + if(!name) { + int_32 count3, type3; + headerGetEntry(header, names_tag, &type3, (void **) &name, &count3); + + name2 = malloc(++count * sizeof(*name)); + memcpy(name2, name, sizeof(*name)*count); + flag2 = malloc(count * sizeof(flag)); + memcpy(flag2, flag, sizeof(flag)*count); + version2 = malloc(count * sizeof(*version)); + memcpy(version2, version, sizeof(*version)*count); + } else { + name2 = realloc(name2, sizeof(*name) * ++count); + flag2 = realloc(flag2, sizeof(flag) * count); + version2 = realloc(version2, sizeof(*version) * count); + } + name2[count-1] = name[ix]; + flag2[count-1] = (flag[ix] | RPMSENSE_LESS) & ~RPMSENSE_EQUAL; + flag2[ix] |= RPMSENSE_GREATER; + version2[count-1] = strdup(version[ix]); + char *v = version2[count-1]; + (*(&v[strlen(v)-1]))++; + } + } + if(name) { + headerModifyEntry(header, names_tag, RPM_STRING_ARRAY_TYPE, name, count); + headerModifyEntry(header, flags_tag, RPM_INT32_TYPE, flag, count); + headerModifyEntry(header, versions_tag, RPM_STRING_ARRAY_TYPE, version, count); + } +} + +static void +remap_suggests(Header header) { + char **list, **list_evr; + int_32 *flags; + int_32 type, count, ix; + + if (headerGetEntry(header, RPMTAG_REQUIREFLAGS, &type, (void **) &flags, &count)) { + int_32 count_sug = 0; + for(ix = 0; ix < count_sug; ix++) + if(flags[ix] & RPMSENSE_MISSINGOK) + count_sug++; + + if(count_sug) { + if(headerGetEntry(header, RPMTAG_REQUIRENAME, &type, (void **) &list, &count)) { + headerGetEntry(header, RPMTAG_REQUIREVERSION, &type, (void **) &list_evr, &count); + char **list_sug, **list_evr_sug; + int_32 *flags_sug; + int_32 ix_sug, ix_list; + + list_sug = malloc(count_sug * sizeof(char*)); + flags_sug = malloc(count_sug * sizeof(int_32)); + list_evr_sug = malloc(count_sug * sizeof(char*)); + + for(ix_sug = ix_list = ix = 0; ix < count; ix++) { + if(flags[ix] & RPMSENSE_MISSINGOK) { + list_sug[ix_sug] = list[ix]; + flags_sug[ix_sug] = flags[ix]; + list_evr_sug[ix_sug] = list_evr[ix]; + + ix_sug++; + count--; + } + else { + list[ix_list] = list[ix]; + flags[ix_list] = flags[ix]; + list_evr[ix_list] = list_evr[ix]; + ix_list++; + } + } + headerModifyEntry(header, RPMTAG_REQUIRENAME, RPM_STRING_ARRAY_TYPE, list, count); + headerModifyEntry(header, RPMTAG_REQUIREFLAGS, RPM_INT32_TYPE, flags, count); + headerModifyEntry(header, RPMTAG_REQUIREVERSION, RPM_STRING_ARRAY_TYPE, list_evr, count); + + headerAddEntry(header, RPMTAG_SUGGESTSNAME, RPM_STRING_ARRAY_TYPE, list_sug, count_sug); + /* XXX: unused + headerAddEntry(header, RPMTAG_SUGGESTSFLAGS, RPM_INT32_TYPE, flags_sug, count_sug); + headerAddEntry(header, RPMTAG_SUGGESTSVERSION, RPM_STRING_ARRAY_TYPE, list_evr_sug, count_sug); + */ + } + } + } +} + +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 */ @@ -254,7 +429,7 @@ ranges_overlap(int_32 aflags, char *sa, int_32 bflags, char *sb, int b_nopromote 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; @@ -268,6 +443,9 @@ ranges_overlap(int_32 aflags, char *sa, int_32 bflags, char *sb, int b_nopromote 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 == ':') { @@ -278,6 +456,8 @@ ranges_overlap(int_32 aflags, char *sa, int_32 bflags, char *sb, int b_nopromote 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"); @@ -292,6 +472,8 @@ ranges_overlap(int_32 aflags, char *sa, int_32 bflags, char *sb, int b_nopromote 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] = ':'; @@ -437,11 +619,28 @@ return_list_str(char *s, Header header, int_32 tag_name, int_32 tag_flags, int_3 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) { @@ -652,13 +851,14 @@ return_list_tag(URPM__Package pkg, int_32 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; } @@ -828,15 +1028,28 @@ 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 *disttag = get_name(pkg->h, RPMTAG_DISTTAG); + const char *distepoch = get_name(pkg->h, RPMTAG_DISTEPOCH); + const char *nvra = headerSprintf(pkg->h, + "%{NAME}-%{VERSION}-%{RELEASE}%|DISTTAG?{-%{DISTTAG}%|DISTEPOCH?" + "{%{DISTEPOCH}}|}|.%|ARCH?{%|SOURCERPM?{%{ARCH}}:{src}|}:{}|", + ourTagTable, headerDefaultFormats, NULL + ); + p += 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); + if (*disttag || *distepoch) { + p = stpcpy(p, "@"); + if (*disttag) + p = stpcpy(p, disttag); + p = stpcpy(p, "@"); + if (*distepoch) + p = stpcpy(p, distepoch); + } + *++p = '\0'; 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) @@ -1298,6 +1511,7 @@ update_header(char *filename, URPM__Package pkg, int keep_all_tags, int vsflags) if (fd != NULL) { if (pkg->h && !(pkg->flag & FLAG_NO_HEADER_FREE)) headerFree(pkg->h); pkg->h = headerRead(fd, HEADER_MAGIC_YES); + pkg->flag &= ~FLAG_NO_HEADER_FREE; Fclose(fd); return 1; @@ -1494,6 +1708,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))); } @@ -1509,6 +1724,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))); } @@ -1523,7 +1739,8 @@ 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))); + XPUSHs(sv_2mortal(newSVpv(release, arch[-2] ? arch-release-1 : 0))); + restore_chars(); } else if (pkg->h) { XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_RELEASE), 0))); } @@ -1537,7 +1754,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))); } @@ -1574,6 +1792,7 @@ Pkg_is_arch_compat__XS(pkg) #else RETVAL = rpmMachineScore(RPM_MACHTABLE_INSTARCH, arch); #endif + restore_chars(); } else { RETVAL = 0; } @@ -1605,6 +1824,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"); @@ -1750,8 +1970,9 @@ Pkg_fullname(pkg) EXTEND(SP, 4); 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(release, arch[-2] ? arch-release-1 : 0))); + PUSHs(sv_2mortal(newSVpv(arch == eos ? "" : arch, eos-arch))); + restore_chars(); } } else if (pkg->h) { char *name = get_name(pkg->h, RPMTAG_NAME); @@ -1760,7 +1981,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 = headerSprintf(pkg->h, + "%{NAME}-%{VERSION}-%{RELEASE}%|DISTTAG?{-%{DISTTAG}%|DISTEPOCH?" + "{%{DISTEPOCH}}|}|.%|ARCH?{%|SOURCERPM?{%{ARCH}}:{src}|}:{}|", + ourTagTable, headerDefaultFormats, NULL + ); + XPUSHs(sv_2mortal(newSVpvf("%s", nvra))); + _free(nvra); } else if (gimme == G_ARRAY) { EXTEND(SP, 4); PUSHs(sv_2mortal(newSVpv(name, 0))); @@ -1854,6 +2081,7 @@ Pkg_compare_pkg(lpkg, rpkg) lrelease[-1] = '-'; larch[-1] = '.'; } + restore_chars(); croak("undefined package"); } compare = lepoch - repoch; @@ -1899,6 +2127,7 @@ Pkg_compare_pkg(lpkg, rpkg) rrelease[-1] = '-'; rarch[-1] = '.'; } + restore_chars(); RETVAL = compare; } OUTPUT: @@ -1933,7 +2162,7 @@ Pkg_compare(pkg, evr) _epoch = get_int(pkg->h, RPMTAG_EPOCH); } else croak("undefined package"); if (!compare) { - char *epoch, *version, *release; + char *epoch, *version, *release, *distepoch; /* extract epoch and version from evr */ version = evr; @@ -1955,6 +2184,10 @@ Pkg_compare(pkg, evr) /* continue extracting release if any */ if ((release = strrchr(version, '-')) != NULL) { *release++ = 0; + /* XXX: compare distepoch rather than just ignoring? */ + if ((distepoch = strrchr(release, ':')) != NULL) + *distepoch++ = 0; + compare = rpmvercmp(_version, version); if (!compare) { /* need to compare with release here */ @@ -1963,6 +2196,8 @@ Pkg_compare(pkg, evr) compare = rpmvercmp(_release, release); } release[-1] = '-'; /* restore in memory modification */ + if (distepoch != NULL) + distepoch[-1] = ':'; } else { compare = rpmvercmp(_version, version); } @@ -1972,6 +2207,7 @@ Pkg_compare(pkg, evr) if (pkg->info) { _release[-1] = '-'; _eos[-1] = '.'; + restore_chars(); } RETVAL = compare; OUTPUT: @@ -2039,12 +2275,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 = headerSprintf(pkg->h, + "%{NAME}-%{VERSION}-%{RELEASE}%|DISTTAG?{-%{DISTTAG}%|DISTEPOCH?" + "{%{DISTEPOCH}}|}|.%|ARCH?{%|SOURCERPM?{%{ARCH}}:{src}|}:{}|", + ourTagTable, headerDefaultFormats, NULL + ); + + XPUSHs(sv_2mortal(newSVpvf("%s.rpm", nvra))); + _free(nvra); } # deprecated @@ -2061,13 +2299,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 = headerSprintf(pkg->h, + "%{NAME}-%{VERSION}-%{RELEASE}%|DISTTAG?{-%{DISTTAG}%|DISTEPOCH?" + "{%{DISTEPOCH}}|}|.%|ARCH?{%|SOURCERPM?{%{ARCH}}:{src}|}:{}|", + ourTagTable, headerDefaultFormats, NULL + ); + + p += snprintf(buff, sizeof(buff), "%s", nvra); XPUSHs(sv_2mortal(newSVpv(buff, p-buff))); + _free(nvra); + } void @@ -2279,6 +2521,36 @@ Pkg_dirnames(pkg) xpush_simple_list_str(pkg->h, RPMTAG_DIRNAMES); SPAGAIN; +void Pkg_distepoch(pkg) + URPM::Package pkg + PPCODE: + if (pkg->info) { + int i; + char *tmp = pkg->info, *eos = NULL; + for (i = 0; i < 5 && tmp != NULL; i++) + tmp = strchr(++tmp, '@'); + if (tmp != NULL && *tmp) + eos = strchr(++tmp, '@'); + XPUSHs(sv_2mortal(newSVpv((tmp && *tmp != '@') ? tmp : "", eos ? eos-tmp : 0))); + } else if (pkg->h) { + XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_DISTEPOCH), 0))); + } + +void Pkg_disttag(pkg) + URPM::Package pkg + PPCODE: + if (pkg->info) { + int i; + char *tmp = pkg->info, *eos = NULL; + for (i = 0; i < 4 && tmp != NULL; i++) + tmp = strchr(++tmp, '@'); + if (tmp != NULL && *tmp) + eos = strchr(++tmp, '@'); + XPUSHs(sv_2mortal(newSVpv((tmp && *tmp != '@') ? tmp : "", eos ? eos-tmp : 0))); + } else if (pkg->h) { + XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_DISTTAG), 0))); + } + void Pkg_filelinktos(pkg) URPM::Package pkg @@ -3062,7 +3334,35 @@ Trans_add(trans, pkg, ...) } } } + + if(headerIsEntry(pkg->h, RPMTAG_DISTEPOCH)) { + pretend_distepoch(pkg->h, RPMTAG_REQUIRENAME, RPMTAG_REQUIREFLAGS, RPMTAG_REQUIREVERSION); + } + remap_suggests(pkg->h); + /* If we're going to update to rpm 5.3, we'll create an empty DB_CONFIG + * first iff there's no existing DB_CONFIG in place. This will prevent + * switching to possibly incompatible configurations during upgrade. + */ + if (!strcmp(get_name(pkg->h, RPMTAG_NAME), "rpm")) { + const char *version = get_name(pkg->h, RPMTAG_VERSION); + if (rpmvercmp(version, "5.3") >= 0) { + const char *fn = rpmGetPath("%{_dbpath}", "/DB_CONFIG", NULL); + struct stat st; + if (stat(fn, &st)) { + FD_t fd = Fopen(fn, "w"); + Fclose(fd); + } + fn = _free(fn); + } + } + 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 */ free(relocations); } else RETVAL = 0; @@ -3328,6 +3628,9 @@ MODULE = URPM PACKAGE = URPM PREFIX = Urpm_ BOOT: (void) read_config_files(0); +ourTagTable = malloc((sizeof(rpmTagTable[0])*rpmTagTableSize)+sizeof(rpmTagTable[0])); +memcpy(ourTagTable, rpmTagTable, sizeof(rpmTagTable[0])*rpmTagTableSize); +ourTagTable[rpmTagTableSize] = (struct headerTagTableEntry_s){ "RPMTAG_DISTEPOCH", RPMTAG_DISTEPOCH, RPM_STRING_TYPE }; void Urpm_bind_rpm_textdomain_codeset() @@ -3559,6 +3862,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; @@ -3888,6 +4193,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); |