aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MANIFEST1
-rwxr-xr-xMakefile.PL4
-rw-r--r--NEWS56
-rw-r--r--URPM.pm26
-rw-r--r--URPM.xs1583
-rw-r--r--URPM/Query.pm45
-rw-r--r--URPM/Resolve.pm22
-rw-r--r--t/01setter-getter.t69
-rw-r--r--t/fatal.t4
-rw-r--r--t/parse.t15
-rw-r--r--t/synthesis.t20
11 files changed, 1153 insertions, 692 deletions
diff --git a/MANIFEST b/MANIFEST
index 848760c..9e8feb2 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -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/*" },
);
diff --git a/NEWS b/NEWS
index 674054d..41ba849 100644
--- a/NEWS
+++ b/NEWS
@@ -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
diff --git a/URPM.pm b/URPM.pm
index ba82c3b..b82a314 100644
--- a/URPM.pm
+++ b/URPM.pm
@@ -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,
diff --git a/URPM.xs b/URPM.xs
index e4dda2a..04c713a 100644
--- a/URPM.xs
+++ b/URPM.xs
@@ -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');
-}
-
-
-
diff --git a/t/fatal.t b/t/fatal.t
index 4638983..0cfeafa 100644
--- a/t/fatal.t
+++ b/t/fatal.t
@@ -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' );
diff --git a/t/parse.t b/t/parse.t
index 92159e8..ef8b5fd 100644
--- a/t/parse.t
+++ b/t/parse.t
@@ -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');