]> TLD Linux GIT Repositories - packages/poldek.git/commitdiff
- merged 0.45.0 from PLD master
authorMarcin Krol <hawk@tld-linux.org>
Tue, 19 May 2026 16:15:13 +0000 (18:15 +0200)
committerMarcin Krol <hawk@tld-linux.org>
Tue, 19 May 2026 16:15:13 +0000 (18:15 +0200)
15 files changed:
fix-reinstall-sigsev.patch [deleted file]
gcc15.patch [deleted file]
linguas.patch [deleted file]
pkgiter-preun-req-skip.patch [deleted file]
poldek-dup-sources.patch [new file with mode: 0644]
poldek-env-columns-lines.patch [new file with mode: 0644]
poldek-global-ignore-merges.patch [new file with mode: 0644]
poldek-multilib-bare-name-install.patch [new file with mode: 0644]
poldek-nocolor-cmp.patch [new file with mode: 0644]
poldek-scoring-evr.patch [new file with mode: 0644]
poldek-search-i-opt.patch [new file with mode: 0644]
poldek.spec
proxy-fix.patch [deleted file]
restore-verify-all.patch [deleted file]
verify-fix.patch [deleted file]

diff --git a/fix-reinstall-sigsev.patch b/fix-reinstall-sigsev.patch
deleted file mode 100644 (file)
index bc05b88..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/pkgset-dep.c b/pkgset-dep.c
-index ddaf74e..f035cd9 100644
---- a/pkgset-dep.c
-+++ b/pkgset-dep.c
-@@ -293,6 +293,8 @@ tn_array *get_conflicted(int indent, struct pkgset *ps,
-     const struct capreq_idx_ent *ent;
-     const char *cnflname = capreq_name(cnfl);
-+    pkgset__index_caps(ps);
-+
-     if ((ent = capreq_idx_lookup(&ps->cap_idx, cnflname, capreq_name_len(cnfl)))) {
-         struct pkg **suspkgs = (struct pkg **)ent->pkgs;
-         int nmatch = 0;
diff --git a/gcc15.patch b/gcc15.patch
deleted file mode 100644 (file)
index 205f933..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-diff -ur poldek-0.44.0.orig/conf.c poldek-0.44.0/conf.c
---- poldek-0.44.0.orig/conf.c  2025-02-26 12:40:22.000000000 +0100
-+++ poldek-0.44.0/conf.c       2025-08-10 22:26:33.098247697 +0200
-@@ -1458,33 +1458,33 @@
- int poldek_conf_get_bool(const tn_hash *htconf, const char *name, int default_v)
- {
-     const char *v;
--    int bool;
-+    int bit;
-     if ((v = poldek_conf_get(htconf, name, NULL)) == NULL)
-         return default_v;
--    if ((bool = poldek_util_parse_bool(v)) < 0) {
-+    if ((bit = poldek_util_parse_bool(v)) < 0) {
-         logn(LOGERR, _("invalid value ('%s') of boolean option '%s'"), v, name);
--        bool = default_v;
-+        bit = default_v;
-     }
--    return bool;
-+    return bit;
- }
- int poldek_conf_get_bool3(const tn_hash *htconf, const char *name, int default_v)
- {
-     const char *v;
--    int bool;
-+    int bit;
-     if ((v = poldek_conf_get(htconf, name, NULL)) == NULL)
-         return default_v;
--    if ((bool = poldek_util_parse_bool3(v)) < 0) {
-+    if ((bit = poldek_util_parse_bool3(v)) < 0) {
-         logn(LOGERR, _("invalid value ('%s') of option '%s'"), v, name);
--        bool = default_v;
-+        bit = default_v;
-     }
--    return bool;
-+    return bit;
- }
diff --git a/linguas.patch b/linguas.patch
deleted file mode 100644 (file)
index 97d86cf..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-From 9a91c58a282617a536a99d86be4eaa2da7e433ed Mon Sep 17 00:00:00 2001
-From: Jan Palus <jpalus@fastmail.com>
-Date: Thu, 26 Jun 2025 00:30:42 +0200
-Subject: [PATCH] list available translations in po/LINGUAS file
-
-fixes compatibility with gettext >= 0.24
----
- configure.ac | 2 --
- po/LINGUAS   | 1 +
- 2 files changed, 1 insertion(+), 2 deletions(-)
- create mode 100644 po/LINGUAS
-
-diff --git a/configure.ac b/configure.ac
-index fab947b..9afc747 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -46,8 +46,6 @@ fi
- AC_SUBST(VERSION_CVSTAG)
- AC_DEFINE_UNQUOTED([VERSION_YEAR], "$VERSION_YEAR", [version year])
--ALL_LINGUAS="pl de"
--
- dnl cond. building NFY
- dnl AC_DEFINE([ENABLE_VFILE_TRURLIO],1,[defined if trurlio is used for vfile operations])
-diff --git a/po/LINGUAS b/po/LINGUAS
-new file mode 100644
-index 0000000..78b66c3
---- /dev/null
-+++ b/po/LINGUAS
-@@ -0,0 +1 @@
-+de pl
--- 
-2.50.0
-
diff --git a/pkgiter-preun-req-skip.patch b/pkgiter-preun-req-skip.patch
deleted file mode 100644 (file)
index 900c616..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-From cfb03a18a51ed409a143ef56624fc67b12b58073 Mon Sep 17 00:00:00 2001
-From: Jan Palus <jpalus@fastmail.com>
-Date: Wed, 25 Jun 2025 22:11:12 +0200
-Subject: [PATCH] pkgiter: don't skip reqs which are both pre and preun
-
----
- pkgiter.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/pkgiter.c b/pkgiter.c
-index bc085a4..4e0b810 100644
---- a/pkgiter.c
-+++ b/pkgiter.c
-@@ -147,7 +147,7 @@ const struct capreq *pkg_req_iter_get(struct pkg_req_iter *it)
-         if ((it->flags & PKG_ITER_REQUN) && !capreq_is_prereq_un(req))
-             return pkg_req_iter_get(it);
--        else if ((it->flags & PKG_ITER_REQUN) == 0 && capreq_is_prereq_un(req))
-+        else if ((it->flags & PKG_ITER_REQUN) == 0 && !capreq_is_prereq(req) && capreq_is_prereq_un(req))
-             return pkg_req_iter_get(it);
-         /* set type of returned (current) req */
--- 
-2.50.0
-
diff --git a/poldek-dup-sources.patch b/poldek-dup-sources.patch
new file mode 100644 (file)
index 0000000..f98da4a
--- /dev/null
@@ -0,0 +1,143 @@
+commit bd97788fa990b4b2cd957c540399cec35afab526
+Author: Arkadiusz Miśkiewicz <arekm@maven.pl>
+Date:   Tue Apr 14 16:26:11 2026 +0200
+
+    Show config file origin when removing duplicated sources
+    
+    Print which config file:line each duplicated source was defined at,
+    making it easy to find and fix the duplication.
+    
+    Also fix conf.c filemark formatting: remove trailing colon from
+    stored __file__line value and format strings to avoid double-colon
+    artifacts in error messages.
+
+diff --git a/conf.c b/conf.c
+index 83e625f6..f9f775b0 100644
+--- a/conf.c
++++ b/conf.c
+@@ -505,7 +505,7 @@ static int verify_param_presence(tn_hash *ht_sect, const char *section,
+     if (overwrite || (tag->flags & CONF_TYPE_F_MULTI_EXCL)) {
+         if (!overwrite || poldek_VERBOSE > 1)
+-            logn(LOGWARN, _("%s %s::%s redefined"), filemark, section, name);
++            logn(LOGWARN, _("%s: %s::%s redefined"), filemark, section, name);
+         n_hash_remove(ht_sect, name);
+     } else if ((tag->flags & CONF_TYPE_F_MULTI) == 0) {
+@@ -541,9 +541,9 @@ static int add_param(tn_hash *ht_sect, const char *section,
+     validate = (flags & ADD_PARAM_VALIDATE);
+     if (path)
+-        n_snprintf(filemark, sizeof(filemark), "%s:%d:", path, nline);
++        n_snprintf(filemark, sizeof(filemark), "%s:%d", path, nline);
+     else
+-        n_snprintf(filemark, sizeof(filemark), "config:");
++        n_snprintf(filemark, sizeof(filemark), "config");
+     if ((tagindex = find_tag(section, name, &sect)) == -1) {
+         if (*name == '_')       /* internal or _macro */
+@@ -554,7 +554,7 @@ static int add_param(tn_hash *ht_sect, const char *section,
+             tag = &unknown_tag;
+         } else {
+-            logn(LOGWARN, _("%s unknown option '%s::%s'"), filemark,
++            logn(LOGWARN, _("%s: unknown option '%s::%s'"), filemark,
+                  section, name);
+             return 0;
+         }
+@@ -604,7 +604,7 @@ static int add_param(tn_hash *ht_sect, const char *section,
+         val = "";
+     if (val == NULL) {
+-        logn(LOGERR, _("%s invalid value of '%s::%s'"), filemark, section, name);
++        logn(LOGERR, _("%s: invalid value of '%s::%s'"), filemark, section, name);
+         return 0;
+     }
+@@ -618,7 +618,7 @@ static int add_param(tn_hash *ht_sect, const char *section,
+         }
+         if (!valid) {
+-            logn(LOGWARN, _("%s invalid value '%s' of '%s::%s'"), filemark,
++            logn(LOGWARN, _("%s: invalid value '%s' of '%s::%s'"), filemark,
+                  val, section, name);
+             return 0;
+         }
+@@ -826,7 +826,7 @@ static tn_hash *open_section_ht(tn_hash *htconf,
+         char filemark[PATH_MAX];
+         struct copt *opt;
+-        n_snprintf(filemark, sizeof(filemark), "%s:%d:", path, nline);
++        n_snprintf(filemark, sizeof(filemark), "%s:%d", path, nline);
+         opt = copt_new("__file__line");
+         opt->val = n_strdup(filemark);
+         n_hash_insert(ht_sect, opt->name, opt);
+diff --git a/pkgdir/source.c b/pkgdir/source.c
+index 28c0049f..8d23592d 100644
+--- a/pkgdir/source.c
++++ b/pkgdir/source.c
+@@ -176,6 +176,7 @@ struct source *source_malloc(void)
+     //src->flags |= PKGSOURCE_PRI;
+     src->name = src->path = src->pkg_prefix = NULL;
+     src->group = src->dscr = NULL;
++    src->config_origin = NULL;
+     src->lc_lang = NULL;
+     src->_refcnt = 0;
+     src->exclude_path = n_array_new(4, free, (tn_fn_cmp)strcmp);
+@@ -213,6 +214,7 @@ struct source *source_clone(const struct source *src)
+     cp_str_ifnotnull(&nsrc->group, src->group);
+     cp_str_ifnotnull(&nsrc->lc_lang, src->lc_lang);
+     cp_str_ifnotnull(&nsrc->original_type, src->original_type);
++    cp_str_ifnotnull(&nsrc->config_origin, src->config_origin);
+     n_array_free(nsrc->exclude_path);
+     nsrc->exclude_path = n_ref(src->exclude_path);
+@@ -241,6 +243,7 @@ void source_free(struct source *src)
+     n_cfree(&src->group);
+     n_cfree(&src->lc_lang);
+     n_cfree(&src->original_type);
++    n_cfree(&src->config_origin);
+     if (src->exclude_path)
+         n_array_free(src->exclude_path);
+@@ -662,6 +665,10 @@ struct source *source_new_htcnf(const tn_hash *htcnf)
+     if (vs)
+         src->original_type = n_strdup(vs);
++    vs = poldek_conf_get(htcnf, "__file__line", NULL);
++    if (vs)
++        src->config_origin = n_strdup(vs);
++
+     get_conf_opt_list(htcnf, "exclude path", src->exclude_path);
+     get_conf_opt_list(htcnf, "ignore", src->ign_patterns);
+     return src;
+@@ -687,11 +694,16 @@ int source_cmp_uniq(const struct source *s1, const struct source *s2)
+         rc = strcmp(n1, n2);
+     }
+-    if (rc == 0)
++    if (rc == 0) {
+         logn(LOGWARN, _("removed duplicated source %s%s%s"),
+              (s2->flags & PKGSOURCE_NAMED) ? s2->name : "",
+              (s2->flags & PKGSOURCE_NAMED) ? " -- " : "",
+              s2->path);
++        if (s1->config_origin || s2->config_origin)
++            logn(LOGWARN, _("  defined at %s and %s"),
++                 s1->config_origin ? s1->config_origin : "(unknown)",
++                 s2->config_origin ? s2->config_origin : "(unknown)");
++    }
+     return rc;
+ }
+diff --git a/pkgdir/source.h b/pkgdir/source.h
+index 6052ec25..b93639b5 100644
+--- a/pkgdir/source.h
++++ b/pkgdir/source.h
+@@ -55,6 +55,7 @@ struct source {
+     tn_array  *exclude_path;
+     tn_array  *ign_patterns;    /* ignore package patterns */
+     char      *original_type;   /* type of source repo for this source  */
++    char      *config_origin;   /* config file:line where source was defined */
+     unsigned  subopt_flags;
+     int       _refcnt;
+     char      *group;
diff --git a/poldek-env-columns-lines.patch b/poldek-env-columns-lines.patch
new file mode 100644 (file)
index 0000000..89198e5
--- /dev/null
@@ -0,0 +1,65 @@
+commit bcf31cc1653155c93ad4b2b1a17d2301ac70d36b
+Author: Arkadiusz Miśkiewicz <arekm@maven.pl>
+Date:   Tue Apr 14 17:45:51 2026 +0200
+
+    Use $COLUMNS as fallback when ioctl fails to get terminal width
+    
+    When stdout is not a tty (e.g. piped output), ioctl TIOCGWINSZ fails
+    and terminal width falls back to 80 columns, causing unnecessary URL
+    truncation. Check $COLUMNS environment variable before falling back
+    to the default.
+
+diff --git a/poldek_term.c b/poldek_term.c
+index 9d4f9a87..6fbf7d82 100644
+--- a/poldek_term.c
++++ b/poldek_term.c
+@@ -245,15 +245,34 @@ static void update_term_width(void)
+     if (winch_reached) {
+         char tmp[256];
++        term_width  = TERM_DEFAULT_WIDTH;
++        term_height = TERM_DEFAULT_HEIGHT;
++
+         if (ioctl(1, TIOCGWINSZ, &ws) == 0) {
+             term_width  = ws.ws_col;
+             term_height = ws.ws_row;
+         } else {
+-            term_width  = TERM_DEFAULT_WIDTH;
+-            term_height = TERM_DEFAULT_HEIGHT;
++            const char *cols = getenv("COLUMNS");
++            if (cols) {
++                int n = atoi(cols);
++                if (n > 0)
++                    term_width = n;
++            }
++
++            const char *rows = getenv("LINES");
++            if (rows) {
++                int n = atoi(rows);
++                if (n > 0)
++                    term_height = n;
++            }
+         }
++        if (term_width < TERM_MIN_WIDTH)
++            term_width = TERM_MIN_WIDTH;
++        if (term_height < TERM_MIN_HEIGHT)
++            term_height = TERM_MIN_HEIGHT;
++
+         //https://www.gnu.org/software/libc/manual/html_node/Argp-User-Customization.html
+         snprintf(tmp, sizeof(tmp), "no-dup-args-note,rmargin=%d", term_width - 1);
+         setenv("ARGP_HELP_FMT", tmp, 1);
+diff --git a/poldek_term.h b/poldek_term.h
+index 80e6d5a6..2b1db740 100644
+--- a/poldek_term.h
++++ b/poldek_term.h
+@@ -25,6 +25,8 @@
+ #define TERM_DEFAULT_WIDTH  80
+ #define TERM_DEFAULT_HEIGHT 24
++#define TERM_MIN_WIDTH      40
++#define TERM_MIN_HEIGHT      4
+ #include <stddef.h>           /* for size_t     */
diff --git a/poldek-global-ignore-merges.patch b/poldek-global-ignore-merges.patch
new file mode 100644 (file)
index 0000000..e7776a7
--- /dev/null
@@ -0,0 +1,193 @@
+commit aea999f2f1cb86579bc8fef9f5393120d12f863b
+Author: Arkadiusz Miśkiewicz <arekm@maven.pl>
+Date:   Wed Apr 22 09:50:32 2026 +0200
+
+    fix: apply [global] + per-source ignore across all pkg paths
+    
+    [global] ignore = ... was silently replaced by any per-source
+    ignore = ... entry rather than extended, so global patterns were
+    lost on every source with its own ignore line. And the stub-index
+    load path (poldek --cmd "ls", search, etc.) bypassed ignore
+    filtering entirely for PKGDIR_CAP_HANDLEIGNORE modules -- that cap
+    only covers the full do_load path, not the separate stub .zst
+    cache loaded by load_stubindex.
+    
+    - lib_init.c: always concat [global] ign_patterns into src's.
+    - lib_pkgset.c: in poldek_load_stubs, post-filter per-source stubs
+      via src->ign_patterns, symmetric with the full-load path and
+      gated by POLDEK_OP_IGNORE.
+    - pkgdir/pkgdir_stubindex.c: source_stubload is now a pure loader;
+      the HANDLEIGNORE guard there was dropping filtering entirely for
+      pndir sources in the stub path.
+
+diff --git a/doc/poldek.conf.xml b/doc/poldek.conf.xml
+index 86cb545b..828bb683 100644
+--- a/doc/poldek.conf.xml
++++ b/doc/poldek.conf.xml
+@@ -395,7 +395,10 @@ and [filename]*-source.conf[/filename], file getters are declared in
+   <option name="ignore" type="string" list="yes" default="vserver-packages" multiple="yes">
+     <description>
+-    Ignore package list - packages fits given mask will be invisible.
++    Ignore package list - packages matching given masks will be invisible.
++    Patterns listed here apply to every [option]source[/option]; any
++    per-source [option]ignore[/option] entry adds more masks on top of this
++    global list rather than replacing it.
+     [screen]
+  ignore = *-smp-* foo*
+  ignore = vserver-packages
+@@ -634,7 +637,9 @@ Every repository is configured in its own [ source ] section.
+   <option name="ignore" type="string" list="yes" default="" multiple="yes">
+     <description>
+-    Have the same meaning as [ global ] parameter. Example:
++    Additional ignore masks for this source, merged with the [ global ]
++    [option]ignore[/option] list (global patterns always apply; per-source
++    entries add more). Example:
+     [screen]
+  ignore = kernel*smp* dev
+     [/screen]
+diff --git a/lib_init.c b/lib_init.c
+index 297ec37e..88684654 100644
+--- a/lib_init.c
++++ b/lib_init.c
+@@ -245,12 +245,11 @@ struct source *do_source_new_htcnf(struct poldek_ctx *ctx,
+                                         (tn_fn_dup)strdup);
+     }
+-    if (n_array_size(src->ign_patterns) == 0 && /* take global  */
+-        n_array_size(ctx->ts->ign_patterns) > 0) {
+-
+-        n_array_free(src->ign_patterns);
+-        src->ign_patterns = n_array_dup(ctx->ts->ign_patterns,
+-                                        (tn_fn_dup)strdup);
++    if (n_array_size(ctx->ts->ign_patterns) > 0) {
++        n_array_concat_ex(src->ign_patterns, ctx->ts->ign_patterns,
++                          (tn_fn_dup)strdup);
++        n_array_sort(src->ign_patterns);
++        n_array_uniq(src->ign_patterns);
+     }
+     return src;
+diff --git a/lib_pkgset.c b/lib_pkgset.c
+index 1b19752e..0b676fc9 100644
+--- a/lib_pkgset.c
++++ b/lib_pkgset.c
+@@ -129,6 +129,7 @@ tn_array *poldek_load_stubs(struct poldek_ctx *ctx)
+     n_array_isort_ex(sources, (tn_fn_cmp)source_cmp_pri);
+     tn_array *stubpkgs = pkgs_array_new(4096);
++    int do_ignore = ctx->ts->getop(ctx->ts, POLDEK_OP_IGNORE);
+     for (i=0; i < n_array_size(sources); i++) {
+         struct source *src = n_array_nth(sources, i);
+@@ -145,6 +146,9 @@ tn_array *poldek_load_stubs(struct poldek_ctx *ctx)
+             return 0;
+         }
++        if (do_ignore && n_array_size(src->ign_patterns) > 0)
++            packages_score_ignore(pkgs, src->ign_patterns, 1);
++
+         while (n_array_size(pkgs) > 0) {
+             struct pkg *pkg = n_array_shift(pkgs);
+diff --git a/pkgdir/pkgdir_stubindex.c b/pkgdir/pkgdir_stubindex.c
+index 7707378b..a7532896 100644
+--- a/pkgdir/pkgdir_stubindex.c
++++ b/pkgdir/pkgdir_stubindex.c
+@@ -204,13 +204,6 @@ tn_array *source_stubload(struct source *src)
+     if (pkgs == NULL)
+         return NULL;
+-    if (src->ign_patterns) {
+-        const struct pkgdir_module *mod = pkgdir_mod_find(src->type);
+-        /* module does not handle "ignore" itself  */
+-        if (mod && (mod->cap_flags & PKGDIR_CAP_HANDLEIGNORE) == 0)
+-            packages_score_ignore(pkgs, src->ign_patterns, 1);
+-    }
+-
+     return pkgs;
+ }
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index 04654c67..ff08ccb9 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -2,7 +2,7 @@ CPPFLAGS = @CPPFLAGS@ @CHECK_CFLAGS@
+ LDADD = $(top_builddir)/libpoldek.la @CHECK_LIBS@
+ check_PROGRAMS = test_match test_env test_pmdb test_op test_config \
+-               test_store test_cmp test_booldeps
++               test_store test_cmp test_booldeps test_ignore_merge
+ TESTS = $(check_PROGRAMS)
+diff --git a/tests/test_ignore_merge.c b/tests/test_ignore_merge.c
+new file mode 100644
+index 00000000..97e061ed
+--- /dev/null
++++ b/tests/test_ignore_merge.c
+@@ -0,0 +1,63 @@
++#include "test.h"
++#include "poldek.h"
++#include "pkgdir/source.h"
++
++static int list_contains(tn_array *list, const char *s)
++{
++    int i;
++    for (i = 0; i < n_array_size(list); i++)
++        if (n_str_eq((const char *)n_array_nth(list, i), s))
++            return 1;
++    return 0;
++}
++
++START_TEST (test_ignore_merge) {
++    const char *path = "poldek_test_ignore_merge.conf";
++    FILE *f = fopen(path, "w");
++    fail_if(f == NULL, "cannot open %s for write", path);
++    fprintf(f,
++            "[global]\n"
++            "ignore = foo* baz*\n"
++            "\n"
++            "[source]\n"
++            "name = testsrc\n"
++            "type = pndir\n"
++            "url  = file:///tmp/poldek-test-nonexistent\n"
++            "ignore = bar*\n");
++    fclose(f);
++
++    poldeklib_init();
++    struct poldek_ctx *ctx = poldek_new(0);
++    fail_if(ctx == NULL, "poldek_new failed");
++    fail_if(poldek_load_config(ctx, path, NULL, 0) == 0,
++            "load_config failed");
++    fail_if(poldek_setup(ctx) == 0, "poldek_setup failed");
++
++    tn_array *sources = poldek_get_sources(ctx);
++    fail_if(sources == NULL, "no sources?");
++
++    struct source *src = NULL;
++    int i;
++    for (i = 0; i < n_array_size(sources); i++) {
++        struct source *s = n_array_nth(sources, i);
++        if (s->name && n_str_eq(s->name, "testsrc")) {
++            src = s;
++            break;
++        }
++    }
++    fail_if(src == NULL, "testsrc not found in sources");
++
++    fail_unless(list_contains(src->ign_patterns, "foo*"),
++                "global 'foo*' missing from merged ign_patterns");
++    fail_unless(list_contains(src->ign_patterns, "baz*"),
++                "global 'baz*' missing from merged ign_patterns");
++    fail_unless(list_contains(src->ign_patterns, "bar*"),
++                "per-source 'bar*' missing from merged ign_patterns");
++
++    n_array_free(sources);
++    poldek_free(ctx);
++    unlink(path);
++}
++END_TEST
++
++NTEST_RUNNER("ignore_merge", test_ignore_merge);
diff --git a/poldek-multilib-bare-name-install.patch b/poldek-multilib-bare-name-install.patch
new file mode 100644 (file)
index 0000000..13d269e
--- /dev/null
@@ -0,0 +1,247 @@
+From 3d5addaec1f408f389f66e3ded712315f734158b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Arkadiusz=20Mi=C5=9Bkiewicz?= <arekm@maven.pl>
+Date: Tue, 14 Apr 2026 13:59:26 +0200
+Subject: [PATCH 1/2] fix: in multilib mode, bare-name install should only
+ install native arch
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Problem: on a multilib system with multiple architecture repos (e.g.
+th, th-i686, th-x86_64), running "install curl" resolves curl from ALL
+architectures and pulls in a massive foreign-arch dependency chain
+(40+ packages). It also emits a misleading "ambiguous name" warning.
+The user only wanted the native-arch package.
+
+Solution: add ARG_PACKAGES_RESOLV_PREFER_NATIVE flag and filter in
+resolve_masks() — the resolution layer where user masks are matched
+to packages. When the flag is set (install path only, not ls/search):
+
+- Bare-name matches (strcmp with pkg->name) skip non-native, non-noarch
+  packages via the multilib_skip_foreign() helper
+- Glob/fnmatch matches are unaffected — "install curl*" installs all
+- Explicit names like "install curl-8.19.0-1.i686" go through fnmatch
+  and are also unaffected
+
+This eliminates the false "ambiguous name" warning (matches_bycmp now
+only counts native-arch matches) and produces a helpful suggestion when
+no native arch exists at all. The no-native-arch case sets rc=0 (fails
+the transaction) like "no such package" does — the user must use an
+explicit name.
+
+The install validation function (poldek_ts_validate_args_with_stubs)
+has no multilib awareness — arch policy lives entirely in the
+resolution layer where it belongs.
+
+Examples:
+  install curl                -> installs only curl.x86_64 (native)
+  install curl-8.19.0-1.i686 -> installs curl.i686 (explicit)
+  install curl*               -> installs all matching arches (glob)
+  ls curl                     -> shows all arches (no PREFER_NATIVE)
+---
+ arg_packages.c | 68 +++++++++++++++++++++++++++++++++++++++++++++-----
+ arg_packages.h |  4 +++
+ 2 files changed, 66 insertions(+), 6 deletions(-)
+
+diff --git a/arg_packages.c b/arg_packages.c
+index 8b2d2cdb..d8def6b9 100644
+--- a/arg_packages.c
++++ b/arg_packages.c
+@@ -457,6 +457,31 @@ tn_array *resolve_bycap(struct arg_packages *aps, struct pkgset *ps,
+     return pkgs;
+ }
++/*
++  multilib: should this package be skipped for a bare-name mask match?
++
++  Problem: "install curl" on a multilib system resolves to curl.x86_64,
++  curl.i686, curl.x32 — pulling in a massive foreign-arch dependency
++  chain.  The user just wanted the native-arch package.
++
++  This only applies to bare-name matches (strcmp with pkg->name).
++  Explicit names ("install curl-1.0-1.i686") and globs ("install curl*")
++  go through the fnmatch path and are not affected.
++
++  Returns true if the package should be skipped:
++  - caller asked for PREFER_NATIVE (install path, not ls/search)
++  - multilib mode is on
++  - package is not noarch (noarch is always installable)
++  - package arch score != 1 (not the native/base architecture)
++*/
++static int multilib_skip_foreign(const struct pkg *pkg, unsigned flags)
++{
++    return (flags & ARG_PACKAGES_RESOLV_PREFER_NATIVE) &&
++           poldek_conf_MULTILIB &&
++           !pkg_is_noarch(pkg) &&
++           pkg_arch_score(pkg) != 1;
++}
++
+ static
+ int resolve_masks(tn_array *re,
+                   struct arg_packages *aps, tn_array *avpkgs,
+@@ -465,6 +490,7 @@ int resolve_masks(tn_array *re,
+ {
+     int i, j, nmasks, rc = 1;
+     int *matches, *matches_bycmp;
++    const char **first_foreign_id;
+     nmasks = n_array_size(aps->package_masks);
+@@ -474,6 +500,12 @@ int resolve_masks(tn_array *re,
+     matches_bycmp = alloca(nmasks * sizeof(*matches_bycmp));
+     memset(matches_bycmp, 0, nmasks * sizeof(*matches_bycmp));
++    /* first_foreign_id[j]: when a bare-name mask skips a foreign-arch
++       package, remember its pkg_id (e.g. "curl-8.19.0-1.i686") so we
++       can suggest it in the warning if no native arch exists at all */
++    first_foreign_id = alloca(nmasks * sizeof(*first_foreign_id));
++    memset(first_foreign_id, 0, nmasks * sizeof(*first_foreign_id));
++
+     for (i=0; i < n_array_size(avpkgs); i++) {
+         struct pkg *pkg = n_array_nth(avpkgs, i);
+@@ -494,11 +526,16 @@ int resolve_masks(tn_array *re,
+             DBGF("%s cmp %s or %s\n", mask, pkg->name, pkg_id(pkg));
+             if (strcmp(mask, pkg->name) == 0) {
+-                if (re)
+-                    n_array_push(re, pkg_link(pkg));
+-
+-                matches_bycmp[j]++;
+-                matches[j]++;
++                if (multilib_skip_foreign(pkg, flags)) {
++                    if (!first_foreign_id[j])
++                        first_foreign_id[j] = pkg_id(pkg);
++                } else {
++                    if (re)
++                        n_array_push(re, pkg_link(pkg));
++
++                    matches_bycmp[j]++;
++                    matches[j]++;
++                }
+             } else if (fnmatch(mask, pkg_id(pkg), 0) == 0) {
+                 if (re)
+@@ -521,6 +558,17 @@ int resolve_masks(tn_array *re,
+             }
+         }
++        /* multilib: bare name matched only foreign-arch packages;
++           fail like "no such package" — the user must be explicit */
++        if (unmatched && first_foreign_id[j]) {
++            if (!quiet)
++                logn(LOGWARN, _("%s: no native arch package available;"
++                     " to install use explicit name, e.g.: %s"),
++                     mask, first_foreign_id[j]);
++            rc = 0;
++            continue;
++        }
++
+         if (unmatched && (flags & ARG_PACKAGES_RESOLV_MISSINGOK) == 0) {
+             if (!quiet)
+                 logn(LOGERR, _("%s: no such package"), mask);
+@@ -698,7 +746,15 @@ int arg_packages__validate_with_stubs(struct arg_packages *aps, tn_array *stubpk
+         re = *resolved;
+     }
+-    if (!resolve_masks(re, aps, stubpkgs, NULL, 0, quiet))
++    /* install path: in multilib mode, bare package names (e.g. "install curl")
++       should resolve only to native-arch packages.  The ls/search path
++       (arg_packages_resolve) does not set this flag, so "ls curl" still
++       shows all architectures. */
++    unsigned resolve_flags = 0;
++    if (poldek_conf_MULTILIB)
++        resolve_flags |= ARG_PACKAGES_RESOLV_PREFER_NATIVE;
++
++    if (!resolve_masks(re, aps, stubpkgs, NULL, resolve_flags, quiet))
+         return 0;
+     if (n_array_size(aps->packages) > 0) {
+diff --git a/arg_packages.h b/arg_packages.h
+index cbeb163a..2de984c4 100644
+--- a/arg_packages.h
++++ b/arg_packages.h
+@@ -50,6 +50,10 @@ EXPORT int arg_packages_setup(struct arg_packages *aps, struct pm_ctx *ctx);
+ #define ARG_PACKAGES_RESOLV_CAPSINLINE  (1 << 4)/* add packages found by caps
+                                                    to resolved packages */
+ #define ARG_PACKAGES_RESOLV_WARN_ONLY   (1 << 5)/* warn only*/
++#define ARG_PACKAGES_RESOLV_PREFER_NATIVE (1 << 6)/* multilib: "install curl"
++                                                      resolves only to native arch;
++                                                      "install curl-1.0-1.i686" and
++                                                      "install curl*" still match all */
+ int arg_packages__validate_with_stubs(struct arg_packages *aps, tn_array *stubpkgs,
+                                       tn_array **resolved, int quiet);
+-- 
+2.53.0
+
+From e924bff4180e6fcba25d8c8d6e12ef5fbe582f52 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Arkadiusz=20Mi=C5=9Bkiewicz?= <arekm@maven.pl>
+Date: Tue, 14 Apr 2026 13:03:34 +0200
+Subject: [PATCH 2/2] test: add multilib bare-name vs explicit arch install
+ tests
+
+Verify that bare-name install picks only native arch, explicit
+name-version.arch installs foreign arch, and glob patterns install
+all matching architectures.
+---
+ tests/sh/07-depsolver | 43 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 43 insertions(+)
+
+diff --git a/tests/sh/07-depsolver b/tests/sh/07-depsolver
+index 5c95e6b0..a4ca2d85 100755
+--- a/tests/sh/07-depsolver
++++ b/tests/sh/07-depsolver
+@@ -965,6 +965,49 @@ xtestUninstallHold() {
+     try_uninstall a "a-1-1,a-devel-1-1"
+ }
++# bare-name install in multilib should only install native arch
++testInstallBareNameMultilibNativeOnly() {
++    ORIG_POLDEK_INSTALL="$POLDEK_INSTALL"
++    POLDEK_INSTALL="$POLDEK_INSTALL -Omultilib=1"
++
++    msgn "Preparing repositories..."
++    build a 1-1 -a x86_64 -f "/hello.x86_64"
++    build a 1-1 -a i686 -f "/hello.i686"
++
++    msgn "Bare-name install should pick only native arch"
++    try_install a "a-1-1.x86_64"
++
++    POLDEK_INSTALL="$ORIG_POLDEK_INSTALL"
++}
++
++# explicit name-version.arch should install that specific arch
++testInstallExplicitArchMultilib() {
++    ORIG_POLDEK_INSTALL="$POLDEK_INSTALL"
++    POLDEK_INSTALL="$POLDEK_INSTALL -Omultilib=1"
++
++    msgn "Preparing repositories..."
++    build a 1-1 -a x86_64 -f "/hello.x86_64"
++    build a 1-1 -a i686 -f "/hello.i686"
++    msgn "Explicit arch should install that specific arch"
++    try_install a-1-1.i686 "a-1-1.i686"
++
++    POLDEK_INSTALL="$ORIG_POLDEK_INSTALL"
++}
++
++# glob pattern should install all matching arches
++testInstallGlobMultilibAllArches() {
++    ORIG_POLDEK_INSTALL="$POLDEK_INSTALL"
++    POLDEK_INSTALL="$POLDEK_INSTALL -Omultilib=1"
++
++    msgn "Preparing repositories..."
++    build a 1-1 -a x86_64 -f "/hello.x86_64"
++    build a 1-1 -a i686 -f "/hello.i686"
++
++    msgn "Glob should install all matching arches"
++    try_install_with_ask_allowed "a*" "a-1-1.x86_64,a-1-1.i686"
++
++    POLDEK_INSTALL="$ORIG_POLDEK_INSTALL"
++}
+ . ./sh/lib/shunit2
+-- 
+2.53.0
+
diff --git a/poldek-nocolor-cmp.patch b/poldek-nocolor-cmp.patch
new file mode 100644 (file)
index 0000000..abfa538
--- /dev/null
@@ -0,0 +1,56 @@
+    fix: do not treat uncolored packages from different architectures as interchangeable
+    
+    -devel packages typically have HEADERCOLOR=0 (no ELF binaries, only
+    headers, symlinks, pkg-config and libtool files). pkg_is_colored_like()
+    was returning 1 ("same kind") whenever at least one package had color 0,
+    causing poldek to incorrectly obsolete e.g. xz-devel.x32 when installing
+    xz-devel.x86_64, even though they install to different paths
+    (/usr/libx32 vs /usr/lib64) and are not interchangeable.
+    
+    The uncolored fallback was changed to a blanket "return 1" in commit
+    dad87fe8 (LP#299685, 2010). The earlier commit 1fd8aa21 (2008) disabled
+    arch-based fallback with the comment "rpm relies on colors only".
+    
+    Regardless of what older RPM versions did, RPM 6.0.1's checkAdded() and
+    rpmtsTeIterator() (lib/depends.cc) use arch string matching as a second
+    layer alongside colors in multilib transactions.
+    
+    Fix pkg_is_colored_like() to fall back to arch comparison when at least
+    one package is uncolored, and remove the redundant "any uncolored"
+    bypass in obs_filter() which was a second path for the same bug.
+
+diff --git a/install3/obsoletes.c b/install3/obsoletes.c
+index c70c04da..d137aeac 100644
+--- a/install3/obsoletes.c
++++ b/install3/obsoletes.c
+@@ -132,10 +132,6 @@ int obs_filter(struct pkgdb *db, const struct pm_dbrec *dbrec, void *apkg)
+     if (pkg_is_colored_like(&dbpkg, pkg))
+         return 1;
+-    /* any uncolored -> rpm allows upgrade */
+-    if (dbpkg.color == 0 || pkg->color == 0)
+-        return 1;
+-
+     return 0;
+ }
+diff --git a/pkgcmp.c b/pkgcmp.c
+index aa8af162..e75ddf5b 100644
+--- a/pkgcmp.c
++++ b/pkgcmp.c
+@@ -80,8 +80,13 @@ int pkg_is_colored_like(const struct pkg *candidate, const struct pkg *pkg)
+     if (pkg->color && candidate->color)
+         return (pkg->color & candidate->color) > 0;
+-    /* either new or old package contains no binary files, let it happen */
+-    return 1;
++    /* When at least one package has no ELF binaries (color 0), fall back
++       to arch comparison. This prevents treating uncolored packages from
++       different architectures (e.g. x32 vs x86_64 -devel packages) as
++       interchangeable. RPM 6.0.1 itself uses arch string matching as a
++       second layer alongside colors (see checkAdded() and
++       rpmtsTeIterator() in rpm's lib/depends.cc). */
++    return pkg_cmp_same_arch(candidate, pkg);
+ }
+ /* ret : 1 if pkg is cappable to upgrade arch<=>arch, arch<=>noarch */
diff --git a/poldek-scoring-evr.patch b/poldek-scoring-evr.patch
new file mode 100644 (file)
index 0000000..f83d6ad
--- /dev/null
@@ -0,0 +1,101 @@
+commit 2d65d2e1063e0f9c7d2196eb9170cd3426192462
+Author: Arkadiusz Miśkiewicz <arekm@maven.pl>
+Date:   Wed Apr 15 21:29:46 2026 +0200
+
+    Break ties between equivalent providers by preferring highest EVR
+    
+    When multiple packages provide the same capability and all score
+    equally on every signal (satisfiability, name-prefix match, arch,
+    conflicts, upgrade), the winner was determined by alphabetical sort
+    order of the package name. This systematically picked the oldest
+    available version — e.g. php4-program over php85-program when 23
+    packages provide /usr/bin/php.
+    
+    Add an EVR (epoch-version-release) comparison as a tiebreaker in
+    do_select_best_pkg(). When two candidates have identical scores,
+    the one with the higher EVR wins. This only fires when all other
+    scoring signals are equal — it never overrides a score-based
+    preference. Version constraints from the requirement are enforced
+    before candidates reach scoring, so the tiebreaker can only choose
+    among packages that already satisfy the requirement.
+    
+    Apply the same tiebreaker in prepare_icap() for the --caplookup
+    path: when no provider is installed, pick highest EVR instead of
+    alphabetically first.
+    
+    Tested on 133 PHP packages and 49 non-PHP packages against a
+    builder-like chroot (base system, no PHP installed):
+    
+    PHP: Before the fix, 44 out of 133 packages pulled in a mix of
+    PHP versions (e.g. php4 + php52 + php53 + php74 simultaneously).
+    After the fix, all 133 resolve to a single consistent version
+    (php85), except 2 packages that depend on extensions only available
+    for old PHP (php-mnogosearch, php-xcache).
+    
+    Java: openjdk8-jre (epoch=1) now selected over icedtea8-jre
+    (no epoch) for ant and maven.
+    
+    Init system: systemd-init (epoch=1) now selected over SysVinit
+    (no epoch) for packages requiring an init daemon.
+
+diff --git a/install3/misc.c b/install3/misc.c
+index b1940972..c6b7c0cb 100644
+--- a/install3/misc.c
++++ b/install3/misc.c
+@@ -370,6 +370,22 @@ static int do_select_best_pkg(int indent, struct i3ctx *ictx,
+         if (sc->score > best_score) {
+             best_score = sc->score;
+             i_best = i;
++        } else if (sc->score == best_score) {
++            /* EVR tiebreaker: when scores are tied, prefer the
++               candidate with the highest epoch-version-release.
++               Without this, the winner is the first candidate in
++               alphabetical name order, which systematically picks
++               the oldest version (e.g. php4-program over
++               php85-program when 23 packages provide /usr/bin/php).
++               This is safe because version constraints are enforced
++               before candidates reach scoring — only packages that
++               satisfy the requirement are considered here.
++               See also prepare_icap() for the --caplookup path. */
++            struct pkg *pbest = n_array_nth(candidates, i_best);
++            struct pkg *pcand = n_array_nth(candidates, i);
++            if (pkg_cmp_evr(pcand, pbest) > 0) {
++                i_best = i;
++            }
+         }
+         if (sc->satscore > best_satscore) {
+diff --git a/install3/preinstall.c b/install3/preinstall.c
+index b237c1b4..1e7e5934 100644
+--- a/install3/preinstall.c
++++ b/install3/preinstall.c
+@@ -90,8 +90,16 @@ int prepare_icap(struct poldek_ts *ts, const char *capname, tn_array *pkgs)
+             }
+         }
+-        if (pkg == NULL)
++        if (pkg == NULL) {
++            /* EVR tiebreaker: pick highest EVR instead of
++               alphabetically first; see also do_select_best_pkg() */
+             pkg = n_array_nth(pkgs, 0);
++            for (i = 1; i < n_array_size(pkgs); i++) {
++                struct pkg *p = n_array_nth(pkgs, i);
++                if (pkg_cmp_evr(p, pkg) > 0)
++                    pkg = p;
++            }
++        }
+         pkg_hand_mark(ts->pms, pkg);
+         return 1;
+diff --git a/pkgcmp.c b/pkgcmp.c
+index e75ddf5b..05fce886 100644
+--- a/pkgcmp.c
++++ b/pkgcmp.c
+@@ -170,7 +170,6 @@ int pkg_cmp_evr(const struct pkg *p1, const struct pkg *p2)
+     return rc;
+ }
+-
+ int pkg_cmp_name_evr(const struct pkg *p1, const struct pkg *p2)
+ {
+     register int rc;
diff --git a/poldek-search-i-opt.patch b/poldek-search-i-opt.patch
new file mode 100644 (file)
index 0000000..c127e45
--- /dev/null
@@ -0,0 +1,138 @@
+diff --git a/cli/search.c b/cli/search.c
+index 4d6f06a..6db2ebc 100644
+--- a/cli/search.c
++++ b/cli/search.c
+@@ -61,6 +61,7 @@ static int                    pcre_established = 0;
+ struct pattern {
+     int              type;
+     char             *regexp;
++    int              ignore_case;
+     int              fnmatch_flags;
+     unsigned         pcre_flags;
+     pcre             *pcre;
+@@ -71,6 +72,7 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state);
+ static int search(struct cmdctx *cmdctx);
+ #define OPT_PATTERN_PCRE     (1 << 10)
++#define OPT_PATTERN_ICASE    (1 << 11)
+ #define OPT_SEARCH_CAP       (1 << 0)
+ #define OPT_SEARCH_REQ       (1 << 1)
+@@ -95,7 +97,7 @@ static int search(struct cmdctx *cmdctx);
+                           OPT_SEARCH_CHANGELOG)
+-#define OPT_NO_SEARCHSW    OPT_PATTERN_PCRE
++#define OPT_NO_SEARCHSW    (OPT_PATTERN_PCRE | OPT_PATTERN_ICASE)
+ static struct argp_option options[] = {
+     { "provides",    'p', 0, 0, N_("Search capabilities"), 1},
+@@ -106,6 +108,7 @@ static struct argp_option options[] = {
+     { "summary",     's', 0, 0, N_("Search summaries, urls and license"), 1},
+     { "description", 'd', 0, 0, N_("Search descriptions"), 1},
+     { "group",       'g', 0, 0, N_("Search groups"), 1 },
++    { "ignore-case", 'i', 0, 0, N_("Ignore case when matching"), 1},
+     { "files",       'f', 0, 0, N_("Search file list"), 1},
+     { NULL,          'l', 0,  OPTION_ALIAS, 0, 1},
+     { "changelog",   'L', 0, 0, N_("Search changelogs"), 1},
+@@ -124,7 +127,10 @@ struct poclidek_cmd command_search = {
+     options, parse_opt,
+     NULL, search,
+     NULL, NULL,
+-    N_("With --perlre pattern must be supplied as:\n"
++    N_("Patterns are matched case-sensitively by default.\n"
++       "Use -i, --ignore-case to ignore case.\n"
++       "\n"
++       "With --perlre pattern must be supplied as:\n"
+        "     <delimiter>perl-regexp<delimiter>[imsx]\n"
+        "  For example to find the packages containing foo.bar do:\n"
+        "     search --perlre /foo\\.bar/\n"
+@@ -204,10 +210,15 @@ static struct pattern *build_pattern(struct cmdctx *cmdctx, char *arg)
+         pt->type = PATTERN_FMASK;
+     pt->regexp = n_strdup(regexp);
++    pt->ignore_case = ((cmdctx->_flags & OPT_PATTERN_ICASE) != 0);
+     pt->fnmatch_flags = 0;
+     pt->pcre_flags = flags;
+     pt->pcre = NULL;
+     pt->pcre_extra = NULL;
++
++    if (pt->ignore_case && pt->type == PATTERN_PCRE)
++        pt->pcre_flags |= PCRE_CASELESS;
++
+     return pt;
+ }
+@@ -237,6 +248,10 @@ error_t parse_opt(int key, char *arg, struct argp_state *state)
+             cmdctx->_flags |= OPT_SEARCH_GROUP;
+             break;
++        case 'i':
++            cmdctx->_flags |= OPT_PATTERN_ICASE;
++            break;
++
+         case 'o':
+             cmdctx->_flags |= OPT_SEARCH_OBSL;
+             break;
+@@ -322,7 +337,13 @@ int pattern_compile(struct pattern *pt, int ntimes)
+     n_assert(pt->pcre_extra == NULL);
+ #ifdef FNM_CASEFOLD
+-    pt->fnmatch_flags |= FNM_CASEFOLD;
++    if (pt->ignore_case)
++        pt->fnmatch_flags |= FNM_CASEFOLD;
++#else
++    if (pt->ignore_case && pt->type == PATTERN_FMASK) {
++        logn(LOGERR, _("search: case-insensitive glob matching is not supported on this platform"));
++        return 0;
++    }
+ #endif
+     if (pt->type != PATTERN_PCRE)
+diff --git a/doc/manual.xml b/doc/manual.xml
+index 9d8923c..6c4fcdc 100644
+--- a/doc/manual.xml
++++ b/doc/manual.xml
+@@ -846,7 +846,9 @@ Syntax of command is:
+ search [OPTION...] PATTERN [PACKAGE...]
+ </screen>
+ Where <emphasis>PATTERN</emphasis> is a glob or, with <option>--perlre</option>, 
+-Perl regular expression.  
++Perl regular expression. Matching is case-sensitive by default; use
++<option>-i</option>, <option>--ignore-case</option> for case-insensitive
++matching.
+ For instance to find the packages that contains <filename>/usr/sbin/ab</filename> file:
+ <screen>
+diff --git a/doc/poldek.1 b/doc/poldek.1
+index fd7982e..273e100 100644
+--- a/doc/poldek.1
++++ b/doc/poldek.1
+@@ -51,6 +51,12 @@ is a full\-featured packages management utility, basically designed to work with
+ This manual page covers command line option reference, the full documentation for poldek is available as a Texinfo manual\&. Do
+ \fBinfo poldek\fR
+ to get it\&.
++.PP
++In shell mode, the
++\fBsearch\fR
++command matches case\-sensitively by default; use
++\fBsearch \-i\fR
++for case\-insensitive matching\&.
+ .SH "OPTIONS REFERENCE"
+ .SS "Repository index creation"
+ .PP
+diff --git a/doc/poldek.1.xml b/doc/poldek.1.xml
+index e1a923a..a7eeff1 100644
+--- a/doc/poldek.1.xml
++++ b/doc/poldek.1.xml
+@@ -44,6 +44,10 @@ tasks like installation, upgrading or removal.
+ <para>
+ This manual page covers command line option reference, the full documentation
+ for poldek is available as a Texinfo manual. Do <command>info poldek</command> to get it.
++</para>
++<para>
++In shell mode, the <command>search</command> command matches case-sensitively
++by default; use <command>search -i</command> for case-insensitive matching.
+ </para>
+   </refsect1>
index 90da7d1b8229040cea8aa2f02d4a4d6533ce9cee..c0c07910b6b1f52bc2f78d8d286d524fff067031 100644 (file)
@@ -8,7 +8,6 @@
 %bcond_with    python  # don't build python bindings
 %bcond_with    tests   # tests
 
 %bcond_with    python  # don't build python bindings
 %bcond_with    tests   # tests
 
-# required versions (forced to avoid SEGV with mixed db used by rpm and poldek)
 %define                ver_rpm         1:4.14
 
 %define                rel     12
 %define                ver_rpm         1:4.14
 
 %define                rel     12
@@ -16,13 +15,13 @@ Summary:    RPM packages management helper tool
 Summary(hu.UTF-8):     RPM csomagkezelést segítő eszköz
 Summary(pl.UTF-8):     Pomocnicze narzędzie do zarządzania pakietami RPM
 Name:          poldek
 Summary(hu.UTF-8):     RPM csomagkezelést segítő eszköz
 Summary(pl.UTF-8):     Pomocnicze narzędzie do zarządzania pakietami RPM
 Name:          poldek
-Version:       0.44.0
+Version:       0.45.0
 Release:       %{rel}
 License:       GPL v2
 Group:         Applications/System
 #Source0:      http://poldek.pld-linux.org/download/snapshots/%{name}-%{version}-cvs%{snap}.tar.bz2
 Source0:       https://github.com/poldek-pm/poldek/releases/download/v%{version}/%{name}-%{version}.tar.xz
 Release:       %{rel}
 License:       GPL v2
 Group:         Applications/System
 #Source0:      http://poldek.pld-linux.org/download/snapshots/%{name}-%{version}-cvs%{snap}.tar.bz2
 Source0:       https://github.com/poldek-pm/poldek/releases/download/v%{version}/%{name}-%{version}.tar.xz
-# Source0-md5: cd0eab5e6fe2ac6995c03541506561fc
+# Source0-md5: 445033ef4d1312718d27b4b7fc197643
 Source1:       tld.conf
 Source2:       tld-multilib.conf
 Source3:       tld-debuginfo.conf
 Source1:       tld.conf
 Source2:       tld-multilib.conf
 Source3:       tld-debuginfo.conf
@@ -34,13 +33,13 @@ Source7:    %{name}.png
 Patch0:                %{name}-config.patch
 Patch1:                pm-hooks.patch
 Patch2:                %{name}-ext-down-enable.patch
 Patch0:                %{name}-config.patch
 Patch1:                pm-hooks.patch
 Patch2:                %{name}-ext-down-enable.patch
-Patch3:                fix-reinstall-sigsev.patch
-Patch4:                restore-verify-all.patch
-Patch5:                proxy-fix.patch
-Patch6:                verify-fix.patch
-Patch7:                linguas.patch
-Patch8:                pkgiter-preun-req-skip.patch
-Patch9:                gcc15.patch
+Patch3:                %{name}-search-i-opt.patch
+Patch4:                %{name}-nocolor-cmp.patch
+Patch5:                %{name}-multilib-bare-name-install.patch
+Patch6:                %{name}-dup-sources.patch
+Patch7:                %{name}-env-columns-lines.patch
+Patch8:                %{name}-scoring-evr.patch
+Patch9:                %{name}-global-ignore-merges.patch
 URL:           http://poldek.pld-linux.org/
 BuildRequires: autoconf >= 2.63
 BuildRequires: automake >= 1:1.11
 URL:           http://poldek.pld-linux.org/
 BuildRequires: autoconf >= 2.63
 BuildRequires: automake >= 1:1.11
@@ -207,16 +206,16 @@ Moduły języka Python dla poldka.
 
 %prep
 %setup -q
 
 %prep
 %setup -q
-%patch -P 0 -p1
-%patch -P 1 -p1
-%patch -P 2 -p1
-%patch -P 3 -p1
-%patch -P 4 -p1
-%patch -P 5 -p1
-%patch -P 6 -p1
-%patch -P 7 -p1
-%patch -P 8 -p1
-%patch -P 9 -p1
+%patch -P0 -p1
+%patch -P1 -p1
+%patch -P2 -p1
+%patch -P3 -p1
+%patch -P4 -p1
+%patch -P5 -p1
+%patch -P6 -p1
+%patch -P7 -p1
+%patch -P8 -p1
+%patch -P9 -p1
 
 %{__rm} doc/poldek.info
 %{__rm} m4/libtool.m4 m4/lt*.m4
 
 %{__rm} doc/poldek.info
 %{__rm} m4/libtool.m4 m4/lt*.m4
@@ -315,7 +314,7 @@ cp -p %{SOURCE7} $RPM_BUILD_ROOT%{_pixmapsdir}/%{name}.png
 %endif
 
 # sources we don't package
 %endif
 
 # sources we don't package
-%{__rm} $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/{rh,fedora,centos}-source.conf
+%{__rm} $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/{repos.d/pld.conf,{rh,fedora,centos}-source.conf}
 # include them in %doc
 %{__rm} -rf configs
 cp -a conf configs
 # include them in %doc
 %{__rm} -rf configs
 cp -a conf configs
@@ -405,7 +404,7 @@ fi
 %attr(755,root,root) %ghost %{_libdir}/libpoclidek.so.2
 %attr(755,root,root) %ghost %{_libdir}/libpoldek.so.4
 %attr(755,root,root) %ghost %{_libdir}/libtndb.so.0
 %attr(755,root,root) %ghost %{_libdir}/libpoclidek.so.2
 %attr(755,root,root) %ghost %{_libdir}/libpoldek.so.4
 %attr(755,root,root) %ghost %{_libdir}/libtndb.so.0
-%attr(755,root,root) %ghost %{_libdir}/libtrurl.so.1
+%attr(755,root,root) %ghost %{_libdir}/libtrurl.so.10
 %attr(755,root,root) %ghost %{_libdir}/libvfile.so.0
 %endif
 
 %attr(755,root,root) %ghost %{_libdir}/libvfile.so.0
 %endif
 
diff --git a/proxy-fix.patch b/proxy-fix.patch
deleted file mode 100644 (file)
index 06aeb7c..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-commit ab4f31ec7afa21d7a769ad6ceb5ec176667191b2
-Author: mis <mistoo@gmail.com>
-Date:   Sat Mar 1 20:02:11 2025 +0100
-
-    fix: do not check http connection with 'HEAD /' when proxied
-
-diff --git a/vfile/vfff/http.c b/vfile/vfff/http.c
-index 92effa2..fa0fc74 100644
---- a/vfile/vfff/http.c
-+++ b/vfile/vfff/http.c
-@@ -790,27 +790,6 @@ static time_t parse_date(const char *dt)
-     return ts;
- }
--static
--int vhttp_vcn_is_alive(struct vcn *cn)
--{
--    char req_line[256];
--
--    if (cn->state != VCN_ALIVE)
--        return 0;
--
--    make_req_line(req_line, sizeof(req_line), "HEAD", "/");
--
--    if (!httpcn_req(cn, req_line, NULL))
--        return 0;
--
--    if (!httpcn_get_resp(cn)) {
--        cn->state = VCN_DEAD;
--        return 0;
--    }
--
--    return 1;
--}
--
- static int is_closing_connection_status(struct http_resp *resp)
- {
-     int close_cn = 0;
-@@ -836,6 +815,34 @@ static int is_closing_connection_status(struct http_resp *resp)
-     return close_cn;
- }
-+static int vhttp_vcn_is_alive(struct vcn *cn)
-+{
-+    char req_line[256];
-+
-+    if (cn->state != VCN_ALIVE)
-+        return 0;
-+
-+    if (cn->flags & VCN_PROXIED)
-+        return 0;
-+
-+    make_req_line(req_line, sizeof(req_line), "HEAD", "/");
-+
-+    if (!httpcn_req(cn, req_line, NULL))
-+        return 0;
-+
-+    if (!httpcn_get_resp(cn)) {
-+        cn->state = VCN_DEAD;
-+        return 0;
-+    }
-+
-+    if (is_closing_connection_status(cn->resp)) {
-+        cn->state = VCN_DEAD;
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
- static
- int is_redirected_connection(struct http_resp *resp, struct vfff_req *rreq)
- {
-diff --git a/vfile/vfff/vfff.c b/vfile/vfff/vfff.c
-index f745ec1..cd014f9 100644
---- a/vfile/vfff/vfff.c
-+++ b/vfile/vfff/vfff.c
-@@ -436,5 +436,10 @@ int vfff_transfer_file(struct vcn *cn, struct vfff_req *vreq, long total_size)
-     if (vreq->progress_fn)
-         vreq->progress_fn(vreq->progress_fn_data, total_size, -1);
--    return is_err == 0;
-+    if (is_err == 0 && cn->state == VCN_ALIVE) {
-+        cn->ts_is_alive = time(0); /* update alive timestamp on success */
-+        return 1;
-+    }
-+
-+    return 0;
- }
-diff --git a/vfile/vfff/vfff.h b/vfile/vfff/vfff.h
-index 22665b0..4f448de 100644
---- a/vfile/vfff/vfff.h
-+++ b/vfile/vfff/vfff.h
-@@ -60,6 +60,7 @@ struct vfff_req;
- /* flags */
- #define VCN_SUPPORTS_SIZE  (1 << 0)
- #define VCN_SUPPORTS_MDTM  (1 << 1)
-+#define VCN_PROXIED        (1 << 9)
- struct vcn {
-     int       proto;
-diff --git a/vfile/vfffmod.c b/vfile/vfffmod.c
-index 98f828d..c6a8503 100644
---- a/vfile/vfffmod.c
-+++ b/vfile/vfffmod.c
-@@ -202,8 +202,12 @@ static struct vcn *vcn_pool_do_connect(struct vf_request *req)
-     if (cn == NULL) {
-         cn = vcn_new(vcn_proto, host, port, login, passwd,
-                      req->proxy_login, req->proxy_passwd);
--        if (cn)
-+        if (cn) {
-+            if (req->proxy_host)
-+                cn->flags |= VCN_PROXIED;
-+
-             n_list_push(vcn_pool, cn);
-+        }
-     }
-     return cn;
diff --git a/restore-verify-all.patch b/restore-verify-all.patch
deleted file mode 100644 (file)
index 2779e06..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-diff --git a/arg_packages.c b/arg_packages.c
-index 48499a9..fab7618 100644
---- a/arg_packages.c
-+++ b/arg_packages.c
-@@ -350,6 +350,11 @@ int arg_packages_add_pkg(struct arg_packages *aps, struct pkg *pkg)
-     return 1;
- }
-+int arg_packages_add_pkgs(struct arg_packages *aps, const tn_array *pkgs)
-+{
-+    n_array_concat_ex(aps->packages, pkgs, (tn_fn_dup)pkg_link);
-+    return 1;
-+}
- static
- int arg_packages_load_list(struct arg_packages *aps, const char *fpath)
-diff --git a/arg_packages.h b/arg_packages.h
-index 611111a..13e8ba2 100644
---- a/arg_packages.h
-+++ b/arg_packages.h
-@@ -38,7 +38,7 @@ EXPORT int arg_packages_add_pkgmaska(struct arg_packages *aps, tn_array *masks);
- EXPORT int arg_packages_add_pkgfile(struct arg_packages *aps, const char *pathname);
- EXPORT int arg_packages_add_pkglist(struct arg_packages *aps, const char *path);
- EXPORT int arg_packages_add_pkg(struct arg_packages *aps, struct pkg *pkg);
--EXPORT int arg_packages_add_pkga(struct arg_packages *aps, tn_array *pkgs);
-+EXPORT int arg_packages_add_pkgs(struct arg_packages *aps, const tn_array *pkgs);
- EXPORT int arg_packages_setup(struct arg_packages *aps, struct pm_ctx *ctx);
-diff --git a/poldek_ts.c b/poldek_ts.c
-index 5185f55..398aafd 100644
---- a/poldek_ts.c
-+++ b/poldek_ts.c
-@@ -943,44 +943,31 @@ static int ts_run_uninstall(struct poldek_ts *ts)
- /* just verify deps, conflicts, ordering, etc */
- static int ts_run_verify(struct poldek_ts *ts)
- {
--    int nerr = 0, rc = 1;
-+    int nerr = 0;
-     //n_assert(poldek_ts_issetf(ts, POLDEK_TS_VERIFY));
--    if (poldek_ts_get_arg_count(ts) == 0) {
--        logn(LOGERR, _("Nothing to do"));
-+    if (!ts_prerun(ts))
-         return 0;
--        // XXX disabled feature of whole set verification, does anybody needs that?
--        //load_sources(ts->ctx);
--
--    } else {
--        if (!ts_prerun(ts))
--            return 0;
--        if (!load_sources(ts->ctx))
--            return 0;
--
--        unsigned flags = TS_MARK_DEPS | TS_MARK_VERBOSE | TS_MARK_CAPSINLINE;
--        rc = ts_mark_arg_packages(ts, flags);
--        (void)rc;               /* XXX unused for now */
--    }
-+    if (!load_sources(ts->ctx))
-+        return 0;
--    /* XXX disabled feature of whole set verification
--    if (poldek_ts_get_arg_count(ts) > 0) {
--        pkgs = pkgmark_get_packages(ts->pms, PKGMARK_MARK | PKGMARK_DEP);
-+    unsigned flags = TS_MARK_DEPS | TS_MARK_CAPSINLINE;
-+    if (poldek_ts_get_arg_count(ts) == 0) { /* no args */
-+        arg_packages_add_pkgs(ts->aps, ts->ctx->ps->pkgs);
-     } else {
--        pkgs = n_ref(ts->ctx->ps->pkgs);
-+        flags |= TS_MARK_VERBOSE;
-     }
--    if (pkgs == NULL)
--        return 0;
--    */
-+    ts_mark_arg_packages(ts, flags);
-     tn_array *pkgs = pkgmark_get_packages(ts->pms, PKGMARK_ANY);
-     if (pkgs == NULL)
-         return 0;
-+    /* just print errors here, deps are already verified by ts_mark_arg_packages */
-     if (ts->getop(ts, POLDEK_OP_VRFY_DEPS)) {
-         msgn(3, _("Verifying dependencies..."));
-         if (pkgmark_log_unsatisfied_dependecies(ts->pms) > 0)
diff --git a/verify-fix.patch b/verify-fix.patch
deleted file mode 100644 (file)
index 7951b1a..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-diff --git a/trurlib/include/trurl/nhash.h b/trurlib/include/trurl/nhash.h
-index e03fa9c..3ffe267 100644
---- a/trurlib/include/trurl/nhash.h
-+++ b/trurlib/include/trurl/nhash.h
-@@ -104,6 +104,7 @@ uint32_t n_hash_compute_index_hash(const tn_hash *ht, uint32_t raw_hash);
- struct trurl_hash_iterator {
-     tn_hash *ht;
-     int pos;
-+    int bpos;
- };
- typedef struct trurl_hash_iterator tn_hash_it;
-diff --git a/trurlib/n_hash_get.c b/trurlib/n_hash_get.c
-index 81c612b..48f0897 100644
---- a/trurlib/n_hash_get.c
-+++ b/trurlib/n_hash_get.c
-@@ -8,21 +8,39 @@ void n_hash_it_init(tn_hash_it *hi, tn_hash *ht)
- {
-     hi->ht = ht;
-     hi->pos = 0;
-+    hi->bpos = 0;
- }
- void *n_hash_it_get(tn_hash_it *hi, const char **key) {
-     struct hash_bucket **tbl = hi->ht->table;
-     size_t i = hi->pos;
--    while (tbl[i] == NULL && i < hi->ht->size)
-+    while (i < hi->ht->size && tbl[i] == NULL)
-         i++;
-     if (i >= hi->ht->size)
-         return NULL;
--    struct hash_bucket *ptr = tbl[i];
-+    struct hash_bucket *ptr;
-+    int j = 0;
-+
-+    ptr = tbl[i];
-+    while (ptr != NULL) {
-+        if (j == hi->bpos)
-+            break;
-+        ptr = ptr->next;
-+        j++;
-+    }
-+
-+    n_assert(ptr);
-+
-+    if (ptr->next == NULL) {
-+        hi->pos = i + 1;
-+        hi->bpos = 0;
-+    } else {
-+        hi->bpos++;
-+    }
--    hi->pos = i + 1;
-     if (key)
-         *key = ptr->key;
-diff --git a/pkgmark.c b/pkgmark.c
-index 84ea6f4..9845bce 100644
---- a/pkgmark.c
-+++ b/pkgmark.c
-@@ -351,8 +351,9 @@ void pkgmark_massset(struct pkgmark_set *pms, int set, uint32_t flag)
-         return;
-     tn_hash_it it;
--    struct pkg_mark *m;
-+    n_hash_it_init(&it, pms->ht);
-+    struct pkg_mark *m;
-     while ((m = n_hash_it_get(&it, NULL)) != NULL) {
-         if (set)
-             m->flags |= flag;
-diff --git a/cli/dent.c b/cli/dent.c
-index b24a723..f4cd4bb 100644
---- a/cli/dent.c
-+++ b/cli/dent.c
-@@ -36,13 +36,14 @@ struct pkg_dent *pkg_dent_new(struct poclidek_ctx *cctx, const char *name,
-                               struct pkg *pkg, int flags, const char *dirpath)
- {
-     struct pkg_dent *ent;
--    int dirpath_at = 0, dirpath_len = 0, len = 0;
-+    int name_len = 0, dirpath_at = 0, dirpath_len = 0, len = 0;
-     if (name) {
-         while (*name == '/')
-             name++;
--        len += strlen(name) + 1;
-+        name_len = strlen(name);
-+        len += name_len + 1;
-         n_assert(flags & PKG_DENT_DIR);
-         n_assert(dirpath);
-@@ -60,7 +61,7 @@ struct pkg_dent *pkg_dent_new(struct poclidek_ctx *cctx, const char *name,
-     if (name) {
-         char *p;
--        memcpy(ent->_buf, name, len);
-+        memcpy(ent->_buf, name, name_len + 1);
-         ent->name = ent->_buf;
-         if (dirpath) {
-diff --git a/cli/ls.c b/cli/ls.c
-index 0027ee0..e2bc01d 100644
---- a/cli/ls.c
-+++ b/cli/ls.c
-@@ -585,9 +585,10 @@ int do_ls(const tn_array *ents, struct cmdctx *cmdctx, const tn_array *evrs)
-             cmdctx_printf(cmdctx, "%-*s %-*s\n",
-                         term_width_div2 + term_width_div2/10 - 1, pkg_name,
-                         (term_width/7), group ? group : "(unset)");
--      }
--        else if (flags & OPT_LS_SOURCERPM) {
--            const char *srcrpm = pkg_srcfilename_s(pkg);
-+      } else if (flags & OPT_LS_SOURCERPM) {
-+            char buf[512];
-+            const char *srcrpm = pkg_srcfilename(pkg, buf, sizeof(buf));
-+
-             cmdctx_printf(cmdctx, "%-*s %-*s\n",
-                         term_width_div2 + term_width_div2/10 - 1, pkg_name,
-                         (term_width/7), srcrpm ? srcrpm : "(unset)");
-diff --git a/vfile/vfile.h b/vfile/vfile.h
-index 3b55b00..b1612f2 100644
---- a/vfile/vfile.h
-+++ b/vfile/vfile.h
-@@ -174,11 +174,11 @@ EXPORT int vf_url_as_path(char *buf, size_t size, const char *url);
- /* replace password with "x" * len(password) */
- EXPORT const char *vf_url_hidepasswd(char *buf, int size, const char *url);
--#define vf_url_hidepasswd_s(url) vf_url_hidepasswd(alloca(PATH_MAX), PATH_MAX, url)
-+#define vf_url_hidepasswd_s(url) vf_url_hidepasswd(alloca(256), 256, url)
- /* applies vf_url_hidepasswd() + slim down url string to maxl */
- EXPORT const char *vf_url_slim(char *buf, int size, const char *url, int maxl);
--#define vf_url_slim_s(url, maxl) vf_url_slim(alloca(PATH_MAX), PATH_MAX, url, (maxl) > 40 ? (maxl) : 40)
-+#define vf_url_slim_s(url, maxl) vf_url_slim(alloca(256), 256, url, (maxl) > 40 ? (maxl) : 40)
- EXPORT char *vf_url_unescape(const char *url);
-diff --git a/pkg.h b/pkg.h
-index 15a68c4..59f3e84 100644
---- a/pkg.h
-+++ b/pkg.h
-@@ -223,14 +223,14 @@ EXPORT int pkg_has_pkgcnfl(struct pkg *pkg, struct pkg *cpkg);
- /* src.rpm */
- EXPORT char *pkg_srcfilename(const struct pkg *pkg, char *buf, size_t size);
--#define pkg_srcfilename_s(pkg) pkg_srcfilename(pkg, alloca(512), 512)
-+#define pkg_srcfilename_s(pkg) pkg_srcfilename(pkg, alloca(256), 256)
- /* RET %path/%name-%version-%release.%arch.rpm  */
- EXPORT char *pkg_filename(const struct pkg *pkg, char *buf, size_t size);
--#define pkg_filename_s(pkg) pkg_filename(pkg, alloca(512), 512)
-+#define pkg_filename_s(pkg) pkg_filename(pkg, alloca(256), 256)
- EXPORT char *pkg_path(const struct pkg *pkg, char *buf, size_t size);
--#define pkg_path_s(pkg) pkg_path(pkg, alloca(512), 512)
-+#define pkg_path_s(pkg) pkg_path(pkg, alloca(256), 256)
- EXPORT char *pkg_localpath(const struct pkg *pkg, char *path, size_t size,
-                     const char *cachedir);
-@@ -251,13 +251,13 @@ EXPORT int pkg_printf(const struct pkg *pkg, const char *str);
- EXPORT int pkg_snprintf(char *str, size_t size, const struct pkg *pkg);
- EXPORT char *pkg_str(char *str, size_t size, const struct pkg *pkg);
--#define pkg_snprintf_s(pkg) pkg_str(alloca(512), 512, pkg)
--#define pkg_snprintf_s0(pkg) pkg_str(alloca(512), 512, pkg)
--#define pkg_snprintf_s1(pkg) pkg_str(alloca(512), 512, pkg)
-+#define pkg_snprintf_s(pkg) pkg_str(alloca(256), 256, pkg)
-+#define pkg_snprintf_s0(pkg) pkg_str(alloca(256), 256, pkg)
-+#define pkg_snprintf_s1(pkg) pkg_str(alloca(256), 256, pkg)
- EXPORT int pkg_evr_snprintf(char *str, size_t size, const struct pkg *pkg);
- EXPORT char *pkg_evr_str(char *str, size_t size, const struct pkg *pkg);
--#define pkg_evr_snprintf_s(pkg) pkg_evr_str(alloca(512), 512, pkg)
-+#define pkg_evr_snprintf_s(pkg) pkg_evr_str(alloca(256), 256, pkg)
- /* must be free()d by pkguinf_free(); see pkgu.h */
- EXPORT struct pkguinf *pkg_uinf(const struct pkg *pkg);
-diff --git a/pkgdir/pkg_restore.c b/pkgdir/pkg_restore.c
-index e7e9373..8dfb4c9 100644
---- a/pkgdir/pkg_restore.c
-+++ b/pkgdir/pkg_restore.c
-@@ -202,9 +202,9 @@ struct pkg *pkg_restore_st(tn_stream *st, tn_alloc *na, struct pkg *pkg,
-     int                  tag, last_tag, tag_binsize = PKG_STORETAG_SIZENIL;
-     const  char          *errmg_double_tag = "%s:%lu: double '%c' tag";
-     const  char          *errmg_ldtag = "%s:%lu: load '%c' tag error";
-+    int                  load_full_fl = (ldflags & PKGDIR_LD_FULLFLIST);
- #if 0
--    printf("FULL %d\n", (ldflags & PKGDIR_LD_FULLFLIST));
-     if (depdirs) {
-         int i;
-         printf("depdirs %p %d\n", depdirs, n_array_size(depdirs));
-@@ -387,13 +387,13 @@ struct pkg *pkg_restore_st(tn_stream *st, tn_alloc *na, struct pkg *pkg,
-             case PKG_STORETAG_FL:
-                 pkgt.nodep_files_offs = n_stream_tell(st);
--                //printf("flag_fullflist %d, %p\n", flag_fullflist, depdirs);
--                if ((ldflags & PKGDIR_LD_FULLFLIST) == 0 && depdirs == NULL) {
-+                if (!load_full_fl && depdirs == NULL) {
-                     pkgfl_skip_st(st);
-                 } else {
-                     tn_tuple *fl;
--                    if (pkgfl_restore_st(na, &fl, st, depdirs, 1) < 0) {
-+
-+                    if (pkgfl_restore_st(na, &fl, st, load_full_fl ? NULL : depdirs, 1) < 0) {
-                         logn(LOGERR, errmg_ldtag, fn, ul_offs, *line);
-                         nerr++;
-                         goto l_end;
-@@ -422,6 +422,10 @@ struct pkg *pkg_restore_st(tn_stream *st, tn_alloc *na, struct pkg *pkg,
-                         pkgt.pkgfl = ffl;
-                     }
-+
-+                    pkgt.flags |= PKGT_HAS_FILES;
-+                    if (load_full_fl)
-+                        pkgt.flags |= PKGT_HAS_ALLFILES;
-                 }
-                 break;