diff options
Diffstat (limited to 'URPM.xs')
-rw-r--r-- | URPM.xs | 1583 |
1 files changed, 533 insertions, 1050 deletions
@@ -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,11 +99,6 @@ 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); } @@ -113,11 +108,34 @@ static const void* unused_variable(const void *p) { static int rpmError_callback_data; -int rpmError_callback() { +static 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* @@ -132,6 +150,8 @@ 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) { @@ -154,7 +174,7 @@ get_fullname_parts(URPM__Package pkg, char **name, char **version, char **releas } static char * -get_name(Header header, int32_t tag) { +get_name(const Header header, rpmTag tag) { struct rpmtd_s val; headerGet(header, tag, &val, HEADERGET_MINMEM); @@ -162,8 +182,13 @@ get_name(Header header, int32_t 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(Header header, int32_t tag) { +get_int(const Header header, rpmTag tag) { struct rpmtd_s val; headerGet(header, tag, &val, HEADERGET_DEFAULT); @@ -177,21 +202,24 @@ get_filesize(const Header h) { } static int -print_list_entry(char *buff, int sz, const char *name, uint32_t flags, const char *evr) { +print_list_entry(char *buff, int sz, const char *name, rpmsenseFlags 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++ = '>'; @@ -208,85 +236,35 @@ print_list_entry(char *buff, int sz, const char *name, uint32_t flags, const cha } static int -ranges_overlap(uint32_t aflags, char *sa, uint32_t bflags, char *sb, int b_nopromote) { +ranges_overlap(rpmsenseFlags aflags, char *sa, rpmsenseFlags bflags, char *sb) { if (!aflags || !bflags) return 1; /* really faster to test it there instead of later */ else { - int sense = 0; + int res; char *eosa = strchr(sa, ']'); char *eosb = strchr(sb, ']'); - char *ea, *va, *ra, *eb, *vb, *rb; + rpmds dsa, dsb; if (eosa) *eosa = 0; if (eosb) *eosb = 0; - /* 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] = ':'; + + dsa = rpmdsSingle(RPMTAG_REQUIRENAME, "", sa, aflags); + dsb = rpmdsSingle(RPMTAG_REQUIRENAME, "", sb, bflags); + res = rpmdsCompare(dsa, dsb); + rpmdsFree(dsa); + rpmdsFree(dsb); + if (eosb) *eosb = ']'; if (eosa) *eosa = ']'; - /* 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; - } -} -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); + return res; + } } -typedef int (*callback_list_str)(char *s, int slen, const char *name, const uint32_t flags, const char *evr, void *param); +typedef int (*callback_list_str)(char *s, int slen, const char *name, const rpmsenseFlags flags, const char *evr, void *param); static int -callback_list_str_xpush(char *s, int slen, const char *name, uint32_t flags, const char *evr, __attribute__((unused)) void *param) { +callback_list_str_xpush(char *s, int slen, const char *name, rpmsenseFlags flags, const char *evr, __attribute__((unused)) void *param) { dSP; if (s) mXPUSHs(newSVpv(s, slen)); @@ -301,26 +279,11 @@ callback_list_str_xpush(char *s, int slen, const char *name, uint32_t flags, con return 0; } static int -callback_list_str_xpush_requires(char *s, int slen, const char *name, const uint32_t flags, const char *evr, __attribute__((unused)) void *param) { +callback_list_str_xpush_requires(char *s, int slen, const char *name, const rpmsenseFlags flags, const char *evr, __attribute__((unused)) void *param) { dSP; if (s) mXPUSHs(newSVpv(s, slen)); - 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)) { + else { char buff[4096]; int len = print_list_entry(buff, sizeof(buff)-1, name, flags, evr); if (len >= 0) @@ -332,15 +295,14 @@ callback_list_str_xpush_old_suggests(char *s, int slen, const char *name, uint32 } 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, uint32_t flags, const char *evr, void *param) { +callback_list_str_overlap(char *s, int slen, const char *name, rpmsenseFlags flags, const char *evr, void *param) { struct cb_overlap_s *os = (struct cb_overlap_s *)param; int result = 0; char *eos = NULL; @@ -350,7 +312,11 @@ callback_list_str_overlap(char *s, int slen, const char *name, uint32_t flags, c /* 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) { @@ -369,14 +335,17 @@ callback_list_str_overlap(char *s, int slen, const char *name, uint32_t flags, c } /* 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, os->b_nopromote); + result = ranges_overlap(os->flags, os->evr, flags, (char *) evr); else - result = ranges_overlap(flags, (char *) evr, os->flags, os->evr, os->b_nopromote); + result = ranges_overlap(flags, (char *) evr, os->flags, os->evr); } /* fprintf(stderr, "cb_list_str_overlap result=%d, os->direction=%d, os->name=%s, os->evr=%s, name=%s, evr=%s\n", @@ -390,7 +359,7 @@ callback_list_str_overlap(char *s, int slen, const char *name, uint32_t flags, c } static int -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) { +return_list_str(char *s, const Header header, rpmTag tag_name, rpmTag tag_flags, rpmTag tag_version, callback_list_str f, void *param) { int count = 0; if (s != NULL) { @@ -398,23 +367,29 @@ return_list_str(char *s, Header header, int32_t tag_name, int32_t tag_flags, int if (tag_flags && tag_version) { while(ps != NULL) { ++count; - if (f(s, ps-s, NULL, 0, NULL, param)) return -count; + 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; @@ -444,18 +419,20 @@ return_list_str(char *s, Header header, int32_t tag_name, int32_t tag_flags, int } static int -xpush_simple_list_str(Header header, int32_t tag_name) { +xpush_simple_list_str(const Header header, rpmTag 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))) { - mXPUSHs(newSVpv(val, 0)); + mPUSHs(newSVpv(val, 0)); } rpmtdFreeData(&list); PUTBACK; @@ -463,33 +440,18 @@ xpush_simple_list_str(Header header, int32_t tag_name) { } else return 0; } -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) { +static void +return_list_number(const Header header, rpmTag tag_name) { dSP; if (header) { struct rpmtd_s list; if (headerGet(header, tag_name, &list, HEADERGET_DEFAULT)) { int count = rpmtdCount(&list); int i; - uint16_t *list_ = list.data; + EXTEND(SP, count); for(i = 0; i < count; i++) { - mXPUSHs(newSViv(list_[i])); + rpmtdNext(&list); + mPUSHs(newSViv(rpmtdGetNumber(&list))); } rpmtdFreeData(&list); } @@ -497,34 +459,37 @@ return_list_uint_16(Header header, int32_t tag_name) { PUTBACK; } -void -return_list_tag_modifier(Header header, int32_t tag_name) { +static void +return_list_tag_modifier(const Header header, rpmTag 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); - int32_t *list = td.data; + rpmtdInit(&td); for (i = 0; i < count; i++) { char buff[15]; char *s = buff; - 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: + 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 { rpmtdFreeData(&td); return; } @@ -535,16 +500,15 @@ return_list_tag_modifier(Header header, int32_t tag_name) { PUTBACK; } -void -return_list_tag(URPM__Package pkg, int32_t tag_name) { +static void +return_list_tag(const URPM__Package pkg, rpmTag 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) ? (char *) list : "src", 0)); + mXPUSHs(newSVpv(headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? rpmtdGetString(&td) : "src", 0)); else switch (rpmtdType(&td)) { case RPM_NULL_TYPE: @@ -555,27 +519,25 @@ return_list_tag(URPM__Package pkg, int32_t tag_name) { case RPM_INT32_TYPE: { int i; - int *r; - r = (int *)list; + EXTEND(SP, count); for (i=0; i < count; i++) { - mXPUSHs(newSViv(r[i])); + rpmtdNext(&td); + mPUSHs(newSViv(rpmtdGetNumber(&td))); } } break; case RPM_STRING_TYPE: - mXPUSHs(newSVpv((char *) list, 0)); + mPUSHs(newSVpv(rpmtdGetString(&td), 0)); break; case RPM_BIN_TYPE: break; case RPM_STRING_ARRAY_TYPE: { int i; - char **s; - - s = (char **)list; - for (i = 0; i < count; i++) { - mXPUSHs(newSVpv(s[i], 0)); - } + EXTEND(SP, count); + rpmtdInit(&td); + for (i = 0; i < count; i++) + mPUSHs(newSVpv(rpmtdNextString(&td), 0)); } break; case RPM_I18NSTRING_TYPE: @@ -621,18 +583,21 @@ return_list_tag(URPM__Package pkg, int32_t tag_name) { case RPMTAG_SUMMARY: mXPUSHs(newSVpv(pkg->summary, 0)); break; + default: + croak("unexpected tag %s", tag_name); + break; } } PUTBACK; } -void -return_files(Header header, int filter_mode) { +static void +return_files(const Header header, int filter_mode) { dSP; if (header) { char buff[4096]; - char *p, *s; + char *p; const char *s; STRLEN len; unsigned int i; @@ -652,17 +617,19 @@ return_files(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; - char **list = NULL; - if (!baseNames || !dirNames || !dirIndexes) { - if (!headerGet(header, RPMTAG_OLDFILENAMES, &td_list, HEADERGET_DEFAULT)) return; - list = td_list.data; + if (is_oldfilenames) { + if (!headerGet(header, RPMTAG_OLDFILENAMES, &td_list, HEADERGET_DEFAULT)) + return; + rpmtdInit(&td_list); } - for(i = 0; i < rpmtdCount(&td_baseNames); i++) { - if (list) { - s = list[i]; - len = strlen(list[i]); + 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); } else { len = strlen(dirNames[dirIndexes[i]]); if (len >= sizeof(buff)) continue; @@ -681,14 +648,15 @@ return_files(Header header, int filter_mode) { mXPUSHs(newSVpv(s, len)); } - free(baseNames); - free(dirNames); - free(list); + rpmtdFreeData(&td_baseNames); + rpmtdFreeData(&td_dirNames); + if (is_oldfilenames) + rpmtdFreeData(&td_list); } PUTBACK; } -void +static void return_problems(rpmps ps, int translate_message, int raw_message) { dSP; if (ps && rpmpsNumProblems(ps) > 0) { @@ -752,9 +720,9 @@ return_problems(rpmps ps, int translate_message, int raw_message) { } static char * -pack_list(Header header, int32_t tag_name, int32_t tag_flags, int32_t tag_version, int32_t (*check_flag)(int32_t)) { +pack_list(const Header header, rpmTag tag_name, rpmTag tag_flags, rpmTag tag_version) { char buff[65536]; - int32_t *flags = NULL; + rpmTag *flags = NULL; char **list_evr = NULL; unsigned int i; char *p = buff; @@ -767,7 +735,6 @@ pack_list(Header header, int32_t tag_name, int32_t tag_flags, int32_t tag_versio 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; @@ -783,35 +750,30 @@ pack_list(Header header, int32_t tag_name, int32_t tag_flags, int32_t tag_versio } static void -pack_header(URPM__Package pkg) { +pack_header(const URPM__Package pkg) { if (pkg->h) { if (pkg->info == NULL) { char buff[1024]; - char *p = buff; - char *name = get_name(pkg->h, RPMTAG_NAME); - char *version = get_name(pkg->h, RPMTAG_VERSION); - char *release = get_name(pkg->h, RPMTAG_RELEASE); - char *arch = headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? get_name(pkg->h, RPMTAG_ARCH) : "src"; + const char *p = buff; + const char *nvr = headerGetAsString(pkg->h, RPMTAG_NVR); + const char *arch = get_arch(pkg->h); - p += 1 + snprintf(buff, sizeof(buff), "%s-%s-%s.%s@%d@%d@%s", name, version, release, arch, + p += 1 + snprintf(buff, sizeof(buff), "%s.%s@%d@%d@%s", nvr, arch, get_int(pkg->h, RPMTAG_EPOCH), get_int(pkg->h, RPMTAG_SIZE), get_name(pkg->h, RPMTAG_GROUP)); pkg->info = memcpy(malloc(p-buff), buff, p-buff); } if (pkg->filesize == 0) pkg->filesize = get_filesize(pkg->h); - 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->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->obsoletes == NULL) - pkg->obsoletes = pack_list(pkg->h, RPMTAG_OBSOLETENAME, RPMTAG_OBSOLETEFLAGS, RPMTAG_OBSOLETEVERSION, NULL); + pkg->obsoletes = pack_list(pkg->h, RPMTAG_OBSOLETENAME, RPMTAG_OBSOLETEFLAGS, RPMTAG_OBSOLETEVERSION); if (pkg->conflicts == NULL) - pkg->conflicts = pack_list(pkg->h, RPMTAG_CONFLICTNAME, RPMTAG_CONFLICTFLAGS, RPMTAG_CONFLICTVERSION, NULL); + pkg->conflicts = pack_list(pkg->h, RPMTAG_CONFLICTNAME, RPMTAG_CONFLICTFLAGS, RPMTAG_CONFLICTVERSION); if (pkg->provides == NULL) - pkg->provides = pack_list(pkg->h, RPMTAG_PROVIDENAME, RPMTAG_PROVIDEFLAGS, RPMTAG_PROVIDEVERSION, NULL); + pkg->provides = pack_list(pkg->h, RPMTAG_PROVIDENAME, RPMTAG_PROVIDEFLAGS, RPMTAG_PROVIDEVERSION); if (pkg->summary == NULL) { char *summary = get_name(pkg->h, RPMTAG_SUMMARY); int len = 1 + strlen(summary); @@ -819,13 +781,13 @@ pack_header(URPM__Package pkg) { pkg->summary = memcpy(malloc(len), summary, len); } - if (!(pkg->flag & FLAG_NO_HEADER_FREE)) pkg->h =headerFree(pkg->h); + _header_free(pkg); pkg->h = NULL; } } static void -update_hash_entry(HV *hash, char *name, STRLEN len, int force, IV use_sense, URPM__Package pkg) { +update_hash_entry(HV *hash, const char *name, STRLEN len, int force, IV use_sense, const URPM__Package pkg) { SV** isv; if (!len) len = strlen(name); @@ -851,24 +813,24 @@ update_hash_entry(HV *hash, char *name, STRLEN len, int force, IV use_sense, URP } static void -update_provide_entry(char *name, STRLEN len, int force, IV use_sense, URPM__Package pkg, HV *provides) { +update_provide_entry(const char *name, STRLEN len, int force, IV use_sense, const URPM__Package pkg, HV *provides) { update_hash_entry(provides, name, len, force, use_sense, pkg); } static void -update_provides(URPM__Package pkg, HV *provides) { +update_provides(const URPM__Package pkg, HV *provides) { if (pkg->h) { int len; struct rpmtd_s td, td_flags; - int32_t *flags = NULL; + rpmsenseFlags *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) { - len = strlen(list[i]); - if (list[i][0] == '/') (void)hv_fetch(provides, list[i], len, 1); + const char *s = rpmtdNextString(&td); + len = strlen(s); + if (s[0] == '/') (void)hv_fetch(provides, s, len, 1); } } @@ -918,16 +880,15 @@ update_provides(URPM__Package pkg, HV *provides) { } static void -update_obsoletes(URPM__Package pkg, HV *obsoletes) { +update_obsoletes(const 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, list[i], 0, 1, 0, pkg); + update_hash_entry(obsoletes, rpmtdNextString(&td), 0, 1, 0, pkg); } } else { char *ps, *s; @@ -948,10 +909,9 @@ update_obsoletes(URPM__Package pkg, HV *obsoletes) { } static void -update_provides_files(URPM__Package pkg, HV *provides) { +update_provides_files(const 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; @@ -977,25 +937,26 @@ update_provides_files(URPM__Package pkg, HV *provides) { update_provide_entry(buff, p-buff, 0, 0, pkg, provides); } - free(baseNames); - free(dirNames); + rpmtdFreeData(&td_baseNames); + rpmtdFreeData(&td_dirNames); } else { struct rpmtd_s td; - headerGet(pkg->h, RPMTAG_OLDFILENAMES, &td, HEADERGET_DEFAULT); - if (list) { + + if (headerGet(pkg->h, RPMTAG_OLDFILENAMES, &td, HEADERGET_DEFAULT)) { for (i = 0; i < rpmtdCount(&td); i++) { - len = strlen(list[i]); + const char *s = rpmtdNextString(&td); + len = strlen(s); - update_provide_entry(list[i], len, 0, 0, pkg, provides); + update_provide_entry(s, len, 0, 0, pkg, provides); } - free(list); + rpmtdFreeData(&td); } } } } -FD_t +static FD_t open_archive(char *filename, int *empty_archive) { int fd; FD_t rfd = NULL; @@ -1077,7 +1038,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(newSVpv("", 0), "URPM::Package", + sv_pkg = sv_setref_pv(newSVpvs(""), "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); @@ -1192,7 +1153,7 @@ update_header(char *filename, URPM__Package pkg, __attribute__((unused)) int kee if (fd != NULL && rpmReadPackageFile(ts, fd, filename, &header) == 0 && header) { Fclose(fd); - if (pkg->h && !(pkg->flag & FLAG_NO_HEADER_FREE)) pkg->h = headerFree(pkg->h); + _header_free(pkg); pkg->h = header; pkg->flag &= ~FLAG_NO_HEADER_FREE; @@ -1207,7 +1168,7 @@ update_header(char *filename, URPM__Package pkg, __attribute__((unused)) int kee close(d); if (fd != NULL) { - if (pkg->h && !(pkg->flag & FLAG_NO_HEADER_FREE)) pkg->h = headerFree(pkg->h); + _header_free(pkg); pkg->h = headerRead(fd, HEADER_MAGIC_YES); pkg->flag &= ~FLAG_NO_HEADER_FREE; Fclose(fd); @@ -1231,9 +1192,9 @@ read_config_files(int force) { return rc; } -static void +static rpmVSFlags ts_nosignature(rpmts ts) { - rpmtsSetVSFlags(ts, _RPMVSF_NODIGESTS | _RPMVSF_NOSIGNATURES); + return rpmtsSetVSFlags(ts, _RPMVSF_NODIGESTS | _RPMVSF_NOSIGNATURES); } static void *rpmRunTransactions_callback(__attribute__((unused)) const void *h, @@ -1334,20 +1295,11 @@ static void *rpmRunTransactions_callback(__attribute__((unused)) const void *h, i = POPi; fd = fdDup(i); if (fd) { -#ifdef RPM490 fd = fdLink(fd); -#else - fd = fdLink(fd, "persist perl-URPM"); -#endif - Fcntl(fd, F_SETFD, (void *)1); /* necessary to avoid forked/execed process to lock removable */ + Fcntl(fd, F_SETFD, (void *)1); /* necessary to avoid forked/execed process to lock removable media */ } 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; @@ -1360,7 +1312,8 @@ static void *rpmRunTransactions_callback(__attribute__((unused)) const void *h, return callback == td->callback_open ? fd : NULL; } -int rpmtag_from_string(char *tag) +static rpmTag +rpmtag_from_string(char *tag) { if (!strcmp(tag, "name")) return RPMTAG_NAME; @@ -1381,6 +1334,44 @@ int 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 @@ -1395,7 +1386,7 @@ Pkg_DESTROY(pkg) free(pkg->provides); free(pkg->rflags); free(pkg->summary); - if (pkg->h && !(pkg->flag & FLAG_NO_HEADER_FREE)) pkg->h = headerFree(pkg->h); + _header_free(pkg); free(pkg); void @@ -1454,7 +1445,7 @@ Pkg_arch(pkg) get_fullname_parts(pkg, NULL, NULL, NULL, &arch, &eos); mXPUSHs(newSVpv(arch, eos-arch)); } else if (pkg->h) { - mXPUSHs(newSVpv(headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? get_name(pkg->h, RPMTAG_ARCH) : "src", 0)); + mXPUSHs(newSVpv(get_arch(pkg->h), 0)); } int @@ -1480,19 +1471,6 @@ 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 @@ -1506,94 +1484,57 @@ 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) - 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)); + 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; + } int Pkg_buildtime(pkg) URPM::Package pkg + ALIAS: + installtid = 1 CODE: if (pkg->h) - 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); + RETVAL = get_int(pkg->h, ix == 1 ? RPMTAG_INSTALLTID : RPMTAG_BUILDTIME); 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) @@ -1613,25 +1554,24 @@ Pkg_fullname(pkg) if (version - name < 1 || release - version < 1 || arch - release < 1) croak("invalid fullname"); EXTEND(SP, 4); - PUSHs(sv_2mortal(newSVpv(name, version-name-1))); - PUSHs(sv_2mortal(newSVpv(version, release-version-1))); - PUSHs(sv_2mortal(newSVpv(release, arch-release-1))); - PUSHs(sv_2mortal(newSVpv(arch, eos-arch))); + mPUSHs(newSVpv(name, version-name-1)); + mPUSHs(newSVpv(version, release-version-1)); + mPUSHs(newSVpv(release, arch-release-1)); + mPUSHs(newSVpv(arch, eos-arch)); } } else if (pkg->h) { - char *name = get_name(pkg->h, RPMTAG_NAME); - char *version = get_name(pkg->h, RPMTAG_VERSION); - char *release = get_name(pkg->h, RPMTAG_RELEASE); - char *arch = headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? get_name(pkg->h, RPMTAG_ARCH) : "src"; + char *arch = get_arch(pkg->h); if (gimme == G_SCALAR) { - mXPUSHs(newSVpvf("%s-%s-%s.%s", name, version, release, arch)); + char *s = headerGetAsString(pkg->h, RPMTAG_NVR); + mXPUSHs(newSVpvf("%s.%s", s, arch)); + free(s); } else if (gimme == G_ARRAY) { EXTEND(SP, 4); - PUSHs(sv_2mortal(newSVpv(name, 0))); - PUSHs(sv_2mortal(newSVpv(version, 0))); - PUSHs(sv_2mortal(newSVpv(release, 0))); - PUSHs(sv_2mortal(newSVpv(arch, 0))); + 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)); } } @@ -1643,7 +1583,8 @@ 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 @@ -1660,57 +1601,16 @@ Pkg_compare_pkg(lpkg, rpkg) URPM::Package rpkg PREINIT: int compare = 0; - int lepoch; - char *lversion; - char *lrelease; - char *larch; - char *leos; - int repoch; - char *rversion; - char *rrelease; - char *rarch; - char *reos; + int lepoch, repoch; + char *lversion, *lrelease, *larch; + char *rversion, *rrelease, *rarch; CODE: if (lpkg == rpkg) RETVAL = 0; else { - 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(lpkg, &lepoch, &lversion, &lrelease, &larch)) + croak("undefined package"); - 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 { + if (!get_e_v_r(rpkg, &repoch, &rversion, &rrelease, &rarch)) { /* restore info string modified */ if (lpkg->info) { lrelease[-1] = '-'; @@ -1718,12 +1618,9 @@ Pkg_compare_pkg(lpkg, rpkg) } croak("undefined package"); } - compare = lepoch - repoch; + compare = compare_evrs(lepoch, lversion, lrelease, repoch, rversion, rrelease); + // equal? compare arches too 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, '@'); @@ -1733,11 +1630,8 @@ 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; @@ -1749,8 +1643,6 @@ Pkg_compare_pkg(lpkg, rpkg) } if (eolarch) *eolarch = '@'; if (eorarch) *eorarch = '@'; - } - } } /* restore info string modified */ if (lpkg->info) { @@ -1771,70 +1663,38 @@ Pkg_compare(pkg, evr) URPM::Package pkg char *evr PREINIT: - int compare = 0; - int _epoch; - char *_version; - char *_release; - char *_eos; + int _epoch, repoch = 0; + char *_version, *_release, *_eos; CODE: - if (pkg->info) { - char *s; + if (!get_e_v_r(pkg, &_epoch, &_version, &_release, &_eos)) + croak("undefined package"); - 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; + char *epoch = NULL, *version, *release; - /* extract epoch and version from evr */ + /* 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 */ 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] = '.'; } - RETVAL = compare; + if (release) + release[-1] = '-'; /* restore in memory modification */ OUTPUT: RETVAL @@ -1846,7 +1706,8 @@ 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 @@ -1906,12 +1767,10 @@ Pkg_filename(pkg) memcpy(eon, savbuf, 4); } } else if (pkg->h) { - char *name = get_name(pkg->h, RPMTAG_NAME); - char *version = get_name(pkg->h, RPMTAG_VERSION); - char *release = get_name(pkg->h, RPMTAG_RELEASE); - char *arch = headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? get_name(pkg->h, RPMTAG_ARCH) : "src"; + char *nvr = headerGetAsString(pkg->h, RPMTAG_NVR); + char *arch = get_arch(pkg->h); - mXPUSHs(newSVpvf("%s-%s-%s.%s.rpm", name, version, release, arch)); + mXPUSHs(newSVpvf("%s.%s.rpm", nvr, arch)); } # deprecated @@ -1928,12 +1787,10 @@ Pkg_header_filename(pkg) } else if (pkg->h) { char buff[1024]; char *p = buff; - char *name = get_name(pkg->h, RPMTAG_NAME); - char *version = get_name(pkg->h, RPMTAG_VERSION); - char *release = get_name(pkg->h, RPMTAG_RELEASE); - char *arch = headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? get_name(pkg->h, RPMTAG_ARCH) : "src"; + char *nvr = headerGetAsString(pkg->h, RPMTAG_NVR); + char *arch = get_arch(pkg->h); - p += snprintf(buff, sizeof(buff), "%s-%s-%s.%s", name, version, release, arch); + p += snprintf(buff, sizeof(buff), "%s.%s", nvr, arch); mXPUSHs(newSVpv(buff, p-buff)); } @@ -1941,9 +1798,8 @@ 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) @@ -1978,10 +1834,7 @@ Pkg_suggests(pkg) URPM::Package pkg PPCODE: PUTBACK; - 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); + return_list_str(pkg->suggests, pkg->h, RPMTAG_SUGGESTSNAME, 0, 0, callback_list_str_xpush, NULL); SPAGAIN; void @@ -1996,22 +1849,46 @@ Pkg_obsoletes(pkg) void Pkg_obsoletes_nosense(pkg) URPM::Package pkg + ALIAS: + conflicts_nosense = 1 + provides_nosense = 2 PPCODE: PUTBACK; - return_list_str(pkg->obsoletes, pkg->h, RPMTAG_OBSOLETENAME, 0, 0, callback_list_str_xpush, NULL); + 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); SPAGAIN; int -Pkg_obsoletes_overlap(pkg, s, b_nopromote=1, direction=-1) +Pkg_obsoletes_overlap(pkg, s) URPM::Package pkg char *s - int b_nopromote - int direction + ALIAS: + provides_overlap = 1 PREINIT: struct cb_overlap_s os; char *eon = NULL; char eonc = '\0'; - CODE: + 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; + } os.name = s; os.flags = 0; while (*s && *s != ' ' && *s != '[' && *s != '<' && *s != '>' && *s != '=') ++s; @@ -2028,12 +1905,14 @@ Pkg_obsoletes_overlap(pkg, s, b_nopromote=1, direction=-1) os.evr = s; } else os.evr = ""; - os.direction = direction; - os.b_nopromote = b_nopromote; + os.direction = ix == 0 ? -1 : 1; /* 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(pkg->obsoletes, pkg->h, RPMTAG_OBSOLETENAME, RPMTAG_OBSOLETEFLAGS, RPMTAG_OBSOLETEVERSION, + RETVAL = return_list_str(ix == 0 ? pkg->obsoletes : pkg->provides, pkg->h, tag_name, tag_flags, tag_version, callback_list_str_overlap, &os) < 0; /* restore end of name */ if (eon) *eon = eonc; @@ -2050,14 +1929,6 @@ 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: @@ -2067,220 +1938,69 @@ 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; - 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); + 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); SPAGAIN; void Pkg_files(pkg) URPM::Package pkg + ALIAS: + conf_files = 1 PPCODE: PUTBACK; - 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); + return_files(pkg->h, ix == 0 ? 0 : FILTER_MODE_CONF_FILES); 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; - 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); + 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); SPAGAIN; void @@ -2293,26 +2013,23 @@ 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; - return_list_tag(pkg, tagname); + if (ix == 0) + return_list_tag(pkg, tagname); + else + return_list_tag_modifier(pkg->h, 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) @@ -2328,10 +2045,7 @@ Pkg_update_header(pkg, filename, ...) int packing = 0; int keep_all_tags = 0; CODE: - /* compability mode with older interface of parse_hdlist */ - if (items == 3) - packing = SvIV(ST(2)); - else if (items > 3) { + if (items > 3) { int i; for (i = 2; i < items-1; i+=2) { STRLEN len; @@ -2352,7 +2066,7 @@ void Pkg_free_header(pkg) URPM::Package pkg CODE: - if (pkg->h && !(pkg->flag & FLAG_NO_HEADER_FREE)) pkg->h = headerFree(pkg->h); + _header_free(pkg); pkg->h = NULL; void @@ -2459,135 +2173,56 @@ 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: - 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; + 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; 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: - 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; + 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; OUTPUT: RETVAL @@ -2706,7 +2341,7 @@ Db_open(prefix=NULL, write_perm=0) RETVAL int -Db_rebuild(prefix="") +Db_rebuild(prefix=NULL) char *prefix PREINIT: rpmts ts; @@ -2720,7 +2355,7 @@ Db_rebuild(prefix="") RETVAL int -Db_verify(prefix="") +Db_verify(prefix=NULL) char *prefix PREINIT: rpmts ts; @@ -2746,35 +2381,20 @@ Db_traverse(db,callback) PREINIT: Header header; rpmdbMatchIterator mi; + rpmVSFlags ovsflags; int count = 0; CODE: -#ifdef RPM490 db->ts = rpmtsLink(db->ts); -#else - db->ts = rpmtsLink(db->ts, "URPM::DB::traverse"); -#endif - ts_nosignature(db->ts); + ovsflags = ts_nosignature(db->ts); mi = rpmtsInitIterator(db->ts, RPMDBI_PACKAGES, NULL, 0); while ((header = rpmdbNextIterator(mi))) { if (SvROK(callback)) { - 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 */ + _run_cb_while_traversing(callback, header); } ++count; } rpmdbFreeIterator(mi); + rpmtsSetVSFlags(db->ts, ovsflags); (void)rpmtsFree(db->ts); RETVAL = count; OUTPUT: @@ -2790,45 +2410,29 @@ 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); -#else - db->ts = rpmtsLink(db->ts, "URPM::DB::traverse_tag"); -#endif - ts_nosignature(db->ts); + ovsflags = ts_nosignature(db->ts); mi = rpmtsInitIterator(db->ts, rpmtag, name, str_len); while ((header = rpmdbNextIterator(mi))) { if (SvROK(callback)) { - 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 */ + _run_cb_while_traversing(callback, header); } ++count; } (void)rpmdbFreeIterator(mi); + rpmtsSetVSFlags(db->ts, ovsflags); (void)rpmtsFree(db->ts); } } else croak("bad arguments list"); @@ -2846,36 +2450,21 @@ Db_traverse_tag_find(db,tag,name,callback) Header header; rpmdbMatchIterator mi; CODE: - int rpmtag = rpmtag_from_string(tag); + rpmTag rpmtag = rpmtag_from_string(tag); int found = 0; -#ifdef RPM490 + rpmVSFlags ovsflags; db->ts = rpmtsLink(db->ts); -#else - db->ts = rpmtsLink(db->ts, "URPM::DB::traverse_tag"); -#endif - ts_nosignature(db->ts); + ovsflags = ts_nosignature(db->ts); mi = rpmtsInitIterator(db->ts, rpmtag, name, 0); while ((header = rpmdbNextIterator(mi))) { - 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 */ + int count = _run_cb_while_traversing(callback, header); if (count == 1 && POPi) { found = 1; break; } } + rpmtsSetVSFlags(db->ts, ovsflags); (void)rpmdbFreeIterator(mi); (void)rpmtsFree(db->ts); RETVAL = found; @@ -2883,17 +2472,12 @@ Db_traverse_tag_find(db,tag,name,callback) RETVAL URPM::Transaction -Db_create_transaction(db, prefix="/") +Db_create_transaction(db) 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: @@ -2924,10 +2508,7 @@ Trans_add(trans, pkg, ...) if ((pkg->flag & FLAG_ID) <= FLAG_ID_MAX && pkg->h != NULL) { int update = 0; rpmRelocation *relocations = NULL; - /* compability mode with older interface of add */ - if (items == 3) - update = SvIV(ST(2)); - else if (items > 3) { + if (items > 3) { int i; for (i = 2; i < items-1; i+=2) { STRLEN len; @@ -2964,19 +2545,7 @@ 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); @@ -2986,7 +2555,6 @@ Trans_remove(trans, name) } } rpmdbFreeIterator(mi); - if (boa) *boa = '.'; RETVAL=count; OUTPUT: RETVAL @@ -3008,7 +2576,7 @@ Trans_traverse(trans, callback) pkg->flag = FLAG_ID_INVALID | FLAG_NO_HEADER_FREE; pkg->h = h; PUSHMARK(SP); - mXPUSHs(sv_setref_pv(newSVpv("", 0), "URPM::Package", pkg)); + mXPUSHs(sv_setref_pv(newSVpvs(""), "URPM::Package", pkg)); PUTBACK; call_sv(callback, G_DISCARD | G_SCALAR); SPAGAIN; @@ -3040,7 +2608,7 @@ Trans_check(trans, ...) if (gimme == G_SCALAR) mXPUSHs(newSViv(0)); else if (gimme == G_ARRAY) - mXPUSHs(newSVpv("error while checking dependencies", 0)); + mXPUSHs(newSVpvs("error while checking dependencies")); } else { rpmps ps = rpmtsProblems(trans->ts); if (rpmpsNumProblems(ps) > 0) { @@ -3071,7 +2639,7 @@ Trans_order(trans) if (gimme == G_SCALAR) mXPUSHs(newSViv(0)); else if (gimme == G_ARRAY) - mXPUSHs(newSVpv("error while ordering dependencies", 0)); + mXPUSHs(newSVpvs("error while ordering dependencies")); } int @@ -3086,39 +2654,22 @@ 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); - 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; + 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; + } OUTPUT: RETVAL @@ -3195,11 +2746,7 @@ 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); @@ -3229,22 +2776,15 @@ 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, b_nopromote=1) +Urpm_ranges_overlap(a, b) char *a char *b - int b_nopromote PREINIT: char *sa = a, *sb = b; int aflags = 0, bflags = 0; @@ -3274,7 +2814,7 @@ Urpm_ranges_overlap(a, b, b_nopromote=1) else break; ++sb; } - RETVAL = ranges_overlap(aflags, sa, bflags, sb, b_nopromote); + RETVAL = ranges_overlap(aflags, sa, bflags, sb); } OUTPUT: RETVAL @@ -3294,12 +2834,13 @@ Urpm_parse_synthesis__XS(urpm, filename, ...) if (depslist != NULL) { char buff[65536]; - char *p, *eol; + char *p, *eol, *t; int buff_len; struct s_Package pkg; - gzFile f; + FD_t f = NULL; int start_id = 1 + av_len(depslist); SV *callback = NULL; + rpmCompressedMagic compressed = COMPRESSED_OTHER; if (items > 2) { int i; @@ -3313,19 +2854,35 @@ Urpm_parse_synthesis__XS(urpm, filename, ...) } PUTBACK; - if ((f = gzopen(filename, "rb")) != NULL) { + 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)) { memset(&pkg, 0, sizeof(struct s_Package)); buff[sizeof(buff)-1] = 0; p = buff; int ok = 1; - while ((buff_len = gzread(f, p, sizeof(buff)-1-(p-buff))) >= 0 && + while ((buff_len = Fread(p, sizeof(buff)-1-(p-buff), 1, f)) >= 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 { @@ -3334,17 +2891,15 @@ 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)]; - } } - if (gzclose(f) != 0) ok = 0; + // EOF: + if (!parse_line(depslist, provides, obsoletes, &pkg, p, urpm, callback)) + ok = 0; + if (Fclose(f) != 0) ok = 0; SPAGAIN; if (ok) { mXPUSHs(newSViv(start_id)); @@ -3389,10 +2944,7 @@ Urpm_parse_hdlist__XS(urpm, filename, ...) int packing = 0; SV *callback = NULL; - /* compability mode with older interface of parse_hdlist */ - if (items == 3) - packing = SvTRUE(ST(2)); - else if (items > 3) { + if (items > 3) { int i; for (i = 2; i < items-1; i+=2) { STRLEN len; @@ -3409,14 +2961,13 @@ Urpm_parse_hdlist__XS(urpm, filename, ...) do { header = headerRead(fd, HEADER_MAGIC_YES); if (header != NULL) { - struct s_Package pkg, *_pkg; + struct s_Package *_pkg; SV *sv_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))); + _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); if (call_package_callback(urpm, sv_pkg, callback)) { if (provides) { update_provides(_pkg, provides); @@ -3460,17 +3011,14 @@ 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, *_pkg; + struct s_Package *_pkg; SV *sv_pkg; int packing = 0; int keep_all_tags = 0; SV *callback = NULL; rpmVSFlags vsflags = RPMVSF_DEFAULT; - /* compability mode with older interface of parse_hdlist */ - if (items == 3) - packing = SvTRUE(ST(2)); - else if (items > 3) { + if (items > 3) { int i; for (i = 2; i < items-1; i+=2) { STRLEN len; @@ -3504,12 +3052,11 @@ Urpm_parse_rpm(urpm, filename, ...) } } PUTBACK; - 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)); + _pkg = calloc(1, sizeof(struct s_Package)); + _pkg->flag = 1 + av_len(depslist); if (update_header(filename, _pkg, keep_all_tags, vsflags)) { - sv_pkg = sv_setref_pv(newSVpv("", 0), "URPM::Package", _pkg); + sv_pkg = sv_setref_pv(newSVpvs(""), "URPM::Package", _pkg); if (call_package_callback(urpm, sv_pkg, callback)) { if (provides) { update_provides(_pkg, provides); @@ -3601,7 +3148,7 @@ Urpm_get_gpg_fingerprint(filename) char * -Urpm_verify_signature(filename, prefix="/") +Urpm_verify_signature(filename, prefix=NULL) char *filename char *prefix PREINIT: @@ -3666,11 +3213,7 @@ 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) @@ -3687,44 +3230,17 @@ Urpm_import_pubkey_file(db, filename) RETVAL int -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 +Urpm_archscore(param) + const char * param + ALIAS: + osscore = 1 PREINIT: CODE: read_config_files(0); - RETVAL=rpmMachineScore(RPM_MACHTABLE_INSTARCH, arch); + RETVAL=rpmMachineScore(ix == 0 ? RPM_MACHTABLE_INSTARCH : RPM_MACHTABLE_INSTOS, param); 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) @@ -3750,7 +3266,6 @@ void Urpm_spec2srcheader(specfile) char *specfile PREINIT: - rpmts ts = rpmtsCreate(); URPM__Package pkg; Spec spec = NULL; Header header = NULL; @@ -3758,65 +3273,33 @@ 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 */ - headerMod(header, &td); - } -#ifdef RPM490 + headerPutString(header, RPMTAG_ARCH, "src"); 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 this when given a bad spec. */ + /* apparently rpmlib sets errno to 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); - XPUSHs(sv_2mortal(newSVpv(value, 0))); + mXPUSHs(newSVpv(value, 0)); void add_macro_noexpand(macro) |