diff options
author | Thierry Vignaud <tv@mageia.org> | 2012-06-26 18:18:30 +0000 |
---|---|---|
committer | Thierry Vignaud <tv@mageia.org> | 2012-06-26 18:18:30 +0000 |
commit | f3a5346c94ceed8c28a10511db0b1019ec532971 (patch) | |
tree | 20a447700578ea9fcd83842600b55f1a0299329a | |
parent | 0f5e4ddc50cf8f93de30d8c10477fff5d9d99282 (diff) | |
parent | 4e351504dc092a0a99f33dcbd301f48877eaa2f0 (diff) | |
download | perl-URPM-f3a5346c94ceed8c28a10511db0b1019ec532971.tar perl-URPM-f3a5346c94ceed8c28a10511db0b1019ec532971.tar.gz perl-URPM-f3a5346c94ceed8c28a10511db0b1019ec532971.tar.bz2 perl-URPM-f3a5346c94ceed8c28a10511db0b1019ec532971.tar.xz perl-URPM-f3a5346c94ceed8c28a10511db0b1019ec532971.zip |
branch
-rw-r--r-- | MANIFEST | 1 | ||||
-rwxr-xr-x | Makefile.PL | 4 | ||||
-rw-r--r-- | NEWS | 56 | ||||
-rw-r--r-- | URPM.pm | 26 | ||||
-rw-r--r-- | URPM.xs | 1583 | ||||
-rw-r--r-- | URPM/Query.pm | 45 | ||||
-rw-r--r-- | URPM/Resolve.pm | 22 | ||||
-rw-r--r-- | t/01setter-getter.t | 69 | ||||
-rw-r--r-- | t/fatal.t | 4 | ||||
-rw-r--r-- | t/parse.t | 15 | ||||
-rw-r--r-- | t/synthesis.t | 20 |
11 files changed, 1153 insertions, 692 deletions
@@ -5,6 +5,7 @@ typemap URPM.xs URPM.pm URPM/Build.pm +URPM/Query.pm URPM/Resolve.pm URPM/Signature.pm t/00prepare.t diff --git a/Makefile.PL b/Makefile.PL index fd41a21..fc330e9 100755 --- a/Makefile.PL +++ b/Makefile.PL @@ -27,7 +27,7 @@ $version =~ s/(-.*)|(\.DEVEL)//; chomp $version; $version =~ s/(RPM version )|(rpm \(RPM\) )//; my $hversion = hexversion($version); -$hversion ge hexversion("4.9") or die "Unable to build URPM with too old (or undetected) rpm version $version\n"; +$hversion ge hexversion("4.8") or die "Unable to build URPM with too old (or undetected) rpm version $version\n"; # to generate the ChangeLog depending on the checkout layout my $commonusername = "../common/"; @@ -69,6 +69,6 @@ WriteMakefile( VERSION_FROM => 'URPM.pm', LIBS => [ $ldflags ], INC => '-I/usr/include/rpm', - dist => { COMPRESS => "xz -f", SUFFIX => ".xz" }, + dist => { COMPRESS => "xz", SUFFIX => ".xz" }, realclean => { FILES => "t/RPMS/noarch/*" }, ); @@ -1,59 +1,3 @@ -Version 4.9 - 25 June 2012 - -- fix setting rflags on packages (mga#6532) - -Version 4.8 - 22 June 2012 - -- enable to read xz & bzip2 compressed synthesis -- internal cleanups -- ranges_overlap(): use rpm to compute whether it overlaps or not - -Version 4.7 - 19 June 2012 - -- workaround changes in rpm-4.10.0 leaving us to leak fds (mga#6453) - -Version 4.6 - 18 June 2012 - -- drop 'direction' parameter in obsoletes_overlap() & provides_overlap() -- fix default 'direction' for provides_overlap() - (regression in URPM-4.2) -- internal cleanups - -Version 4.5 - 17 June 2012 - -- drop support for old mdv2008.0 suggests (RPMTAG_REQUIRENAME + RPMSENSE_MISSINGOK) -- internal cleanups - -Version 4.4 - 15 June 2012 - -- internal cleanups -- obsoletes_overlap(), ranges_overlap(): drop unused 'nopromotion' parameter - (always hardcoded to 1 at least for 5 years) - -Version 4.3 - 14 June 2012 - -- fix a very old segfault in unused code -- internal cleanups -- reduce code size - -Version 4.2 - 13 June 2012 - -- clean DB API (needs a new urpmi) -- internal cleanups -- reduce code size - -Version 4.1 - 11 June 2012 - -- drop import_pubkey function (dead for 5 years) -- fix importing pubkeys with rpm-4.10.0 (eg: when adding media) - -Version 4.0 - 8 June 2012 - -- drop URPM::Query (broken for years) -- drop support for rpm-4.8.x -- kill functions unimplemented for years -- reduce code size - Version 3.40 - 16 March 2012 - add URPM::traverse_tag_find() for urpme --env @@ -11,7 +11,7 @@ use URPM::Resolve; use URPM::Signature; our @ISA = qw(DynaLoader); -our $VERSION = '4.9'; +our $VERSION = '3.40'; URPM->bootstrap($VERSION); @@ -320,7 +320,7 @@ parse_synthesis()). Force the re-reading of the RPM configuration files. -=item URPM::ranges_overlap($range1, $range2) +=item URPM::ranges_overlap($range1, $range2 [, $nopromoteepoch]) This utility function compares two version ranges, in order to calculate dependencies properly. The ranges have roughly the form @@ -329,6 +329,13 @@ dependencies properly. The ranges have roughly the form where epoch, version and release are RPM-style version numbers. +If the optional parameter $nopromoteepoch is true, and if the 2nd range has no +epoch while the first one has one, then the 2nd range is assumed to have an +epoch C<== 0>. + +B<Warning>: $nopromoteepoch actually defaults to 1, so if you're going to +pass a variable, make sure undef is treated like 1, not 0. + =item $urpm->parse_synthesis($file [, callback => sub {...} ]) This method gets the B<depslist> and the B<provides> from a synthesis file @@ -615,6 +622,12 @@ Returns whether this package is compatible with the current machine's architecture. 0 means not compatible. The lower the result is, the preferred the package is. +=item $package->is_platform_compat() + +Return whether this package is compatible with the current machine's +platform configuration (/etc/rpm/platform). 0 mean not compatible. +The lower the result is the preferred the package is. + =item $package->license() =item $package->name() @@ -629,7 +642,7 @@ Full obsoletes tags Just the obsoleted package name. -=item $package->obsoletes_overlap($s) +=item $package->obsoletes_overlap($s, [$nopromoteepoch, [$direction] ]) =item $package->os() @@ -647,7 +660,7 @@ Full provides tags Just the provided package name. -=item $package->provides_overlap($s) +=item $package->provides_overlap($s, [$nopromoteepoch,] [$direction]) =item $package->rate() @@ -818,6 +831,11 @@ Sets rpm verbosity level. $level is an integer between 2 (RPMMESS_CRIT) and 7 =item rpmErrorWriteTo($fd) +=item platformscore($platform) + +Return the score of $platform according computer's configuration. +0 mean not compatible, lower is prefered. + =item archscore($arch) Return the score of the given arch. 0 mean not compatible, @@ -20,15 +20,15 @@ #include <sys/wait.h> #include <fcntl.h> #include <unistd.h> +#include <zlib.h> #include <libintl.h> -// fix compiling (error: conflicting types for ‘fflush’): #undef Fflush #undef Mkdir #undef Stat #undef Fstat -static inline void *_free(const void * p) { +static inline void *_free(const void * p) { if (p != NULL) free((void *)p); return NULL; } @@ -99,6 +99,11 @@ typedef struct s_Package* URPM__Package; #define FILTER_MODE_ALL_FILES 0 #define FILTER_MODE_CONF_FILES 2 +/* promote epoch sense should be : + 0 for compability with old packages + 1 for rpm 4.2 and better new approach. */ +#define PROMOTE_EPOCH_SENSE 1 + static ssize_t write_nocheck(int fd, const void *buf, size_t count) { return write(fd, buf, count); } @@ -108,34 +113,11 @@ static const void* unused_variable(const void *p) { static int rpmError_callback_data; -static int rpmError_callback() { +int rpmError_callback() { write_nocheck(rpmError_callback_data, rpmlogMessage(), strlen(rpmlogMessage())); return RPMLOG_DEFAULT; } -static inline int _run_cb_while_traversing(SV *callback, Header header) { - dSP; - URPM__Package pkg = calloc(1, sizeof(struct s_Package)); - - pkg->flag = FLAG_ID_INVALID | FLAG_NO_HEADER_FREE; - pkg->h = header; - - PUSHMARK(SP); - mXPUSHs(sv_setref_pv(newSVpvs(""), "URPM::Package", pkg)); - PUTBACK; - - int count = call_sv(callback, G_SCALAR); - - SPAGAIN; - pkg->h = NULL; /* avoid using it anymore, in case it has been copied inside callback */ - return count; -} - -static inline void _header_free(URPM__Package pkg) { - if (pkg->h && !(pkg->flag & FLAG_NO_HEADER_FREE)) - pkg->h = headerFree(pkg->h); -} - static int rpm_codeset_is_utf8 = 0; static SV* @@ -150,8 +132,6 @@ 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; - if (!pkg->info) - return; if ((_eos = strchr(pkg->info, '@')) != NULL) { *_eos = 0; /* mark end of string to enable searching backwards */ if ((_arch = strrchr(pkg->info, '.')) != NULL) { @@ -174,7 +154,7 @@ get_fullname_parts(URPM__Package pkg, char **name, char **version, char **releas } static char * -get_name(const Header header, rpmTag tag) { +get_name(Header header, int32_t tag) { struct rpmtd_s val; headerGet(header, tag, &val, HEADERGET_MINMEM); @@ -182,13 +162,8 @@ get_name(const Header header, rpmTag tag) { return name ? name : ""; } -static char* -get_arch(const Header header) { - return headerIsEntry(header, RPMTAG_SOURCERPM) ? get_name(header, RPMTAG_ARCH) : "src"; -} - static int -get_int(const Header header, rpmTag tag) { +get_int(Header header, int32_t tag) { struct rpmtd_s val; headerGet(header, tag, &val, HEADERGET_DEFAULT); @@ -202,24 +177,21 @@ get_filesize(const Header h) { } static int -print_list_entry(char *buff, int sz, const char *name, rpmsenseFlags flags, const char *evr) { +print_list_entry(char *buff, int sz, const char *name, uint32_t flags, const char *evr) { int len = strlen(name); char *p = buff; - if (len >= sz || !strncmp(name, "rpmlib(", 7)) - return -1; + if (len >= sz || !strncmp(name, "rpmlib(", 7)) return -1; memcpy(p, name, len); p += len; if (flags & (RPMSENSE_PREREQ|RPMSENSE_SCRIPT_PREUN|RPMSENSE_SCRIPT_PRE|RPMSENSE_SCRIPT_POSTUN|RPMSENSE_SCRIPT_POST)) { - if (p - buff + 3 >= sz) - return -1; + if (p - buff + 3 >= sz) return -1; memcpy(p, "[*]", 4); p += 3; } if (evr != NULL) { len = strlen(evr); if (len > 0) { - if (p - buff + 6 + len >= sz) - return -1; + if (p - buff + 6 + len >= sz) return -1; *p++ = '['; if (flags & RPMSENSE_LESS) *p++ = '<'; if (flags & RPMSENSE_GREATER) *p++ = '>'; @@ -236,35 +208,85 @@ print_list_entry(char *buff, int sz, const char *name, rpmsenseFlags flags, cons } static int -ranges_overlap(rpmsenseFlags aflags, char *sa, rpmsenseFlags bflags, char *sb) { +ranges_overlap(uint32_t aflags, char *sa, uint32_t bflags, char *sb, int b_nopromote) { if (!aflags || !bflags) return 1; /* really faster to test it there instead of later */ else { - int res; + int sense = 0; char *eosa = strchr(sa, ']'); char *eosb = strchr(sb, ']'); - rpmds dsa, dsb; + char *ea, *va, *ra, *eb, *vb, *rb; if (eosa) *eosa = 0; if (eosb) *eosb = 0; - - dsa = rpmdsSingle(RPMTAG_REQUIRENAME, "", sa, aflags); - dsb = rpmdsSingle(RPMTAG_REQUIRENAME, "", sb, bflags); - res = rpmdsCompare(dsa, dsb); - rpmdsFree(dsa); - rpmdsFree(dsb); - + /* parse sa as an [epoch:]version[-release] */ + for (ea = sa; *sa >= '0' && *sa <= '9'; ++sa); + if (*sa == ':') { + *sa++ = 0; /* ea could be an empty string (should be interpreted as 0) */ + va = sa; + } else { + va = ea; /* no epoch */ + ea = NULL; + } + if ((ra = strrchr(sa, '-'))) *ra++ = 0; + /* parse sb as an [epoch:]version[-release] */ + for (eb = sb; *sb >= '0' && *sb <= '9'; ++sb); + if (*sb == ':') { + *sb++ = 0; /* ea could be an empty string (should be interpreted as 0) */ + vb = sb; + } else { + vb = eb; /* no epoch */ + eb = NULL; + } + if ((rb = strrchr(sb, '-'))) *rb++ = 0; + /* now compare epoch */ + if (ea && eb) + sense = rpmvercmp(*ea ? ea : "0", *eb ? eb : "0"); + else if (ea && *ea && atol(ea) > 0) + sense = b_nopromote ? 1 : 0; + else if (eb && *eb && atol(eb) > 0) + sense = -1; + /* now compare version and release if epoch has not been enough */ + if (sense == 0) { + sense = rpmvercmp(va, vb); + if (sense == 0 && ra && *ra && rb && *rb) + sense = rpmvercmp(ra, rb); + } + /* restore all character that have been modified inline */ + if (rb) rb[-1] = '-'; + if (ra) ra[-1] = '-'; + if (eb) vb[-1] = ':'; + if (ea) va[-1] = ':'; if (eosb) *eosb = ']'; if (eosa) *eosa = ']'; - - return res; + /* finish the overlap computation */ + if (sense < 0 && ((aflags & RPMSENSE_GREATER) || (bflags & RPMSENSE_LESS))) + return 1; + else if (sense > 0 && ((aflags & RPMSENSE_LESS) || (bflags & RPMSENSE_GREATER))) + return 1; + else if (sense == 0 && (((aflags & RPMSENSE_EQUAL) && (bflags & RPMSENSE_EQUAL)) || + ((aflags & RPMSENSE_LESS) && (bflags & RPMSENSE_LESS)) || + ((aflags & RPMSENSE_GREATER) && (bflags & RPMSENSE_GREATER)))) + return 1; + else + return 0; } } -typedef int (*callback_list_str)(char *s, int slen, const char *name, const rpmsenseFlags flags, const char *evr, void *param); +static int has_old_suggests; +int32_t is_old_suggests(int32_t flags) { + int is = flags & RPMSENSE_MISSINGOK; + if (is) has_old_suggests = is; + return is; +} +int32_t is_not_old_suggests(int32_t flags) { + return !is_old_suggests(flags); +} + +typedef int (*callback_list_str)(char *s, int slen, const char *name, const uint32_t flags, const char *evr, void *param); static int -callback_list_str_xpush(char *s, int slen, const char *name, rpmsenseFlags flags, const char *evr, __attribute__((unused)) void *param) { +callback_list_str_xpush(char *s, int slen, const char *name, uint32_t flags, const char *evr, __attribute__((unused)) void *param) { dSP; if (s) mXPUSHs(newSVpv(s, slen)); @@ -279,11 +301,26 @@ callback_list_str_xpush(char *s, int slen, const char *name, rpmsenseFlags flags return 0; } static int -callback_list_str_xpush_requires(char *s, int slen, const char *name, const rpmsenseFlags flags, const char *evr, __attribute__((unused)) void *param) { +callback_list_str_xpush_requires(char *s, int slen, const char *name, const uint32_t flags, const char *evr, __attribute__((unused)) void *param) { dSP; if (s) mXPUSHs(newSVpv(s, slen)); - else { + else if (is_not_old_suggests(flags)) { + char buff[4096]; + int len = print_list_entry(buff, sizeof(buff)-1, name, flags, evr); + if (len >= 0) + mXPUSHs(newSVpv(buff, len)); + } + PUTBACK; + /* returning zero indicates to continue processing */ + return 0; +} +static int +callback_list_str_xpush_old_suggests(char *s, int slen, const char *name, uint32_t flags, const char *evr, __attribute__((unused)) void *param) { + dSP; + if (s) + mXPUSHs(newSVpv(s, slen)); + else if (is_old_suggests(flags)) { char buff[4096]; int len = print_list_entry(buff, sizeof(buff)-1, name, flags, evr); if (len >= 0) @@ -295,14 +332,15 @@ callback_list_str_xpush_requires(char *s, int slen, const char *name, const rpms } struct cb_overlap_s { - rpmsenseFlags flags; - int direction; /* indicate to compare the above at left or right to the iteration element */ char *name; + int32_t flags; char *evr; + int direction; /* indicate to compare the above at left or right to the iteration element */ + int b_nopromote; }; static int -callback_list_str_overlap(char *s, int slen, const char *name, rpmsenseFlags flags, const char *evr, void *param) { +callback_list_str_overlap(char *s, int slen, const char *name, uint32_t flags, const char *evr, void *param) { struct cb_overlap_s *os = (struct cb_overlap_s *)param; int result = 0; char *eos = NULL; @@ -312,11 +350,7 @@ callback_list_str_overlap(char *s, int slen, const char *name, rpmsenseFlags fla /* we need to extract name, flags and evr from a full sense information, store result in local copy */ if (s) { - if (slen) { - eos = s + slen; - eosc = *eos; - *eos = 0; - } + if (slen) { eos = s + slen; eosc = *eos; *eos = 0; } name = s; while (*s && *s != ' ' && *s != '[' && *s != '<' && *s != '>' && *s != '=') ++s; if (*s) { @@ -335,17 +369,14 @@ callback_list_str_overlap(char *s, int slen, const char *name, rpmsenseFlags fla } /* mark end of name */ - if (eon) { - eonc = *eon; - *eon = 0; - } + if (eon) { eonc = *eon; *eon = 0; } /* names should be equal, else it will not overlap */ if (!strcmp(name, os->name)) { /* perform overlap according to direction needed, negative for left */ if (os->direction < 0) - result = ranges_overlap(os->flags, os->evr, flags, (char *) evr); + result = ranges_overlap(os->flags, os->evr, flags, (char *) evr, os->b_nopromote); else - result = ranges_overlap(flags, (char *) evr, os->flags, os->evr); + result = ranges_overlap(flags, (char *) evr, os->flags, os->evr, os->b_nopromote); } /* fprintf(stderr, "cb_list_str_overlap result=%d, os->direction=%d, os->name=%s, os->evr=%s, name=%s, evr=%s\n", @@ -359,7 +390,7 @@ callback_list_str_overlap(char *s, int slen, const char *name, rpmsenseFlags fla } static int -return_list_str(char *s, const Header header, rpmTag tag_name, rpmTag tag_flags, rpmTag tag_version, callback_list_str f, void *param) { +return_list_str(char *s, Header header, int32_t tag_name, int32_t tag_flags, int32_t tag_version, callback_list_str f, void *param) { int count = 0; if (s != NULL) { @@ -367,29 +398,23 @@ return_list_str(char *s, const Header header, rpmTag tag_name, rpmTag tag_flags, if (tag_flags && tag_version) { while(ps != NULL) { ++count; - if (f(s, ps-s, NULL, 0, NULL, param)) - return -count; + if (f(s, ps-s, NULL, 0, NULL, param)) return -count; s = ps + 1; ps = strchr(s, '@'); } ++count; - if (f(s, 0, NULL, 0, NULL, param)) - return -count; + if (f(s, 0, NULL, 0, NULL, param)) return -count; } else { char *eos; while(ps != NULL) { *ps = 0; eos = strchr(s, '['); if (!eos) eos = strchr(s, ' '); ++count; - if (f(s, eos ? eos-s : ps-s, NULL, 0, NULL, param)) { - *ps = '@'; - return -count; - } + if (f(s, eos ? eos-s : ps-s, NULL, 0, NULL, param)) { *ps = '@'; return -count; } *ps = '@'; /* restore in memory modified char */ s = ps + 1; ps = strchr(s, '@'); } eos = strchr(s, '['); if (!eos) eos = strchr(s, ' '); ++count; - if (f(s, eos ? eos-s : 0, NULL, 0, NULL, param)) - return -count; + if (f(s, eos ? eos-s : 0, NULL, 0, NULL, param)) return -count; } } else if (header) { struct rpmtd_s list, flags, list_evr; @@ -419,20 +444,18 @@ return_list_str(char *s, const Header header, rpmTag tag_name, rpmTag tag_flags, } static int -xpush_simple_list_str(const Header header, rpmTag tag_name) { +xpush_simple_list_str(Header header, int32_t tag_name) { dSP; if (header) { struct rpmtd_s list; const char *val; int size; - if (!headerGet(header, tag_name, &list, HEADERGET_DEFAULT)) - return 0; + if (!headerGet(header, tag_name, &list, HEADERGET_DEFAULT)) return 0; size = rpmtdCount(&list); - EXTEND(SP, size); while ((val = rpmtdNextString(&list))) { - mPUSHs(newSVpv(val, 0)); + mXPUSHs(newSVpv(val, 0)); } rpmtdFreeData(&list); PUTBACK; @@ -440,18 +463,33 @@ xpush_simple_list_str(const Header header, rpmTag tag_name) { } else return 0; } -static void -return_list_number(const Header header, rpmTag tag_name) { +void +return_list_int32_t(Header header, int32_t tag_name) { + dSP; + if (header) { + struct rpmtd_s list; + + if (headerGet(header, tag_name, &list, HEADERGET_DEFAULT)) { + uint32_t *val; + while ((val = rpmtdNextUint32(&list))) + mXPUSHs(newSViv(*val)); + rpmtdFreeData(&list); + } + } + PUTBACK; +} + +void +return_list_uint_16(Header header, int32_t tag_name) { dSP; if (header) { struct rpmtd_s list; if (headerGet(header, tag_name, &list, HEADERGET_DEFAULT)) { int count = rpmtdCount(&list); int i; - EXTEND(SP, count); + uint16_t *list_ = list.data; for(i = 0; i < count; i++) { - rpmtdNext(&list); - mPUSHs(newSViv(rpmtdGetNumber(&list))); + mXPUSHs(newSViv(list_[i])); } rpmtdFreeData(&list); } @@ -459,37 +497,34 @@ return_list_number(const Header header, rpmTag tag_name) { PUTBACK; } -static void -return_list_tag_modifier(const Header header, rpmTag tag_name) { +void +return_list_tag_modifier(Header header, int32_t tag_name) { dSP; int i; struct rpmtd_s td; - if (!headerGet(header, tag_name, &td, HEADERGET_DEFAULT)) - return; + if (!headerGet(header, tag_name, &td, HEADERGET_DEFAULT)) return; int count = rpmtdCount(&td); - rpmtdInit(&td); + int32_t *list = td.data; for (i = 0; i < count; i++) { char buff[15]; char *s = buff; - int32_t tag; - rpmtdNext(&td); - tag = rpmtdGetNumber(&td); - - if (tag_name == RPMTAG_FILEFLAGS) { - if (tag & RPMFILE_CONFIG) *s++ = 'c'; - if (tag & RPMFILE_DOC) *s++ = 'd'; - if (tag & RPMFILE_GHOST) *s++ = 'g'; - if (tag & RPMFILE_LICENSE) *s++ = 'l'; - if (tag & RPMFILE_MISSINGOK) *s++ = 'm'; - if (tag & RPMFILE_NOREPLACE) *s++ = 'n'; - if (tag & RPMFILE_SPECFILE) *s++ = 'S'; - if (tag & RPMFILE_README) *s++ = 'R'; - if (tag & RPMFILE_EXCLUDE) *s++ = 'e'; - if (tag & RPMFILE_ICON) *s++ = 'i'; - if (tag & RPMFILE_UNPATCHED) *s++ = 'u'; - if (tag & RPMFILE_PUBKEY) *s++ = 'p'; - } else { + switch (tag_name) { + case RPMTAG_FILEFLAGS: + if (list[i] & RPMFILE_CONFIG) *s++ = 'c'; + if (list[i] & RPMFILE_DOC) *s++ = 'd'; + if (list[i] & RPMFILE_GHOST) *s++ = 'g'; + if (list[i] & RPMFILE_LICENSE) *s++ = 'l'; + if (list[i] & RPMFILE_MISSINGOK) *s++ = 'm'; + if (list[i] & RPMFILE_NOREPLACE) *s++ = 'n'; + if (list[i] & RPMFILE_SPECFILE) *s++ = 'S'; + if (list[i] & RPMFILE_README) *s++ = 'R'; + if (list[i] & RPMFILE_EXCLUDE) *s++ = 'e'; + if (list[i] & RPMFILE_ICON) *s++ = 'i'; + if (list[i] & RPMFILE_UNPATCHED) *s++ = 'u'; + if (list[i] & RPMFILE_PUBKEY) *s++ = 'p'; + break; + default: rpmtdFreeData(&td); return; } @@ -500,15 +535,16 @@ return_list_tag_modifier(const Header header, rpmTag tag_name) { PUTBACK; } -static void -return_list_tag(const URPM__Package pkg, rpmTag tag_name) { +void +return_list_tag(URPM__Package pkg, int32_t tag_name) { dSP; if (pkg->h != NULL) { struct rpmtd_s td; if (headerGet(pkg->h, tag_name, &td, HEADERGET_DEFAULT)) { + void *list = td.data; int32_t count = rpmtdCount(&td); if (tag_name == RPMTAG_ARCH) - mXPUSHs(newSVpv(headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? rpmtdGetString(&td) : "src", 0)); + mXPUSHs(newSVpv(headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? (char *) list : "src", 0)); else switch (rpmtdType(&td)) { case RPM_NULL_TYPE: @@ -519,25 +555,27 @@ return_list_tag(const URPM__Package pkg, rpmTag tag_name) { case RPM_INT32_TYPE: { int i; - EXTEND(SP, count); + int *r; + r = (int *)list; for (i=0; i < count; i++) { - rpmtdNext(&td); - mPUSHs(newSViv(rpmtdGetNumber(&td))); + mXPUSHs(newSViv(r[i])); } } break; case RPM_STRING_TYPE: - mPUSHs(newSVpv(rpmtdGetString(&td), 0)); + mXPUSHs(newSVpv((char *) list, 0)); break; case RPM_BIN_TYPE: break; case RPM_STRING_ARRAY_TYPE: { int i; - EXTEND(SP, count); - rpmtdInit(&td); - for (i = 0; i < count; i++) - mPUSHs(newSVpv(rpmtdNextString(&td), 0)); + char **s; + + s = (char **)list; + for (i = 0; i < count; i++) { + mXPUSHs(newSVpv(s[i], 0)); + } } break; case RPM_I18NSTRING_TYPE: @@ -583,21 +621,18 @@ return_list_tag(const URPM__Package pkg, rpmTag tag_name) { case RPMTAG_SUMMARY: mXPUSHs(newSVpv(pkg->summary, 0)); break; - default: - croak("unexpected tag %s", tag_name); - break; } } PUTBACK; } -static void -return_files(const Header header, int filter_mode) { +void +return_files(Header header, int filter_mode) { dSP; if (header) { char buff[4096]; - char *p; const char *s; + char *p, *s; STRLEN len; unsigned int i; @@ -617,19 +652,17 @@ return_files(const Header header, int filter_mode) { char **baseNames = td_baseNames.data; char **dirNames = td_dirNames.data; int32_t *dirIndexes = td_dirIndexes.data; - int is_oldfilenames = !baseNames || !dirNames || !dirIndexes; - if (is_oldfilenames) { - if (!headerGet(header, RPMTAG_OLDFILENAMES, &td_list, HEADERGET_DEFAULT)) - return; - rpmtdInit(&td_list); + char **list = NULL; + if (!baseNames || !dirNames || !dirIndexes) { + if (!headerGet(header, RPMTAG_OLDFILENAMES, &td_list, HEADERGET_DEFAULT)) return; + list = td_list.data; } - rpm_count_t count = is_oldfilenames ? rpmtdCount(&td_list) : rpmtdCount(&td_baseNames); - for(i = 0; i < count; i++) { - if (is_oldfilenames) { - s = rpmtdNextString(&td_list); - len = strlen(s); + for(i = 0; i < rpmtdCount(&td_baseNames); i++) { + if (list) { + s = list[i]; + len = strlen(list[i]); } else { len = strlen(dirNames[dirIndexes[i]]); if (len >= sizeof(buff)) continue; @@ -648,15 +681,14 @@ return_files(const Header header, int filter_mode) { mXPUSHs(newSVpv(s, len)); } - rpmtdFreeData(&td_baseNames); - rpmtdFreeData(&td_dirNames); - if (is_oldfilenames) - rpmtdFreeData(&td_list); + free(baseNames); + free(dirNames); + free(list); } PUTBACK; } -static void +void return_problems(rpmps ps, int translate_message, int raw_message) { dSP; if (ps && rpmpsNumProblems(ps) > 0) { @@ -720,9 +752,9 @@ return_problems(rpmps ps, int translate_message, int raw_message) { } static char * -pack_list(const Header header, rpmTag tag_name, rpmTag tag_flags, rpmTag tag_version) { +pack_list(Header header, int32_t tag_name, int32_t tag_flags, int32_t tag_version, int32_t (*check_flag)(int32_t)) { char buff[65536]; - rpmTag *flags = NULL; + int32_t *flags = NULL; char **list_evr = NULL; unsigned int i; char *p = buff; @@ -735,6 +767,7 @@ pack_list(const Header header, rpmTag tag_name, rpmTag tag_flags, rpmTag tag_ver if (tag_flags && headerGet(header, tag_flags, &td_flags, HEADERGET_DEFAULT)) flags = td_flags.data; if (tag_version && headerGet(header, tag_version, &td_list_evr, HEADERGET_DEFAULT)) list_evr = td_list_evr.data; for(i = 0; i < rpmtdCount(&td); i++) { + if (check_flag && !check_flag(flags[i])) continue; int len = print_list_entry(p, sizeof(buff)-(p-buff)-1, list[i], flags ? flags[i] : 0, list_evr ? list_evr[i] : NULL); if (len < 0) continue; p += len; @@ -750,30 +783,35 @@ pack_list(const Header header, rpmTag tag_name, rpmTag tag_flags, rpmTag tag_ver } static void -pack_header(const URPM__Package pkg) { +pack_header(URPM__Package pkg) { if (pkg->h) { if (pkg->info == NULL) { char buff[1024]; - const char *p = buff; - const char *nvr = headerGetAsString(pkg->h, RPMTAG_NVR); - const char *arch = get_arch(pkg->h); + 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@%d@%d@%s", nvr, arch, + p += 1 + snprintf(buff, sizeof(buff), "%s-%s-%s.%s@%d@%d@%s", name, version, release, 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); } if (pkg->filesize == 0) pkg->filesize = get_filesize(pkg->h); - if (pkg->requires == NULL && pkg->suggests == NULL) { - pkg->requires = pack_list(pkg->h, RPMTAG_REQUIRENAME, RPMTAG_REQUIREFLAGS, RPMTAG_REQUIREVERSION); - pkg->suggests = pack_list(pkg->h, RPMTAG_SUGGESTSNAME, 0, 0); - } + if (pkg->requires == NULL && pkg->suggests == NULL) + has_old_suggests = 0; + pkg->requires = pack_list(pkg->h, RPMTAG_REQUIRENAME, RPMTAG_REQUIREFLAGS, RPMTAG_REQUIREVERSION, is_not_old_suggests); + if (has_old_suggests) + pkg->suggests = pack_list(pkg->h, RPMTAG_REQUIRENAME, RPMTAG_REQUIREFLAGS, RPMTAG_REQUIREVERSION, is_old_suggests); + else + pkg->suggests = pack_list(pkg->h, RPMTAG_SUGGESTSNAME, 0, 0, NULL); if (pkg->obsoletes == NULL) - pkg->obsoletes = pack_list(pkg->h, RPMTAG_OBSOLETENAME, RPMTAG_OBSOLETEFLAGS, RPMTAG_OBSOLETEVERSION); + pkg->obsoletes = pack_list(pkg->h, RPMTAG_OBSOLETENAME, RPMTAG_OBSOLETEFLAGS, RPMTAG_OBSOLETEVERSION, NULL); if (pkg->conflicts == NULL) - pkg->conflicts = pack_list(pkg->h, RPMTAG_CONFLICTNAME, RPMTAG_CONFLICTFLAGS, RPMTAG_CONFLICTVERSION); + pkg->conflicts = pack_list(pkg->h, RPMTAG_CONFLICTNAME, RPMTAG_CONFLICTFLAGS, RPMTAG_CONFLICTVERSION, NULL); if (pkg->provides == NULL) - pkg->provides = pack_list(pkg->h, RPMTAG_PROVIDENAME, RPMTAG_PROVIDEFLAGS, RPMTAG_PROVIDEVERSION); + pkg->provides = pack_list(pkg->h, RPMTAG_PROVIDENAME, RPMTAG_PROVIDEFLAGS, RPMTAG_PROVIDEVERSION, NULL); if (pkg->summary == NULL) { char *summary = get_name(pkg->h, RPMTAG_SUMMARY); int len = 1 + strlen(summary); @@ -781,13 +819,13 @@ pack_header(const URPM__Package pkg) { pkg->summary = memcpy(malloc(len), summary, len); } - _header_free(pkg); + if (!(pkg->flag & FLAG_NO_HEADER_FREE)) pkg->h =headerFree(pkg->h); pkg->h = NULL; } } static void -update_hash_entry(HV *hash, const char *name, STRLEN len, int force, IV use_sense, const URPM__Package pkg) { +update_hash_entry(HV *hash, char *name, STRLEN len, int force, IV use_sense, URPM__Package pkg) { SV** isv; if (!len) len = strlen(name); @@ -813,24 +851,24 @@ update_hash_entry(HV *hash, const char *name, STRLEN len, int force, IV use_sens } static void -update_provide_entry(const char *name, STRLEN len, int force, IV use_sense, const URPM__Package pkg, HV *provides) { +update_provide_entry(char *name, STRLEN len, int force, IV use_sense, URPM__Package pkg, HV *provides) { update_hash_entry(provides, name, len, force, use_sense, pkg); } static void -update_provides(const URPM__Package pkg, HV *provides) { +update_provides(URPM__Package pkg, HV *provides) { if (pkg->h) { int len; struct rpmtd_s td, td_flags; - rpmsenseFlags *flags = NULL; + int32_t *flags = NULL; unsigned int i; /* examine requires for files which need to be marked in provides */ if (headerGet(pkg->h, RPMTAG_REQUIRENAME, &td, HEADERGET_DEFAULT)) { + char **list = td.data; for (i = 0; i < rpmtdCount(&td); ++i) { - const char *s = rpmtdNextString(&td); - len = strlen(s); - if (s[0] == '/') (void)hv_fetch(provides, s, len, 1); + len = strlen(list[i]); + if (list[i][0] == '/') (void)hv_fetch(provides, list[i], len, 1); } } @@ -880,15 +918,16 @@ update_provides(const URPM__Package pkg, HV *provides) { } static void -update_obsoletes(const URPM__Package pkg, HV *obsoletes) { +update_obsoletes(URPM__Package pkg, HV *obsoletes) { if (pkg->h) { struct rpmtd_s td; /* update all provides */ if (headerGet(pkg->h, RPMTAG_OBSOLETENAME, &td, HEADERGET_DEFAULT)) { + char **list = td.data; unsigned int i; for (i = 0; i < rpmtdCount(&td); ++i) - update_hash_entry(obsoletes, rpmtdNextString(&td), 0, 1, 0, pkg); + update_hash_entry(obsoletes, list[i], 0, 1, 0, pkg); } } else { char *ps, *s; @@ -909,9 +948,10 @@ update_obsoletes(const URPM__Package pkg, HV *obsoletes) { } static void -update_provides_files(const URPM__Package pkg, HV *provides) { +update_provides_files(URPM__Package pkg, HV *provides) { if (pkg->h) { STRLEN len; + char **list = NULL; unsigned int i; struct rpmtd_s td_baseNames, td_dirIndexes, td_dirNames; @@ -937,26 +977,25 @@ update_provides_files(const URPM__Package pkg, HV *provides) { update_provide_entry(buff, p-buff, 0, 0, pkg, provides); } - rpmtdFreeData(&td_baseNames); - rpmtdFreeData(&td_dirNames); + free(baseNames); + free(dirNames); } else { struct rpmtd_s td; - - if (headerGet(pkg->h, RPMTAG_OLDFILENAMES, &td, HEADERGET_DEFAULT)) { + headerGet(pkg->h, RPMTAG_OLDFILENAMES, &td, HEADERGET_DEFAULT); + if (list) { for (i = 0; i < rpmtdCount(&td); i++) { - const char *s = rpmtdNextString(&td); - len = strlen(s); + len = strlen(list[i]); - update_provide_entry(s, len, 0, 0, pkg, provides); + update_provide_entry(list[i], len, 0, 0, pkg, provides); } - rpmtdFreeData(&td); + free(list); } } } } -static FD_t +FD_t open_archive(char *filename, int *empty_archive) { int fd; FD_t rfd = NULL; @@ -1038,7 +1077,7 @@ parse_line(AV *depslist, HV *provides, HV *obsoletes, URPM__Package pkg, char *b pkg->info = memcpy(malloc(data_len), data, data_len); pkg->flag &= ~FLAG_ID; pkg->flag |= 1 + av_len(depslist); - sv_pkg = sv_setref_pv(newSVpvs(""), "URPM::Package", + sv_pkg = sv_setref_pv(newSVpv("", 0), "URPM::Package", _pkg = memcpy(malloc(sizeof(struct s_Package)), pkg, sizeof(struct s_Package))); if (call_package_callback(urpm, sv_pkg, callback)) { if (provides) update_provides(_pkg, provides); @@ -1153,7 +1192,7 @@ update_header(char *filename, URPM__Package pkg, __attribute__((unused)) int kee if (fd != NULL && rpmReadPackageFile(ts, fd, filename, &header) == 0 && header) { Fclose(fd); - _header_free(pkg); + if (pkg->h && !(pkg->flag & FLAG_NO_HEADER_FREE)) pkg->h = headerFree(pkg->h); pkg->h = header; pkg->flag &= ~FLAG_NO_HEADER_FREE; @@ -1168,7 +1207,7 @@ update_header(char *filename, URPM__Package pkg, __attribute__((unused)) int kee close(d); if (fd != NULL) { - _header_free(pkg); + 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); @@ -1192,9 +1231,9 @@ read_config_files(int force) { return rc; } -static rpmVSFlags +static void ts_nosignature(rpmts ts) { - return rpmtsSetVSFlags(ts, _RPMVSF_NODIGESTS | _RPMVSF_NOSIGNATURES); + rpmtsSetVSFlags(ts, _RPMVSF_NODIGESTS | _RPMVSF_NOSIGNATURES); } static void *rpmRunTransactions_callback(__attribute__((unused)) const void *h, @@ -1295,11 +1334,20 @@ static void *rpmRunTransactions_callback(__attribute__((unused)) const void *h, i = POPi; fd = fdDup(i); if (fd) { +#ifdef RPM490 fd = fdLink(fd); - Fcntl(fd, F_SETFD, (void *)1); /* necessary to avoid forked/execed process to lock removable media */ +#else + fd = fdLink(fd, "persist perl-URPM"); +#endif + Fcntl(fd, F_SETFD, (void *)1); /* necessary to avoid forked/execed process to lock removable */ } PUTBACK; } else if (callback == td->callback_close) { +#ifdef RPM490 + fd = fdFree(fd); +#else + fd = fdFree(fd, "persist perl-URPM"); +#endif if (fd) { Fclose(fd); fd = NULL; @@ -1312,8 +1360,7 @@ static void *rpmRunTransactions_callback(__attribute__((unused)) const void *h, return callback == td->callback_open ? fd : NULL; } -static rpmTag -rpmtag_from_string(char *tag) +int rpmtag_from_string(char *tag) { if (!strcmp(tag, "name")) return RPMTAG_NAME; @@ -1334,44 +1381,6 @@ rpmtag_from_string(char *tag) else croak("unknown tag [%s]", tag); } -static int compare_evrs(int lepoch, char*lversion, char*lrelease, int repoch, char*rversion, char*rrelease) { - int compare; - compare = lepoch - repoch; - if (!compare) { - compare = rpmvercmp(lversion, rversion); - if (!compare && rrelease) - compare = rpmvercmp(lrelease, rrelease); - } - return compare; -} - -static int get_e_v_r(URPM__Package pkg, int *epoch, char **version, char **release, char **arch) { - if (pkg->info) { - char *s, *eos; - - if ((s = strchr(pkg->info, '@')) != NULL) { - if ((eos = strchr(s+1, '@')) != NULL) - *eos = 0; /* mark end of string to enable searching backwards */ - *epoch = atoi(s+1); - if (eos != NULL) *eos = '@'; - } else - *epoch = 0; - get_fullname_parts(pkg, NULL, version, release, arch, &eos); - /* temporarily mark end of each substring */ - (*release)[-1] = 0; - (*arch)[-1] = 0; - return 1; - } else if (pkg->h) { - *epoch = get_int(pkg->h, RPMTAG_EPOCH); - *version = get_name(pkg->h, RPMTAG_VERSION); - *release = get_name(pkg->h, RPMTAG_RELEASE); - *arch = get_arch(pkg->h); - return 1; - } - return 0; -} - - MODULE = URPM PACKAGE = URPM::Package PREFIX = Pkg_ void @@ -1386,7 +1395,7 @@ Pkg_DESTROY(pkg) free(pkg->provides); free(pkg->rflags); free(pkg->summary); - _header_free(pkg); + if (pkg->h && !(pkg->flag & FLAG_NO_HEADER_FREE)) pkg->h = headerFree(pkg->h); free(pkg); void @@ -1445,7 +1454,7 @@ Pkg_arch(pkg) get_fullname_parts(pkg, NULL, NULL, NULL, &arch, &eos); mXPUSHs(newSVpv(arch, eos-arch)); } else if (pkg->h) { - mXPUSHs(newSVpv(get_arch(pkg->h), 0)); + mXPUSHs(newSVpv(headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? get_name(pkg->h, RPMTAG_ARCH) : "src", 0)); } int @@ -1471,6 +1480,19 @@ Pkg_is_arch_compat__XS(pkg) OUTPUT: RETVAL +int +Pkg_is_platform_compat(pkg) + URPM::Package pkg + INIT: + CODE: + croak("is_platform_compat() is available only since rpm 4.4.8"); + { /* to match last } and avoid another #ifdef for it */ + RETVAL = 0; + } + + OUTPUT: + RETVAL + void Pkg_summary(pkg) URPM::Package pkg @@ -1484,57 +1506,94 @@ Pkg_summary(pkg) void Pkg_description(pkg) URPM::Package pkg - ALIAS: - sourcerpm = 1 - packager = 2 - buildhost = 3 - url = 4 - license = 5 - distribution = 6 - vendor = 7 - os = 8 - payload_format = 9 - disttag = 10 PPCODE: if (pkg->h) - switch (ix) { - case 0: - mXPUSHs(newSVpv_utf8(get_name(pkg->h, RPMTAG_DESCRIPTION), 0)); break; - case 1: - mXPUSHs(newSVpv(get_name(pkg->h, RPMTAG_SOURCERPM), 0)); break; - case 2: - mXPUSHs(newSVpv_utf8(get_name(pkg->h, RPMTAG_PACKAGER), 0)); break; - case 3: - mXPUSHs(newSVpv(get_name(pkg->h, RPMTAG_BUILDHOST), 0)); break; - case 4: - mXPUSHs(newSVpv(get_name(pkg->h, RPMTAG_URL), 0)); break; - case 5: - mXPUSHs(newSVpv(get_name(pkg->h, RPMTAG_LICENSE), 0)); break; - case 6: - mXPUSHs(newSVpv(get_name(pkg->h, RPMTAG_DISTRIBUTION), 0)); break; - case 7: - mXPUSHs(newSVpv(get_name(pkg->h, RPMTAG_VENDOR), 0)); break; - case 8: - mXPUSHs(newSVpv(get_name(pkg->h, RPMTAG_OS), 0)); break; - case 9: - mXPUSHs(newSVpv(get_name(pkg->h, RPMTAG_PAYLOADFORMAT), 0)); break; - case 10: - mXPUSHs(newSVpv(get_name(pkg->h, RPMTAG_DISTTAG), 0)); break; - } + mXPUSHs(newSVpv_utf8(get_name(pkg->h, RPMTAG_DESCRIPTION), 0)); + +void +Pkg_sourcerpm(pkg) + URPM::Package pkg + PPCODE: + if (pkg->h) + mXPUSHs(newSVpv(get_name(pkg->h, RPMTAG_SOURCERPM), 0)); + +void +Pkg_packager(pkg) + URPM::Package pkg + PPCODE: + if (pkg->h) + mXPUSHs(newSVpv_utf8(get_name(pkg->h, RPMTAG_PACKAGER), 0)); + +void +Pkg_buildhost(pkg) + URPM::Package pkg + PPCODE: + if (pkg->h) + mXPUSHs(newSVpv(get_name(pkg->h, RPMTAG_BUILDHOST), 0)); int Pkg_buildtime(pkg) URPM::Package pkg - ALIAS: - installtid = 1 CODE: if (pkg->h) - RETVAL = get_int(pkg->h, ix == 1 ? RPMTAG_INSTALLTID : RPMTAG_BUILDTIME); + RETVAL = get_int(pkg->h, RPMTAG_BUILDTIME); + else + RETVAL = 0; + OUTPUT: + RETVAL + +int +Pkg_installtid(pkg) + URPM::Package pkg + CODE: + if (pkg->h) + RETVAL = get_int(pkg->h, RPMTAG_INSTALLTID); else RETVAL = 0; OUTPUT: RETVAL +void +Pkg_url(pkg) + URPM::Package pkg + PPCODE: + if (pkg->h) + mXPUSHs(newSVpv(get_name(pkg->h, RPMTAG_URL), 0)); + +void +Pkg_license(pkg) + URPM::Package pkg + PPCODE: + if (pkg->h) + mXPUSHs(newSVpv(get_name(pkg->h, RPMTAG_LICENSE), 0)); + +void +Pkg_distribution(pkg) + URPM::Package pkg + PPCODE: + if (pkg->h) + mXPUSHs(newSVpv(get_name(pkg->h, RPMTAG_DISTRIBUTION), 0)); + +void +Pkg_vendor(pkg) + URPM::Package pkg + PPCODE: + if (pkg->h) + mXPUSHs(newSVpv(get_name(pkg->h, RPMTAG_VENDOR), 0)); + +void +Pkg_os(pkg) + URPM::Package pkg + PPCODE: + if (pkg->h) + mXPUSHs(newSVpv(get_name(pkg->h, RPMTAG_OS), 0)); + +void +Pkg_payload_format(pkg) + URPM::Package pkg + PPCODE: + if (pkg->h) + mXPUSHs(newSVpv(get_name(pkg->h, RPMTAG_PAYLOADFORMAT), 0)); void Pkg_fullname(pkg) @@ -1554,24 +1613,25 @@ Pkg_fullname(pkg) if (version - name < 1 || release - version < 1 || arch - release < 1) croak("invalid fullname"); EXTEND(SP, 4); - mPUSHs(newSVpv(name, version-name-1)); - mPUSHs(newSVpv(version, release-version-1)); - mPUSHs(newSVpv(release, arch-release-1)); - mPUSHs(newSVpv(arch, eos-arch)); + 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))); } } else if (pkg->h) { - char *arch = get_arch(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"; if (gimme == G_SCALAR) { - char *s = headerGetAsString(pkg->h, RPMTAG_NVR); - mXPUSHs(newSVpvf("%s.%s", s, arch)); - free(s); + mXPUSHs(newSVpvf("%s-%s-%s.%s", name, version, release, arch)); } else if (gimme == G_ARRAY) { EXTEND(SP, 4); - mPUSHs(newSVpv(get_name(pkg->h, RPMTAG_NAME), 0)); - mPUSHs(newSVpv(get_name(pkg->h, RPMTAG_VERSION), 0)); - mPUSHs(newSVpv(get_name(pkg->h, RPMTAG_RELEASE), 0)); - mPUSHs(newSVpv(arch, 0)); + PUSHs(sv_2mortal(newSVpv(name, 0))); + PUSHs(sv_2mortal(newSVpv(version, 0))); + PUSHs(sv_2mortal(newSVpv(release, 0))); + PUSHs(sv_2mortal(newSVpv(arch, 0))); } } @@ -1583,8 +1643,7 @@ Pkg_epoch(pkg) char *s, *eos; if ((s = strchr(pkg->info, '@')) != NULL) { - if ((eos = strchr(s+1, '@')) != NULL) - *eos = 0; /* mark end of string to enable searching backwards */ + if ((eos = strchr(s+1, '@')) != NULL) *eos = 0; /* mark end of string to enable searching backwards */ RETVAL = atoi(s+1); if (eos != NULL) *eos = '@'; } else @@ -1601,16 +1660,57 @@ Pkg_compare_pkg(lpkg, rpkg) URPM::Package rpkg PREINIT: int compare = 0; - int lepoch, repoch; - char *lversion, *lrelease, *larch; - char *rversion, *rrelease, *rarch; + int lepoch; + char *lversion; + char *lrelease; + char *larch; + char *leos; + int repoch; + char *rversion; + char *rrelease; + char *rarch; + char *reos; CODE: if (lpkg == rpkg) RETVAL = 0; else { - if (!get_e_v_r(lpkg, &lepoch, &lversion, &lrelease, &larch)) - croak("undefined package"); + if (lpkg->info) { + char *s; + + if ((s = strchr(lpkg->info, '@')) != NULL) { + if ((leos = strchr(s+1, '@')) != NULL) *leos = 0; /* mark end of string to enable searching backwards */ + lepoch = atoi(s+1); + if (leos != NULL) *leos = '@'; + } else + lepoch = 0; + get_fullname_parts(lpkg, NULL, &lversion, &lrelease, &larch, &leos); + /* temporarily mark end of each substring */ + lrelease[-1] = 0; + larch[-1] = 0; + } else if (lpkg->h) { + lepoch = get_int(lpkg->h, RPMTAG_EPOCH); + lversion = get_name(lpkg->h, RPMTAG_VERSION); + lrelease = get_name(lpkg->h, RPMTAG_RELEASE); + larch = headerIsEntry(lpkg->h, RPMTAG_SOURCERPM) ? get_name(lpkg->h, RPMTAG_ARCH) : "src"; + } else croak("undefined package"); + if (rpkg->info) { + char *s; - if (!get_e_v_r(rpkg, &repoch, &rversion, &rrelease, &rarch)) { + if ((s = strchr(rpkg->info, '@')) != NULL) { + if ((reos = strchr(s+1, '@')) != NULL) *reos = 0; /* mark end of string to enable searching backwards */ + repoch = atoi(s+1); + if (reos != NULL) *reos = '@'; + } else + repoch = 0; + get_fullname_parts(rpkg, NULL, &rversion, &rrelease, &rarch, &reos); + /* temporarily mark end of each substring */ + rrelease[-1] = 0; + rarch[-1] = 0; + } else if (rpkg->h) { + repoch = get_int(rpkg->h, RPMTAG_EPOCH); + rversion = get_name(rpkg->h, RPMTAG_VERSION); + rrelease = get_name(rpkg->h, RPMTAG_RELEASE); + rarch = headerIsEntry(rpkg->h, RPMTAG_SOURCERPM) ? get_name(rpkg->h, RPMTAG_ARCH) : "src"; + } else { /* restore info string modified */ if (lpkg->info) { lrelease[-1] = '-'; @@ -1618,9 +1718,12 @@ Pkg_compare_pkg(lpkg, rpkg) } croak("undefined package"); } - compare = compare_evrs(lepoch, lversion, lrelease, repoch, rversion, rrelease); - // equal? compare arches too + compare = lepoch - repoch; if (!compare) { + compare = rpmvercmp(lversion, rversion); + if (!compare) { + compare = rpmvercmp(lrelease, rrelease); + if (!compare) { int lscore, rscore; char *eolarch = strchr(larch, '@'); char *eorarch = strchr(rarch, '@'); @@ -1630,8 +1733,11 @@ Pkg_compare_pkg(lpkg, rpkg) if (eorarch) *eorarch = 0; rscore = rpmMachineScore(RPM_MACHTABLE_INSTARCH, rarch); if (lscore == 0) { if (rscore == 0) +#if 0 /* Nanar: TODO check this * hu ?? what is the goal of strcmp, some of arch are equivalent */ + compare = 0 +#endif compare = strcmp(larch, rarch); else compare = -1; @@ -1643,6 +1749,8 @@ Pkg_compare_pkg(lpkg, rpkg) } if (eolarch) *eolarch = '@'; if (eorarch) *eorarch = '@'; + } + } } /* restore info string modified */ if (lpkg->info) { @@ -1663,38 +1771,70 @@ Pkg_compare(pkg, evr) URPM::Package pkg char *evr PREINIT: - int _epoch, repoch = 0; - char *_version, *_release, *_eos; + int compare = 0; + int _epoch; + char *_version; + char *_release; + char *_eos; CODE: - if (!get_e_v_r(pkg, &_epoch, &_version, &_release, &_eos)) - croak("undefined package"); + if (pkg->info) { + char *s; - char *epoch = NULL, *version, *release; + if ((s = strchr(pkg->info, '@')) != NULL) { + if ((_eos = strchr(s+1, '@')) != NULL) *_eos = 0; /* mark end of string to enable searching backwards */ + _epoch = atoi(s+1); + if (_eos != NULL) *_eos = '@'; + } else + _epoch = 0; + get_fullname_parts(pkg, NULL, &_version, &_release, &_eos, NULL); + /* temporarily mark end of each substring */ + _release[-1] = 0; + _eos[-1] = 0; + } else if (pkg->h) + _epoch = get_int(pkg->h, RPMTAG_EPOCH); + else croak("undefined package"); + if (!compare) { + char *epoch, *version, *release; - /* extract epoch and version from evr */ - version = evr; - while (*version && isdigit(*version)) version++; - if (*version == ':') { - epoch = evr; - *version++ = 0; - if (!*epoch) epoch = "0"; - version[-1] = ':'; /* restore in memory modification */ - } else { - /* there is no epoch defined, so assume epoch = 0 */ + /* extract epoch and version from evr */ version = evr; + while (*version && isdigit(*version)) version++; + if (*version == ':') { + epoch = evr; + *version++ = 0; + if (!*epoch) epoch = "0"; + compare = _epoch - (*epoch ? atoi(epoch) : 0); + version[-1] = ':'; /* restore in memory modification */ + } else { + /* there is no epoch defined, so assume epoch = 0 */ + version = evr; + compare = _epoch; + } + if (!compare) { + if (!pkg->info) + _version = get_name(pkg->h, RPMTAG_VERSION); + /* continue extracting release if any */ + if ((release = strrchr(version, '-')) != NULL) { + *release++ = 0; + compare = rpmvercmp(_version, version); + if (!compare) { + /* need to compare with release here */ + if (!pkg->info) + _release = get_name(pkg->h, RPMTAG_RELEASE); + compare = rpmvercmp(_release, release); + } + release[-1] = '-'; /* restore in memory modification */ + } else { + compare = rpmvercmp(_version, version); + } + } } - if ((release = strrchr(version, '-')) != NULL) - *release++ = 0; - repoch = epoch && *epoch ? atoi(epoch) : 0; - - RETVAL = compare_evrs(_epoch, _version, _release, repoch, version, release); /* restore info string modified */ if (pkg->info) { _release[-1] = '-'; _eos[-1] = '.'; } - if (release) - release[-1] = '-'; /* restore in memory modification */ + RETVAL = compare; OUTPUT: RETVAL @@ -1706,8 +1846,7 @@ Pkg_size(pkg) char *s, *eos; if ((s = strchr(pkg->info, '@')) != NULL && (s = strchr(s+1, '@')) != NULL) { - if ((eos = strchr(s+1, '@')) != NULL) - *eos = 0; /* mark end of string to enable searching backwards */ + if ((eos = strchr(s+1, '@')) != NULL) *eos = 0; /* mark end of string to enable searching backwards */ RETVAL = atoi(s+1); if (eos != NULL) *eos = '@'; } else @@ -1767,10 +1906,12 @@ Pkg_filename(pkg) memcpy(eon, savbuf, 4); } } else if (pkg->h) { - char *nvr = headerGetAsString(pkg->h, RPMTAG_NVR); - char *arch = get_arch(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"; - mXPUSHs(newSVpvf("%s.%s.rpm", nvr, arch)); + mXPUSHs(newSVpvf("%s-%s-%s.%s.rpm", name, version, release, arch)); } # deprecated @@ -1787,10 +1928,12 @@ Pkg_header_filename(pkg) } else if (pkg->h) { char buff[1024]; char *p = buff; - char *nvr = headerGetAsString(pkg->h, RPMTAG_NVR); - char *arch = get_arch(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"; - p += snprintf(buff, sizeof(buff), "%s.%s", nvr, arch); + p += snprintf(buff, sizeof(buff), "%s-%s-%s.%s", name, version, release, arch); mXPUSHs(newSVpv(buff, p-buff)); } @@ -1798,8 +1941,9 @@ void Pkg_id(pkg) URPM::Package pkg PPCODE: - if ((pkg->flag & FLAG_ID) <= FLAG_ID_MAX) + if ((pkg->flag & FLAG_ID) <= FLAG_ID_MAX) { mXPUSHs(newSViv(pkg->flag & FLAG_ID)); + } void Pkg_set_id(pkg, id=-1) @@ -1834,7 +1978,10 @@ Pkg_suggests(pkg) URPM::Package pkg PPCODE: PUTBACK; - return_list_str(pkg->suggests, pkg->h, RPMTAG_SUGGESTSNAME, 0, 0, callback_list_str_xpush, NULL); + int count = return_list_str(pkg->suggests, pkg->h, RPMTAG_SUGGESTSNAME, 0, 0, callback_list_str_xpush, NULL); + if (count == 0) + return_list_str(pkg->suggests, pkg->h, RPMTAG_REQUIRENAME, RPMTAG_REQUIREFLAGS, 0, + callback_list_str_xpush_old_suggests, NULL); SPAGAIN; void @@ -1849,46 +1996,22 @@ Pkg_obsoletes(pkg) void Pkg_obsoletes_nosense(pkg) URPM::Package pkg - ALIAS: - conflicts_nosense = 1 - provides_nosense = 2 PPCODE: PUTBACK; - rpmTag tag; - char *s; - switch (ix) { - case 1: tag = RPMTAG_CONFLICTNAME; s = pkg->conflicts; break; - case 2: tag = RPMTAG_PROVIDENAME; s = pkg->provides; break; - default: tag = RPMTAG_OBSOLETENAME; s = pkg->obsoletes; break; - } - return_list_str(s, pkg->h, tag, 0, 0, callback_list_str_xpush, NULL); + return_list_str(pkg->obsoletes, pkg->h, RPMTAG_OBSOLETENAME, 0, 0, callback_list_str_xpush, NULL); SPAGAIN; int -Pkg_obsoletes_overlap(pkg, s) +Pkg_obsoletes_overlap(pkg, s, b_nopromote=1, direction=-1) URPM::Package pkg char *s - ALIAS: - provides_overlap = 1 + int b_nopromote + int direction PREINIT: struct cb_overlap_s os; char *eon = NULL; char eonc = '\0'; - rpmTag tag_name; - rpmTag tag_flags, tag_version; - CODE: - switch (ix) { - case 1: - tag_name = RPMTAG_PROVIDENAME; - tag_flags = RPMTAG_PROVIDEFLAGS; - tag_version = RPMTAG_PROVIDEVERSION; - break; - default: - tag_name = RPMTAG_OBSOLETENAME; - tag_flags = RPMTAG_OBSOLETEFLAGS; - tag_version = RPMTAG_OBSOLETEVERSION; - break; - } + CODE: os.name = s; os.flags = 0; while (*s && *s != ' ' && *s != '[' && *s != '<' && *s != '>' && *s != '=') ++s; @@ -1905,14 +2028,12 @@ Pkg_obsoletes_overlap(pkg, s) os.evr = s; } else os.evr = ""; - os.direction = ix == 0 ? -1 : 1; + os.direction = direction; + os.b_nopromote = b_nopromote; /* mark end of name */ - if (eon) { - eonc = *eon; - *eon = 0; - } + if (eon) { eonc = *eon; *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, + RETVAL = return_list_str(pkg->obsoletes, pkg->h, RPMTAG_OBSOLETENAME, RPMTAG_OBSOLETEFLAGS, RPMTAG_OBSOLETEVERSION, callback_list_str_overlap, &os) < 0; /* restore end of name */ if (eon) *eon = eonc; @@ -1929,6 +2050,14 @@ Pkg_conflicts(pkg) SPAGAIN; void +Pkg_conflicts_nosense(pkg) + URPM::Package pkg + PPCODE: + PUTBACK; + return_list_str(pkg->conflicts, pkg->h, RPMTAG_CONFLICTNAME, 0, 0, callback_list_str_xpush, NULL); + SPAGAIN; + +void Pkg_provides(pkg) URPM::Package pkg PPCODE: @@ -1938,69 +2067,220 @@ Pkg_provides(pkg) SPAGAIN; void +Pkg_provides_nosense(pkg) + URPM::Package pkg + PPCODE: + PUTBACK; + return_list_str(pkg->provides, pkg->h, RPMTAG_PROVIDENAME, 0, 0, callback_list_str_xpush, NULL); + SPAGAIN; + +int +Pkg_provides_overlap(pkg, s, b_nopromote=1, direction=1) + URPM::Package pkg + char *s + int b_nopromote + int direction + PREINIT: + struct cb_overlap_s os; + char *eon = NULL; + char eonc = '\0'; + CODE: + os.name = s; + os.flags = 0; + while (*s && *s != ' ' && *s != '[' && *s != '<' && *s != '>' && *s != '=') ++s; + if (*s) { + eon = s; + while (*s) { + if (*s == ' ' || *s == '[' || *s == '*' || *s == ']'); + else if (*s == '<') os.flags |= RPMSENSE_LESS; + else if (*s == '>') os.flags |= RPMSENSE_GREATER; + else if (*s == '=') os.flags |= RPMSENSE_EQUAL; + else break; + ++s; + } + os.evr = s; + } else + os.evr = ""; + os.direction = direction; + os.b_nopromote = b_nopromote; + /* mark end of name */ + if (eon) { eonc = *eon; *eon = 0; } + /* return_list_str returns a negative value is the callback has returned non-zero */ + RETVAL = return_list_str(pkg->provides, pkg->h, RPMTAG_PROVIDENAME, RPMTAG_PROVIDEFLAGS, RPMTAG_PROVIDEVERSION, + callback_list_str_overlap, &os) < 0; + /* restore end of name */ + if (eon) *eon = eonc; + OUTPUT: + RETVAL + +void Pkg_buildarchs(pkg) URPM::Package pkg - ALIAS: - excludearchs = 1 - exclusivearchs = 2 - dirnames = 3 - filelinktos = 4 - files_md5sum = 5 - files_owner = 6 - files_group = 7 - changelog_name = 8 - changelog_text = 9 PPCODE: PUTBACK; - rpmTag tag; - switch (ix) { - case 1: tag = RPMTAG_EXCLUDEARCH; break; - case 2: tag = RPMTAG_EXCLUSIVEARCH; break; - case 3: tag = RPMTAG_DIRNAMES; break; - case 4: tag = RPMTAG_FILELINKTOS; break; - case 5: tag = RPMTAG_FILEMD5S; break; - case 6: tag = RPMTAG_FILEUSERNAME; break; - case 7: tag = RPMTAG_FILEGROUPNAME; break; - case 8: tag = RPMTAG_CHANGELOGNAME; break; - case 9: tag = RPMTAG_CHANGELOGTEXT; break; - default: tag = RPMTAG_BUILDARCHS; break; - } - xpush_simple_list_str(pkg->h, tag); + xpush_simple_list_str(pkg->h, RPMTAG_BUILDARCHS); + SPAGAIN; + +void +Pkg_excludearchs(pkg) + URPM::Package pkg + PPCODE: + PUTBACK; + xpush_simple_list_str(pkg->h, RPMTAG_EXCLUDEARCH); + SPAGAIN; + +void +Pkg_exclusivearchs(pkg) + URPM::Package pkg + PPCODE: + PUTBACK; + xpush_simple_list_str(pkg->h, RPMTAG_EXCLUSIVEARCH); + SPAGAIN; + +void +Pkg_dirnames(pkg) + URPM::Package pkg + PPCODE: + PUTBACK; + xpush_simple_list_str(pkg->h, RPMTAG_DIRNAMES); + SPAGAIN; + +void Pkg_distepoch(pkg) + URPM::Package pkg + PPCODE: +#ifdef RPMTAG_DISTEPOCH + if (pkg->h) { + mXPUSHs(newSVpv(get_name(pkg->h, RPMTAG_DISTEPOCH), 0)); + } +#else + croak("distepoch isn't available with this rpm version"); +#endif + +void Pkg_disttag(pkg) + URPM::Package pkg + PPCODE: + if (pkg->h) { + mXPUSHs(newSVpv(get_name(pkg->h, RPMTAG_DISTTAG), 0)); + } + +void +Pkg_filelinktos(pkg) + URPM::Package pkg + PPCODE: + PUTBACK; + xpush_simple_list_str(pkg->h, RPMTAG_FILELINKTOS); SPAGAIN; void Pkg_files(pkg) URPM::Package pkg - ALIAS: - conf_files = 1 PPCODE: PUTBACK; - return_files(pkg->h, ix == 0 ? 0 : FILTER_MODE_CONF_FILES); + return_files(pkg->h, 0); + SPAGAIN; + +void +Pkg_files_md5sum(pkg) + URPM::Package pkg + PPCODE: + PUTBACK; + xpush_simple_list_str(pkg->h, RPMTAG_FILEMD5S); + SPAGAIN; + +void +Pkg_files_owner(pkg) + URPM::Package pkg + PPCODE: + PUTBACK; + xpush_simple_list_str(pkg->h, RPMTAG_FILEUSERNAME); + SPAGAIN; + +void +Pkg_files_group(pkg) + URPM::Package pkg + PPCODE: + PUTBACK; + xpush_simple_list_str(pkg->h, RPMTAG_FILEGROUPNAME); SPAGAIN; void Pkg_files_mtime(pkg) URPM::Package pkg - ALIAS: - files_size = 1 - files_uid = 2 - files_gid = 3 - files_mode = 4 - files_flags = 5 - changelog_time = 6 PPCODE: PUTBACK; - rpmTag tag; - switch (ix) { - case 1: tag = RPMTAG_FILESIZES; break; - case 2: tag = RPMTAG_FILEUIDS; break; - case 3: tag = RPMTAG_FILEGIDS; break; - case 4: tag = RPMTAG_FILEMODES; break; - case 5: tag = RPMTAG_FILEFLAGS; break; - case 6: tag = RPMTAG_CHANGELOGTIME; break; - default: tag = RPMTAG_FILEMTIMES; break; - } - return_list_number(pkg->h, tag); + return_list_int32_t(pkg->h, RPMTAG_FILEMTIMES); + SPAGAIN; + +void +Pkg_files_size(pkg) + URPM::Package pkg + PPCODE: + PUTBACK; + return_list_int32_t(pkg->h, RPMTAG_FILESIZES); + SPAGAIN; + +void +Pkg_files_uid(pkg) + URPM::Package pkg + PPCODE: + PUTBACK; + return_list_int32_t(pkg->h, RPMTAG_FILEUIDS); + SPAGAIN; + +void +Pkg_files_gid(pkg) + URPM::Package pkg + PPCODE: + PUTBACK; + return_list_int32_t(pkg->h, RPMTAG_FILEGIDS); + SPAGAIN; + +void +Pkg_files_mode(pkg) + URPM::Package pkg + PPCODE: + PUTBACK; + return_list_uint_16(pkg->h, RPMTAG_FILEMODES); + SPAGAIN; + +void +Pkg_files_flags(pkg) + URPM::Package pkg + PPCODE: + PUTBACK; + return_list_int32_t(pkg->h, RPMTAG_FILEFLAGS); + SPAGAIN; + +void +Pkg_conf_files(pkg) + URPM::Package pkg + PPCODE: + PUTBACK; + return_files(pkg->h, FILTER_MODE_CONF_FILES); + SPAGAIN; + +void +Pkg_changelog_time(pkg) + URPM::Package pkg + PPCODE: + PUTBACK; + return_list_int32_t(pkg->h, RPMTAG_CHANGELOGTIME); + SPAGAIN; + +void +Pkg_changelog_name(pkg) + URPM::Package pkg + PPCODE: + PUTBACK; + xpush_simple_list_str(pkg->h, RPMTAG_CHANGELOGNAME); + SPAGAIN; + +void +Pkg_changelog_text(pkg) + URPM::Package pkg + PPCODE: + PUTBACK; + xpush_simple_list_str(pkg->h, RPMTAG_CHANGELOGTEXT); SPAGAIN; void @@ -2013,23 +2293,26 @@ Pkg_queryformat(pkg, fmt) if (pkg->h) { s = headerFormat(pkg->h, fmt, NULL); if (s) - mXPUSHs(newSVpv_utf8(s, 0)); + mXPUSHs(newSVpv_utf8(s,0)); } void Pkg_get_tag(pkg, tagname) URPM::Package pkg int tagname; - ALIAS: - get_tag_modifiers = 1 PPCODE: PUTBACK; - if (ix == 0) - return_list_tag(pkg, tagname); - else - return_list_tag_modifier(pkg->h, tagname); + return_list_tag(pkg, tagname); SPAGAIN; +void +Pkg_get_tag_modifiers(pkg, tagname) + URPM::Package pkg + int tagname; + PPCODE: + PUTBACK; + return_list_tag_modifier(pkg->h, tagname); + SPAGAIN; void Pkg_pack_header(pkg) @@ -2045,7 +2328,10 @@ Pkg_update_header(pkg, filename, ...) int packing = 0; int keep_all_tags = 0; CODE: - if (items > 3) { + /* compability mode with older interface of parse_hdlist */ + if (items == 3) + packing = SvIV(ST(2)); + else if (items > 3) { int i; for (i = 2; i < items-1; i+=2) { STRLEN len; @@ -2066,7 +2352,7 @@ void Pkg_free_header(pkg) URPM::Package pkg CODE: - _header_free(pkg); + if (pkg->h && !(pkg->flag & FLAG_NO_HEADER_FREE)) pkg->h = headerFree(pkg->h); pkg->h = NULL; void @@ -2173,56 +2459,135 @@ Pkg_set_flag(pkg, name, value=1) RETVAL int +Pkg_flag_skip(pkg) + URPM::Package pkg + CODE: + RETVAL = pkg->flag & FLAG_SKIP; + OUTPUT: + RETVAL + +int Pkg_set_flag_skip(pkg, value=1) URPM::Package pkg int value - ALIAS: - set_flag_base = 1 - set_flag_disable_obsolete = 2 - set_flag_installed = 3 - set_flag_requested = 4 - set_flag_required = 5 - set_flag_upgrade = 6 CODE: - unsigned flag; - switch (ix) { - case 1: flag = FLAG_BASE; break; - case 2: flag = FLAG_DISABLE_OBSOLETE; break; - case 3: flag = FLAG_INSTALLED; break; - case 4: flag = FLAG_REQUESTED; break; - case 5: flag = FLAG_REQUIRED; break; - case 6: flag = FLAG_UPGRADE; break; - default: flag = FLAG_SKIP; break; - } - RETVAL = pkg->flag & flag; - if (value) pkg->flag |= flag; - else pkg->flag &= ~flag; + RETVAL = pkg->flag & FLAG_SKIP; + if (value) pkg->flag |= FLAG_SKIP; + else pkg->flag &= ~FLAG_SKIP; OUTPUT: RETVAL +int +Pkg_flag_base(pkg) + URPM::Package pkg + CODE: + RETVAL = pkg->flag & FLAG_BASE; + OUTPUT: + RETVAL + +int +Pkg_set_flag_base(pkg, value=1) + URPM::Package pkg + int value + CODE: + RETVAL = pkg->flag & FLAG_BASE; + if (value) pkg->flag |= FLAG_BASE; + else pkg->flag &= ~FLAG_BASE; + OUTPUT: + RETVAL + +int +Pkg_flag_disable_obsolete(pkg) + URPM::Package pkg + CODE: + RETVAL = pkg->flag & FLAG_DISABLE_OBSOLETE; + OUTPUT: + RETVAL + +int +Pkg_set_flag_disable_obsolete(pkg, value=1) + URPM::Package pkg + int value + CODE: + RETVAL = pkg->flag & FLAG_DISABLE_OBSOLETE; + if (value) pkg->flag |= FLAG_DISABLE_OBSOLETE; + else pkg->flag &= ~FLAG_DISABLE_OBSOLETE; + OUTPUT: + RETVAL + +int +Pkg_flag_installed(pkg) + URPM::Package pkg + CODE: + RETVAL = pkg->flag & FLAG_INSTALLED; + OUTPUT: + RETVAL + +int +Pkg_set_flag_installed(pkg, value=1) + URPM::Package pkg + int value + CODE: + RETVAL = pkg->flag & FLAG_INSTALLED; + if (value) pkg->flag |= FLAG_INSTALLED; + else pkg->flag &= ~FLAG_INSTALLED; + OUTPUT: + RETVAL + +int +Pkg_flag_requested(pkg) + URPM::Package pkg + CODE: + RETVAL = pkg->flag & FLAG_REQUESTED; + OUTPUT: + RETVAL + +int +Pkg_set_flag_requested(pkg, value=1) + URPM::Package pkg + int value + CODE: + RETVAL = pkg->flag & FLAG_REQUESTED; + if (value) pkg->flag |= FLAG_REQUESTED; + else pkg->flag &= ~FLAG_REQUESTED; + OUTPUT: + RETVAL int Pkg_flag_required(pkg) URPM::Package pkg - ALIAS: - flag_upgrade = 1 - flag_disable_obsolete = 2 - flag_requested = 3 - flag_installed = 4 - flag_base = 5 - flag_skip = 6 CODE: - unsigned flag; - switch (ix) { - case 1: flag = FLAG_UPGRADE; break; - case 2: flag = FLAG_DISABLE_OBSOLETE; break; - case 3: flag = FLAG_REQUESTED; break; - case 4: flag = FLAG_INSTALLED; break; - case 5: flag = FLAG_BASE; break; - case 6: flag = FLAG_SKIP; break; - default: flag = FLAG_REQUIRED; break; - } - RETVAL = pkg->flag & flag; + RETVAL = pkg->flag & FLAG_REQUIRED; + OUTPUT: + RETVAL + +int +Pkg_set_flag_required(pkg, value=1) + URPM::Package pkg + int value + CODE: + RETVAL = pkg->flag & FLAG_REQUIRED; + if (value) pkg->flag |= FLAG_REQUIRED; + else pkg->flag &= ~FLAG_REQUIRED; + OUTPUT: + RETVAL + +int +Pkg_flag_upgrade(pkg) + URPM::Package pkg + CODE: + RETVAL = pkg->flag & FLAG_UPGRADE; + OUTPUT: + RETVAL + +int +Pkg_set_flag_upgrade(pkg, value=1) + URPM::Package pkg + int value + CODE: + RETVAL = pkg->flag & FLAG_UPGRADE; + if (value) pkg->flag |= FLAG_UPGRADE; + else pkg->flag &= ~FLAG_UPGRADE; OUTPUT: RETVAL @@ -2341,7 +2706,7 @@ Db_open(prefix=NULL, write_perm=0) RETVAL int -Db_rebuild(prefix=NULL) +Db_rebuild(prefix="") char *prefix PREINIT: rpmts ts; @@ -2355,7 +2720,7 @@ Db_rebuild(prefix=NULL) RETVAL int -Db_verify(prefix=NULL) +Db_verify(prefix="") char *prefix PREINIT: rpmts ts; @@ -2381,20 +2746,35 @@ Db_traverse(db,callback) PREINIT: Header header; rpmdbMatchIterator mi; - rpmVSFlags ovsflags; int count = 0; CODE: +#ifdef RPM490 db->ts = rpmtsLink(db->ts); - ovsflags = ts_nosignature(db->ts); +#else + db->ts = rpmtsLink(db->ts, "URPM::DB::traverse"); +#endif + ts_nosignature(db->ts); mi = rpmtsInitIterator(db->ts, RPMDBI_PACKAGES, NULL, 0); while ((header = rpmdbNextIterator(mi))) { if (SvROK(callback)) { - _run_cb_while_traversing(callback, header); + dSP; + URPM__Package pkg = calloc(1, sizeof(struct s_Package)); + + pkg->flag = FLAG_ID_INVALID | FLAG_NO_HEADER_FREE; + pkg->h = header; + + PUSHMARK(SP); + mXPUSHs(sv_setref_pv(newSVpv("", 0), "URPM::Package", pkg)); + PUTBACK; + + call_sv(callback, G_DISCARD | G_SCALAR); + + SPAGAIN; + pkg->h = NULL; /* avoid using it anymore, in case it has been copied inside callback */ } ++count; } rpmdbFreeIterator(mi); - rpmtsSetVSFlags(db->ts, ovsflags); (void)rpmtsFree(db->ts); RETVAL = count; OUTPUT: @@ -2410,29 +2790,45 @@ Db_traverse_tag(db,tag,names,callback) Header header; rpmdbMatchIterator mi; int count = 0; - rpmVSFlags ovsflags; CODE: if (SvROK(names) && SvTYPE(SvRV(names)) == SVt_PVAV) { AV* names_av = (AV*)SvRV(names); int len = av_len(names_av); - int i; - rpmTag rpmtag = rpmtag_from_string(tag); + int i, rpmtag; + + rpmtag = rpmtag_from_string(tag); for (i = 0; i <= len; ++i) { STRLEN str_len; SV **isv = av_fetch(names_av, i, 0); char *name = SvPV(*isv, str_len); +#ifdef RPM490 db->ts = rpmtsLink(db->ts); - ovsflags = ts_nosignature(db->ts); +#else + db->ts = rpmtsLink(db->ts, "URPM::DB::traverse_tag"); +#endif + ts_nosignature(db->ts); mi = rpmtsInitIterator(db->ts, rpmtag, name, str_len); while ((header = rpmdbNextIterator(mi))) { if (SvROK(callback)) { - _run_cb_while_traversing(callback, header); + dSP; + URPM__Package pkg = calloc(1, sizeof(struct s_Package)); + + pkg->flag = FLAG_ID_INVALID | FLAG_NO_HEADER_FREE; + pkg->h = header; + + PUSHMARK(SP); + mXPUSHs(sv_setref_pv(newSVpv("", 0), "URPM::Package", pkg)); + PUTBACK; + + call_sv(callback, G_DISCARD | G_SCALAR); + + SPAGAIN; + pkg->h = NULL; /* avoid using it anymore, in case it has been copied inside callback */ } ++count; } (void)rpmdbFreeIterator(mi); - rpmtsSetVSFlags(db->ts, ovsflags); (void)rpmtsFree(db->ts); } } else croak("bad arguments list"); @@ -2450,21 +2846,36 @@ Db_traverse_tag_find(db,tag,name,callback) Header header; rpmdbMatchIterator mi; CODE: - rpmTag rpmtag = rpmtag_from_string(tag); + int rpmtag = rpmtag_from_string(tag); int found = 0; - rpmVSFlags ovsflags; +#ifdef RPM490 db->ts = rpmtsLink(db->ts); - ovsflags = ts_nosignature(db->ts); +#else + db->ts = rpmtsLink(db->ts, "URPM::DB::traverse_tag"); +#endif + ts_nosignature(db->ts); mi = rpmtsInitIterator(db->ts, rpmtag, name, 0); while ((header = rpmdbNextIterator(mi))) { - int count = _run_cb_while_traversing(callback, header); + dSP; + URPM__Package pkg = calloc(1, sizeof(struct s_Package)); + + pkg->flag = FLAG_ID_INVALID | FLAG_NO_HEADER_FREE; + pkg->h = header; + + PUSHMARK(SP); + mXPUSHs(sv_setref_pv(newSVpv("", 0), "URPM::Package", pkg)); + PUTBACK; + + int count = call_sv(callback, G_SCALAR); + + SPAGAIN; + pkg->h = NULL; /* avoid using it anymore, in case it has been copied inside callback */ if (count == 1 && POPi) { found = 1; break; } } - rpmtsSetVSFlags(db->ts, ovsflags); (void)rpmdbFreeIterator(mi); (void)rpmtsFree(db->ts); RETVAL = found; @@ -2472,12 +2883,17 @@ Db_traverse_tag_find(db,tag,name,callback) RETVAL URPM::Transaction -Db_create_transaction(db) +Db_create_transaction(db, prefix="/") URPM::DB db + char *prefix CODE: /* this is *REALLY* dangerous to create a new transaction while another is open, so use the db transaction instead. */ +#ifdef RPM490 db->ts = rpmtsLink(db->ts); +#else + db->ts = rpmtsLink(db->ts, "URPM::DB::create_transaction"); +#endif ++db->count; RETVAL = db; OUTPUT: @@ -2508,7 +2924,10 @@ Trans_add(trans, pkg, ...) if ((pkg->flag & FLAG_ID) <= FLAG_ID_MAX && pkg->h != NULL) { int update = 0; rpmRelocation *relocations = NULL; - if (items > 3) { + /* compability mode with older interface of add */ + if (items == 3) + update = SvIV(ST(2)); + else if (items > 3) { int i; for (i = 2; i < items-1; i+=2) { STRLEN len; @@ -2545,7 +2964,19 @@ Trans_remove(trans, name) Header h; rpmdbMatchIterator mi; int count = 0; + char *boa = NULL, *bor = NULL; CODE: + /* hide arch in name if present */ + if ((boa = strrchr(name, '.'))) { + *boa = 0; + if ((bor = strrchr(name, '-'))) { + *bor = 0; + if (!strrchr(name, '-')) + *boa = '.'; boa = NULL; + *bor = '-'; bor = NULL; + } else + *boa = '.'; boa = NULL; + } mi = rpmtsInitIterator(trans->ts, RPMDBI_LABEL, name, 0); while ((h = rpmdbNextIterator(mi))) { unsigned int recOffset = rpmdbGetIteratorOffset(mi); @@ -2555,6 +2986,7 @@ Trans_remove(trans, name) } } rpmdbFreeIterator(mi); + if (boa) *boa = '.'; RETVAL=count; OUTPUT: RETVAL @@ -2576,7 +3008,7 @@ Trans_traverse(trans, callback) pkg->flag = FLAG_ID_INVALID | FLAG_NO_HEADER_FREE; pkg->h = h; PUSHMARK(SP); - mXPUSHs(sv_setref_pv(newSVpvs(""), "URPM::Package", pkg)); + mXPUSHs(sv_setref_pv(newSVpv("", 0), "URPM::Package", pkg)); PUTBACK; call_sv(callback, G_DISCARD | G_SCALAR); SPAGAIN; @@ -2608,7 +3040,7 @@ Trans_check(trans, ...) if (gimme == G_SCALAR) mXPUSHs(newSViv(0)); else if (gimme == G_ARRAY) - mXPUSHs(newSVpvs("error while checking dependencies")); + mXPUSHs(newSVpv("error while checking dependencies", 0)); } else { rpmps ps = rpmtsProblems(trans->ts); if (rpmpsNumProblems(ps) > 0) { @@ -2639,7 +3071,7 @@ Trans_order(trans) if (gimme == G_SCALAR) mXPUSHs(newSViv(0)); else if (gimme == G_ARRAY) - mXPUSHs(newSVpvs("error while ordering dependencies")); + mXPUSHs(newSVpv("error while ordering dependencies", 0)); } int @@ -2654,22 +3086,39 @@ char * Trans_Element_name(trans, index) URPM::Transaction trans int index - ALIAS: - Element_version = 1 - Element_release = 2 - Element_fullname = 3 CODE: rpmte te = rpmtsElement(trans->ts, index); - if (te) { - switch (ix) { - case 1: RETVAL = (char *) rpmteV(te); break; - case 2: RETVAL = (char *) rpmteR(te); break; - case 3: RETVAL = (char *) rpmteNEVRA(te); break; - default: RETVAL = (char *) rpmteN(te); break; - } - } else { - RETVAL = NULL; - } + RETVAL = te ? (char *) rpmteN(te) : NULL; + OUTPUT: + RETVAL + +char * +Trans_Element_version(trans, index) + URPM::Transaction trans + int index + CODE: + rpmte te = rpmtsElement(trans->ts, index); + RETVAL = te ? (char *) rpmteV(te) : NULL; + OUTPUT: + RETVAL + +char * +Trans_Element_release(trans, index) + URPM::Transaction trans + int index + CODE: + rpmte te = rpmtsElement(trans->ts, index); + RETVAL = te ? (char *) rpmteR(te) : NULL; + OUTPUT: + RETVAL + +char * +Trans_Element_fullname(trans, index) + URPM::Transaction trans + int index + CODE: + rpmte te = rpmtsElement(trans->ts, index); + RETVAL = te ? (char *) rpmteNEVRA(te) : NULL; OUTPUT: RETVAL @@ -2746,7 +3195,11 @@ Trans_run(trans, data, ...) if (repa) free(repa); } rpmtsSetFlags(trans->ts, transFlags); +#ifdef RPM490 trans->ts = rpmtsLink(trans->ts); +#else + trans->ts = rpmtsLink(trans->ts, "URPM::Transaction::run"); +#endif rpmtsSetNotifyCallback(trans->ts, rpmRunTransactions_callback, &td); if (rpmtsRun(trans->ts, NULL, probFilter) > 0) { rpmps ps = rpmtsProblems(trans->ts); @@ -2776,15 +3229,22 @@ Urpm_read_config_files() OUTPUT: RETVAL +void +Urpm_list_rpm_tag(urpm=Nullsv) + SV *urpm + CODE: + croak("list_rpm_tag() has been removed from perl-URPM. please report if you need it back"); + int rpmvercmp(one, two) char *one char *two int -Urpm_ranges_overlap(a, b) +Urpm_ranges_overlap(a, b, b_nopromote=1) char *a char *b + int b_nopromote PREINIT: char *sa = a, *sb = b; int aflags = 0, bflags = 0; @@ -2814,7 +3274,7 @@ Urpm_ranges_overlap(a, b) else break; ++sb; } - RETVAL = ranges_overlap(aflags, sa, bflags, sb); + RETVAL = ranges_overlap(aflags, sa, bflags, sb, b_nopromote); } OUTPUT: RETVAL @@ -2834,13 +3294,12 @@ Urpm_parse_synthesis__XS(urpm, filename, ...) if (depslist != NULL) { char buff[65536]; - char *p, *eol, *t; + char *p, *eol; int buff_len; struct s_Package pkg; - FD_t f = NULL; + gzFile f; int start_id = 1 + av_len(depslist); SV *callback = NULL; - rpmCompressedMagic compressed = COMPRESSED_OTHER; if (items > 2) { int i; @@ -2854,35 +3313,19 @@ Urpm_parse_synthesis__XS(urpm, filename, ...) } PUTBACK; - int rc = rpmFileIsCompressed(filename, &compressed); - - switch (compressed) { - case COMPRESSED_BZIP2: t = "r.bzip2"; break; - case COMPRESSED_LZMA: - case COMPRESSED_XZ: - t = "r.xz"; break; - case COMPRESSED_OTHER: - default: - t = "r.gzip"; break; - } - f = Fopen(filename, "r.fdio"); - - if (!rc && (f = Fdopen(f, t)) != NULL && !Ferror(f)) { + if ((f = gzopen(filename, "rb")) != NULL) { memset(&pkg, 0, sizeof(struct s_Package)); buff[sizeof(buff)-1] = 0; p = buff; int ok = 1; - while ((buff_len = Fread(p, sizeof(buff)-1-(p-buff), 1, f)) >= 0 && + while ((buff_len = gzread(f, p, sizeof(buff)-1-(p-buff))) >= 0 && (buff_len += p-buff)) { buff[buff_len] = 0; p = buff; if ((eol = strchr(p, '\n')) != NULL) { do { *eol++ = 0; - if (!parse_line(depslist, provides, obsoletes, &pkg, p, urpm, callback)) { - ok = 0; - break; - } + if (!parse_line(depslist, provides, obsoletes, &pkg, p, urpm, callback)) { ok = 0; break; } p = eol; } while ((eol = strchr(p, '\n')) != NULL); } else { @@ -2891,15 +3334,17 @@ Urpm_parse_synthesis__XS(urpm, filename, ...) ok = 0; break; } + if (gzeof(f)) { + if (!parse_line(depslist, provides, obsoletes, &pkg, p, urpm, callback)) ok = 0; + break; + } else { /* move the remaining non-complete-line at beginning */ memmove(buff, p, buff_len-(p-buff)); /* point to the end of the non-complete-line */ p = &buff[buff_len-(p-buff)]; + } } - // EOF: - if (!parse_line(depslist, provides, obsoletes, &pkg, p, urpm, callback)) - ok = 0; - if (Fclose(f) != 0) ok = 0; + if (gzclose(f) != 0) ok = 0; SPAGAIN; if (ok) { mXPUSHs(newSViv(start_id)); @@ -2944,7 +3389,10 @@ Urpm_parse_hdlist__XS(urpm, filename, ...) int packing = 0; SV *callback = NULL; - if (items > 3) { + /* compability mode with older interface of parse_hdlist */ + if (items == 3) + packing = SvTRUE(ST(2)); + else if (items > 3) { int i; for (i = 2; i < items-1; i+=2) { STRLEN len; @@ -2961,13 +3409,14 @@ Urpm_parse_hdlist__XS(urpm, filename, ...) do { header = headerRead(fd, HEADER_MAGIC_YES); if (header != NULL) { - struct s_Package *_pkg; + struct s_Package pkg, *_pkg; SV *sv_pkg; - _pkg = calloc(1, sizeof(struct s_Package)); - _pkg->flag = 1 + av_len(depslist); - _pkg->h = header; - sv_pkg = sv_setref_pv(newSVpvs(""), "URPM::Package", _pkg); + memset(&pkg, 0, sizeof(struct s_Package)); + pkg.flag = 1 + av_len(depslist); + pkg.h = header; + sv_pkg = sv_setref_pv(newSVpv("", 0), "URPM::Package", + _pkg = memcpy(malloc(sizeof(struct s_Package)), &pkg, sizeof(struct s_Package))); if (call_package_callback(urpm, sv_pkg, callback)) { if (provides) { update_provides(_pkg, provides); @@ -3011,14 +3460,17 @@ Urpm_parse_rpm(urpm, filename, ...) HV *obsoletes = fobsoletes && SvROK(*fobsoletes) && SvTYPE(SvRV(*fobsoletes)) == SVt_PVHV ? (HV*)SvRV(*fobsoletes) : NULL; if (depslist != NULL) { - struct s_Package *_pkg; + struct s_Package pkg, *_pkg; SV *sv_pkg; int packing = 0; int keep_all_tags = 0; SV *callback = NULL; rpmVSFlags vsflags = RPMVSF_DEFAULT; - if (items > 3) { + /* compability mode with older interface of parse_hdlist */ + if (items == 3) + packing = SvTRUE(ST(2)); + else if (items > 3) { int i; for (i = 2; i < items-1; i+=2) { STRLEN len; @@ -3052,11 +3504,12 @@ Urpm_parse_rpm(urpm, filename, ...) } } PUTBACK; - _pkg = calloc(1, sizeof(struct s_Package)); - _pkg->flag = 1 + av_len(depslist); + memset(&pkg, 0, sizeof(struct s_Package)); + pkg.flag = 1 + av_len(depslist); + _pkg = memcpy(malloc(sizeof(struct s_Package)), &pkg, sizeof(struct s_Package)); if (update_header(filename, _pkg, keep_all_tags, vsflags)) { - sv_pkg = sv_setref_pv(newSVpvs(""), "URPM::Package", _pkg); + sv_pkg = sv_setref_pv(newSVpv("", 0), "URPM::Package", _pkg); if (call_package_callback(urpm, sv_pkg, callback)) { if (provides) { update_provides(_pkg, provides); @@ -3148,7 +3601,7 @@ Urpm_get_gpg_fingerprint(filename) char * -Urpm_verify_signature(filename, prefix=NULL) +Urpm_verify_signature(filename, prefix="/") char *filename char *prefix PREINIT: @@ -3213,7 +3666,11 @@ Urpm_import_pubkey_file(db, filename) size_t pktlen = 0; int rc; CODE: +#ifdef RPM490 rpmts ts = rpmtsLink(db->ts); +#else + rpmts ts = rpmtsLink(db->ts, "URPM::import_pubkey_file"); +#endif rpmtsClean(ts); if ((rc = pgpReadPkts(filename, (uint8_t ** ) &pkt, &pktlen)) <= 0) @@ -3230,17 +3687,44 @@ Urpm_import_pubkey_file(db, filename) RETVAL int -Urpm_archscore(param) - const char * param - ALIAS: - osscore = 1 +Urpm_import_pubkey(...) + CODE: + unused_variable(&items); + croak("import_pubkey() is dead. use import_pubkey_file() instead"); + RETVAL = 1; + OUTPUT: + RETVAL + +int +Urpm_archscore(arch) + const char * arch PREINIT: CODE: read_config_files(0); - RETVAL=rpmMachineScore(ix == 0 ? RPM_MACHTABLE_INSTARCH : RPM_MACHTABLE_INSTOS, param); + RETVAL=rpmMachineScore(RPM_MACHTABLE_INSTARCH, arch); OUTPUT: RETVAL +int +Urpm_osscore(os) + const char * os + PREINIT: + CODE: + read_config_files(0); + RETVAL=rpmMachineScore(RPM_MACHTABLE_INSTOS, os); + OUTPUT: + RETVAL + +int +Urpm_platformscore(platform) + const char * platform + CODE: + read_config_files(0); + unused_variable(platform); + croak("platformscore() is available only since rpm 4.4.8"); + RETVAL=0; + OUTPUT: + RETVAL void Urpm_stream2header(fp) @@ -3266,6 +3750,7 @@ void Urpm_spec2srcheader(specfile) char *specfile PREINIT: + rpmts ts = rpmtsCreate(); URPM__Package pkg; Spec spec = NULL; Header header = NULL; @@ -3273,33 +3758,65 @@ Urpm_spec2srcheader(specfile) /* ensure the config is in memory with all macro */ read_config_files(0); /* Do not verify architecture */ +#define SPEC_ANYARCH 1 /* Do not verify whether sources exist */ +#define SPEC_FORCE 1 +#ifdef RPM490 spec = rpmSpecParse(specfile, RPMSPEC_ANYARCH|RPMSPEC_FORCE, NULL); if (spec) { header = rpmSpecSourceHeader(spec); +#else + if (!parseSpec(ts, specfile, "/", NULL, 0, NULL, NULL, SPEC_ANYARCH, SPEC_FORCE)) { +#endif SV *sv_pkg; +#ifndef RPM490 + // FIXME: has disappeared in rpm-4.9.0rpmSpecParse + // (See http://www.rpm.org/wiki/Releases/4.9.0) + spec = rpmtsSetSpec(ts, NULL); + header = spec->sourceHeader; + if (! header) + initSourceHeader(spec); +#endif pkg = (URPM__Package)calloc(1, sizeof(struct s_Package)); headerPutString(header, RPMTAG_SOURCERPM, ""); + + { + struct rpmtd_s td = { + .tag = RPMTAG_ARCH, + .type = RPM_STRING_TYPE, + .data = (void *) "src", + .count = 1, + }; /* parseSpec() sets RPMTAG_ARCH to %{_target_cpu} whereas we really a header similar to .src.rpm header */ - headerPutString(header, RPMTAG_ARCH, "src"); + headerMod(header, &td); + } +#ifdef RPM490 pkg->h = headerLink(header); +#else + pkg->h = headerLink(spec->sourceHeader); +#endif sv_pkg = sv_newmortal(); sv_setref_pv(sv_pkg, "URPM::Package", (void*)pkg); XPUSHs(sv_pkg); +#ifdef RPM490 spec = rpmSpecFree(spec); +#else + spec = freeSpec(spec); +#endif } else { XPUSHs(&PL_sv_undef); - /* apparently rpmlib sets errno to this when given a bad spec. */ + /* apparently rpmlib sets errno this when given a bad spec. */ if (errno == EBADF) errno = 0; } + ts = rpmtsFree(ts); void expand(name) char * name PPCODE: const char * value = rpmExpand(name, NULL); - mXPUSHs(newSVpv(value, 0)); + XPUSHs(sv_2mortal(newSVpv(value, 0))); void add_macro_noexpand(macro) diff --git a/URPM/Query.pm b/URPM/Query.pm new file mode 100644 index 0000000..02e911e --- /dev/null +++ b/URPM/Query.pm @@ -0,0 +1,45 @@ +package URPM; + +use strict; +use warnings; + +# perl_checker: require URPM + +# Olivier Thauvin <thauvin@aerov.jussieu.fr> +# This package extend URPM functions to permit +# URPM low level query on rpm header +# $Id: Query.pm 270395 2010-07-30 00:55:59Z nanardon $ +# +# UNUSED BY ANYTHING IN THE DISTRO +# + +# tag2id +# INPUT array of rpm tag name +# Return an array of ID tag + +sub tag2id { + my @l = @_; + my %taglist = URPM::list_rpm_tag(); + map { $taglist{uc($_)} || undef } @l; +} + +sub query_pkg { + my (undef, $pkg, $query) = @_; + my @tags = map { + [ $pkg->get_tag(tag2id($_)) ]; + } $query =~ m/\%\{([^{}]*)\}*/g; + + $query =~ s/\%\{[^{}]*\}/%s/g; + $query =~ s/\\n/\n/g; + $query =~ s/\\t/\t/g; + my ($max, @res) = 0; + + foreach (@tags) { $max < $#{$_} and $max = $#{$_} } + + foreach my $i (0 .. $max) { + push @res, sprintf($query, map { ${$_}[ $#{$_} < $i ? $#{$_} : $i] } @tags); + } + @res; +} + +1; diff --git a/URPM/Resolve.pm b/URPM/Resolve.pm index f79c438..e0eaf9d 100644 --- a/URPM/Resolve.pm +++ b/URPM/Resolve.pm @@ -82,7 +82,7 @@ sub find_candidate_packages_ { $pkg->is_arch_compat or next; $o_rejected && exists $o_rejected->{$pkg->fullname} and next; #- check if at least one provide of the package overlap the property. - !$urpm->{provides}{$name}{$_} || $pkg->provides_overlap($property) + !$urpm->{provides}{$name}{$_} || $pkg->provides_overlap($property, 1) and push @packages, $pkg; } } @@ -287,7 +287,7 @@ sub _find_required_package__sort { my @chosen = map { $_->[0] } @chosen_with_score; #- return immediately if there is only one chosen package - return \@chosen if @chosen == 1; + if (@chosen == 1) { return \@chosen } #- if several packages were selected to match a requested installation, #- and if --more-choices wasn't given, trim the choices to the first one. @@ -490,7 +490,7 @@ sub unsatisfied_requires { #- check on the selected package if a provide is satisfying the resolution (need to do the ops). foreach (grep { exists $state->{selected}{$_} } keys %{$urpm->{provides}{$n} || {}}) { my $p = $urpm->{depslist}[$_]; - !$urpm->{provides}{$n}{$_} || $p->provides_overlap($prop) and next REQUIRES; + !$urpm->{provides}{$n}{$_} || $p->provides_overlap($prop, 1) and next REQUIRES; } #- check if the package itself provides what is necessary. @@ -513,7 +513,7 @@ sub unsatisfied_requires { if (my ($pn, $ps) = property2name_range($_)) { $ps or $state->{cached_installed}{$pn}{$p->fullname} = undef; $pn eq $n or next; - URPM::ranges_overlap($ps, $s) and ++$satisfied; + URPM::ranges_overlap($ps, $s, 1) and ++$satisfied; } } }); @@ -1487,7 +1487,9 @@ sub disable_selected_and_unrequested_dependencies { #- keep in the packages that had to be unselected. @all_unselected or push @all_unselected, @unselected; - last if $urpm->{keep_unrequested_dependencies}; + if ($urpm->{keep_unrequested_dependencies}) { + last; + } #- search for unrequested required packages. foreach (@unselected) { @@ -1552,7 +1554,11 @@ sub _selected_size_filesize { foreach (values %{$state->{rejected} || {}}) { $_->{removed} || $_->{obsoleted} or next; - $size -= abs($_->{size}); + if ($_->{size} < 0) { + $size += $_->{size}; + } else { + $size -= $_->{size}; + } } foreach (@{$state->{orphans_to_remove} || []}) { @@ -1643,7 +1649,9 @@ sub compute_flags { sub _choose_best_pkg { my ($urpm, $pkg_installed, @pkgs) = @_; - _choose_best_pkg_($urpm, $pkg_installed, grep { $_->compare_pkg($pkg_installed) > 0 } @pkgs); + _choose_best_pkg_($urpm, $pkg_installed, grep { + $_->compare_pkg($pkg_installed) > 0; + } @pkgs); } #- side-effects: none diff --git a/t/01setter-getter.t b/t/01setter-getter.t deleted file mode 100644 index 871433d..0000000 --- a/t/01setter-getter.t +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; -use Test::More tests => 63; -use URPM; - - -chdir 't' if -d 't'; - -my $u = URPM->new; -ok($u, 'URPM'); - -$u->parse_rpm("tmp/RPMS/noarch/test-rpm-1.0-1mdk.noarch.rpm"); -ok(@{$u->{depslist}} == 1, 'depslist'); - -my $pkg = $u->{depslist}[0]; -ok($pkg, 'Package'); - -is($pkg->rflags, undef, 'default rflags'); -is($pkg->set_rflags(1, 3), undef, 'storing rflags'); -is(join(',', $pkg->set_rflags(1, 4)), "1,3", 'storing rflags'); -is(join(',', $pkg->rflags), "1,4", 'retrieving stored rflags'); - -######################################## - -test_flags($pkg, ()); - -$pkg->set_flag_skip; -test_flags($pkg, skip => 33554432); -$pkg->set_flag_skip(0); - -$pkg->set_flag_base; -test_flags($pkg, base => 16777216); -$pkg->set_flag_base(0); - -$pkg->set_flag_installed; -test_flags($pkg, installed => 134217728); -$pkg->set_flag_installed(0); - -$pkg->set_flag_upgrade; -test_flags($pkg, upgrade => 1073741824); -$pkg->set_flag_upgrade(0); - -$pkg->set_flag_required; -test_flags($pkg, required => 536870912); -$pkg->set_flag_required(0); - -$pkg->set_flag_requested; -test_flags($pkg, requested => 268435456); -$pkg->set_flag_requested(0); - -$pkg->set_flag_disable_obsolete; -test_flags($pkg, disable_obsolete => 67108864); -$pkg->set_flag_disable_obsolete(0); - -sub test_flags { - my ($pkg, %flags) = @_; - is($pkg->flag_base, $flags{base} || 0, 'base flag'); - is($pkg->flag_skip, $flags{skip} || 0, 'skip flag'); - is($pkg->flag_disable_obsolete, $flags{disable_obsolete} || 0, 'disable_obsolete flag'); - is($pkg->flag_installed, $flags{installed} || 0, 'installed flag'); - is($pkg->flag_requested, $flags{requested} || 0, 'requested flag'); - is($pkg->flag_required, $flags{required} || 0, 'required flag'); - is($pkg->flag_upgrade, $flags{upgrade} || 0, 'upgrade flag'); -} - - - @@ -4,7 +4,7 @@ use strict; use Test::More tests => 8; use URPM; -my $u = URPM->new; +my $u = new URPM; eval { $u->parse_hdlist('non-existent'); }; like( $@, qr/^cannot open hdlist file non-existent/, 'fatal error on hdlist not found' ); @@ -13,7 +13,7 @@ eval { $u->parse_synthesis('non-existent'); }; like( $@, qr/^unable to read synthesis file non-existent/, 'fatal error on synthesis not found' ); is( $! + 0, $!{ENOENT}, '$! is ENOENT' ); -my $v = URPM->new( nofatal => 1 ); +my $v = new URPM( nofatal => 1 ); eval { $v->parse_hdlist('non-existent'); }; is( $@, '', 'no error on hdlist not found' ); @@ -4,18 +4,18 @@ use strict; use warnings; -use Test::More tests => 38; +use Test::More tests => 39; use MDV::Packdrakeng; use URPM; use URPM::Build; - +use URPM::Query; chdir 't' if -d 't'; # shut up URPM::setVerbosity(2); -my $a = URPM->new; +my $a = new URPM; ok($a); END { system('rm -rf hdlist.cz empty_hdlist.cz headers tmp') } @@ -54,7 +54,7 @@ $a->build_hdlist( ok(-f 'hdlist.cz'); -my $b = URPM->new; +my $b = new URPM; ($start, $end) = $b->parse_hdlist('hdlist.cz', keep_all_tags => 1); is("$start $end", "0 0", 'parse_hdlist'); ok(@{$b->{depslist}} == 1); @@ -65,6 +65,9 @@ is($pkg->get_tag(1001), '1.0', 'version'); is($pkg->get_tag(1002), '1mdk', 'release'); is($pkg->queryformat("%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}"), "test-rpm-1.0-1mdk.noarch", q(get headers from hdlist)); +rpm_is_jbj_version() ? + ok($pkg->is_platform_compat() > 0, "can evaluate platform score") : + pass('no platform compat'); my $headers = eval { [ $b->parse_rpms_build_headers(rpms => [ "tmp/RPMS/noarch/test-rpm-1.0-1mdk.noarch.rpm" ], dir => 'headers') ] }; @@ -110,3 +113,7 @@ ok(URPM::rpmvercmp("1:1-1mdk", "2:1-1mdk") == -1, "epoch 1 vs 2 = -1"); END { unlink "bad.spec" } } +sub rpm_is_jbj_version { + # checking for --yaml support + `rpm --help` =~ /yaml/; +} diff --git a/t/synthesis.t b/t/synthesis.t index 4d9d79b..6729b3b 100644 --- a/t/synthesis.t +++ b/t/synthesis.t @@ -2,39 +2,29 @@ use strict ; use warnings ; -use Test::More tests => 95; +use Test::More tests => 94; use URPM; chdir 't' if -d 't'; my $file1 = 'synthesis.sample.cz'; -my $file2 = 'synthesis.sample-xz.cz'; -my $s = <<'EOF'; +open my $f, "| gzip -9 >$file1"; +print $f <<'EOF'; @provides@glibc-devel == 6:2.2.4-25mdk @requires@/sbin/install-info@glibc == 2.2.4@kernel-headers@kernel-headers >= 2.2.1@/bin/sh@/bin/sh@/bin/sh@rpmlib(PayloadFilesHavePrefix) <= 4.0-1@rpmlib(CompressedFileNames) <= 3.0.4-1 @conflicts@texinfo < 3.11@gcc < 2.96-0.50mdk @obsoletes@libc-debug@libc-headers@libc-devel@linuxthreads-devel@glibc-debug @info@glibc-devel-2.2.4-25mdk.i586@6@45692097@Development/C EOF -open my $f, "| gzip -9 >$file1"; -print $f $s; -close $f; -open my $f, "| xz -9 >$file2"; -print $f $s; -$s =~ s/-devel//g; -print $f $s; close $f; -END { unlink $file1, $file2 } +END { unlink $file1 } -my $a = URPM->new; +my $a = new URPM; ok($a); my ($first, $end); -($first, $end) = URPM->new->parse_synthesis($file2); -ok($first == 0 && $end == 1, 'parse XZ synthesis'); - ($first, $end) = URPM->new->parse_synthesis('empty_synthesis.cz'); is("$first $end", "0 -1", 'parse empty synthesis'); |