> On Apr 13, 2018, at 3:49 AM, Aleksei Nikiforov <darktemp...@altlinux.org> 
> wrote:
> 
> ---
> lib/depends.c        | 23 +++++++++++++++++------
> lib/rpmte.c          | 28 +++++++++++++++++++++++++---
> lib/rpmte_internal.h |  3 ++-
> lib/rpmts.h          | 30 ++++++++++++++++++++++++++++++
> lib/verify.c         |  2 +-
> 5 files changed, 75 insertions(+), 11 deletions(-)
> 

So instead of just a single char value saved and added, you are using a header 
as a tag bag to be appended. I suppose that is progress, but it's all kinda 
gross overkill for tags that rpm itself neither needs nor uses.

Instead of drilling an additional argument throughout the rpmte API, the 2 new 
top level *WithTags() routines can just do the headerLink() into the rpmte 
object.

> diff --git a/lib/depends.c b/lib/depends.c
> index fc413a9..60282d0 100644
> --- a/lib/depends.c
> +++ b/lib/depends.c
> @@ -123,7 +123,7 @@ static int removePackage(rpmts ts, Header h, rpmte 
> depends)
>    return 0;
>     }
> 
> -    p = rpmteNew(ts, h, TR_REMOVED, NULL, NULL);
> +    p = rpmteNew(ts, h, TR_REMOVED, NULL, NULL, NULL);
>     if (p == NULL)
>    return 1;
> 
> @@ -410,7 +410,7 @@ rpmal rpmtsCreateAl(rpmts ts, rpmElementTypes types)
> }
> 
> static int addPackage(rpmts ts, Header h,
> -            fnpyKey key, int op, rpmRelocation * relocs)
> +            fnpyKey key, int op, rpmRelocation * relocs, Header tags)
> {
>     tsMembers tsmem = rpmtsMembers(ts);
>     rpm_color_t tscolor = rpmtsColor(ts);
> @@ -435,7 +435,7 @@ static int addPackage(rpmts ts, Header h,
>        goto exit;
>     }
> 
> -    p = rpmteNew(ts, h, TR_ADDED, key, relocs);
> +    p = rpmteNew(ts, h, TR_ADDED, key, relocs, tags);
>     if (p == NULL) {
>    ec = 1;
>    goto exit;
> @@ -487,19 +487,30 @@ exit:
> int rpmtsAddInstallElement(rpmts ts, Header h,
>            fnpyKey key, int upgrade, rpmRelocation * relocs)
> {
> +    return rpmtsAddInstallElementWithTags(ts, h, key, upgrade, relocs, NULL);
> +}
> +
> +int rpmtsAddReinstallElement(rpmts ts, Header h, fnpyKey key)
> +{
> +    return rpmtsAddReinstallElementWithTags(ts, h, key, NULL);
> +}
> +
> +int rpmtsAddInstallElementWithTags(rpmts ts, Header h,
> +    fnpyKey key, int upgrade, rpmRelocation * relocs, Header tags)
> +{
>     int op = (upgrade == 0) ? RPMTE_INSTALL : RPMTE_UPGRADE;
>     if (rpmtsSetupTransactionPlugins(ts) == RPMRC_FAIL)
>    return 1;
> -    return addPackage(ts, h, key, op, relocs);
> +    return addPackage(ts, h, key, op, relocs, tags);
> }
> 
> -int rpmtsAddReinstallElement(rpmts ts, Header h, fnpyKey key)
> +int rpmtsAddReinstallElementWithTags(rpmts ts, Header h, fnpyKey key, Header 
> tags)
> {
>     if (rpmtsSetupTransactionPlugins(ts) == RPMRC_FAIL)
>    return 1;
>     /* TODO: pull relocations from installed package */
>     /* TODO: should reinstall of non-installed package fail? */
> -    return addPackage(ts, h, key, RPMTE_REINSTALL, NULL);
> +    return addPackage(ts, h, key, RPMTE_REINSTALL, NULL, tags);
> }
> 
> int rpmtsAddEraseElement(rpmts ts, Header h, int dboffset)
> diff --git a/lib/rpmte.c b/lib/rpmte.c
> index f05c2e2..3ed9f48 100644
> --- a/lib/rpmte.c
> +++ b/lib/rpmte.c
> @@ -77,6 +77,8 @@ struct rpmte_s {
>     int transscripts;        /*!< pre/posttrans script existence */
>     int failed;            /*!< (parent) install/erase failed */
> 
> +    Header extra_tags;        /*! extra tags to be saved */
> +
>     rpmfs fs;
> };
> 
> @@ -122,8 +124,9 @@ static rpmfiles getFiles(rpmte p, Header h)
>  * @param h        header
>  * @param key        (TR_ADDED) package retrieval key (e.g. file name)
>  * @param relocs    (TR_ADDED) package file relocations
> + * @param tags        additional tags to be saved
>  */
> -static int addTE(rpmte p, Header h, fnpyKey key, rpmRelocation * relocs)
> +static int addTE(rpmte p, Header h, fnpyKey key, rpmRelocation * relocs, 
> Header tags)
> {
>     rpmstrPool tspool = rpmtsPool(p->ts);
>     struct rpmtd_s bnames;
> @@ -197,6 +200,8 @@ static int addTE(rpmte p, Header h, fnpyKey key, 
> rpmRelocation * relocs)
>     if (p->type == TR_ADDED)
>    p->pkgFileSize = headerGetNumber(h, RPMTAG_LONGSIGSIZE) + 96 + 256;
> 
> +    p->extra_tags = headerLink(tags);
> +
>     rc = 0;
> 
> exit:
> @@ -224,6 +229,7 @@ rpmte rpmteFree(rpmte te)
>    free(te->NEVR);
>    free(te->NEVRA);
> 
> +    headerFree(te->extra_tags);
>    fdFree(te->fd);
>    rpmfiFree(te->fi);
>    rpmfilesFree(te->files);
> @@ -239,13 +245,13 @@ rpmte rpmteFree(rpmte te)
> }
> 
> rpmte rpmteNew(rpmts ts, Header h, rpmElementType type, fnpyKey key,
> -           rpmRelocation * relocs)
> +           rpmRelocation * relocs, Header tags)
> {
>     rpmte p = xcalloc(1, sizeof(*p));
>     p->ts = ts;
>     p->type = type;
> 
> -    if (addTE(p, h, key, relocs)) {
> +    if (addTE(p, h, key, relocs, tags)) {
>    rpmteFree(p);
>    return NULL;
>     }
> @@ -564,6 +570,9 @@ static int rpmteOpen(rpmte te, int reload_fi)
> {
>     int rc = 0; /* assume failure */
>     Header h = NULL;
> +    HeaderIterator h_iter;
> +    struct rpmtd_s td;
> +
>     if (te == NULL || te->ts == NULL || rpmteFailed(te))
>    goto exit;
> 
> @@ -586,6 +595,19 @@ static int rpmteOpen(rpmte te, int reload_fi)
>        rc = 1;
>    }
>    
> +    if (te->extra_tags != NULL)
> +    {
> +        h_iter = headerInitIterator(te->extra_tags);
> +
> +        while (headerNext(h_iter, &td))
> +        {
> +            headerPut(h, &td, HEADERPUT_DEFAULT);
> +            rpmtdFreeData(&td);
> +        }

There need to be (at least) checks on type and tagno, as well as limiting the 
merge so that existing tags are not just blindly replaced.

Headers with immutable regions are more complicated than "tag bags".

> +
> +        headerFreeIterator(h_iter);
> +    }
> +
>    rpmteSetHeader(te, h);
>    headerFree(h);
>     }
> diff --git a/lib/rpmte_internal.h b/lib/rpmte_internal.h
> index 464f476..14bc612 100644
> --- a/lib/rpmte_internal.h
> +++ b/lib/rpmte_internal.h
> @@ -34,11 +34,12 @@ extern "C" {
>  * @param type        TR_ADDED/TR_REMOVED
>  * @param key        (TR_ADDED) package retrieval key (e.g. file name)
>  * @param relocs    (TR_ADDED) package file relocations
> + * @param tags        additional tags to be saved
>  * @return        new transaction element
>  */
> RPM_GNUC_INTERNAL
> rpmte rpmteNew(rpmts ts, Header h, rpmElementType type, fnpyKey key,
> -           rpmRelocation * relocs);
> +           rpmRelocation * relocs, Header tags);
> 

Why does rpmteNew need to have an added argument?

> /** \ingroup rpmte
>  * Destroy a transaction element.
> diff --git a/lib/rpmts.h b/lib/rpmts.h
> index 5231c80..3836f84 100644
> --- a/lib/rpmts.h
> +++ b/lib/rpmts.h
> @@ -572,6 +572,36 @@ int rpmtsAddInstallElement(rpmts ts, Header h,
> int rpmtsAddReinstallElement(rpmts ts, Header h, const fnpyKey key);
> 
> /** \ingroup rpmts
> + * Add package to be installed to transaction set.
> + *
> + * The transaction set is checked for duplicate package names.
> + * If found, the package with the "newest" EVR will be replaced.
> + *
> + * @param ts        transaction set
> + * @param h        header
> + * @param key        package retrieval key (e.g. file name)
> + * @param upgrade    is package being upgraded?
> + * @param relocs    package file relocations
> + * @param tags        additional tags to be saved
> + * @return        0 on success, 1 on I/O error, 2 needs capabilities
> + */
> +int rpmtsAddInstallElementWithTags(rpmts ts, Header h,
> +        const fnpyKey key, int upgrade,
> +        rpmRelocation * relocs,
> +        Header tags);
> +
> +/** \ingroup rpmts
> + * Add package to be reinstalled to transaction set.
> + *
> + * @param ts        transaction set
> + * @param h        header
> + * @param key        package retrieval key (e.g. file name)
> + * @param tags        additional tags to be saved
> + * @return        0 on success
> + */
> +int rpmtsAddReinstallElementWithTags(rpmts ts, Header h, const fnpyKey key, 
> Header tags);
> +
> +/** \ingroup rpmts
>  * Add package to be erased to transaction set.
>  * @param ts        transaction set
>  * @param h        header
> diff --git a/lib/verify.c b/lib/verify.c
> index 1a8ce8d..83f1106 100644
> --- a/lib/verify.c
> +++ b/lib/verify.c
> @@ -297,7 +297,7 @@ static int rpmVerifyScript(rpmts ts, Header h)
> 
>     if (headerIsEntry(h, RPMTAG_VERIFYSCRIPT)) {
>    /* fake up a erasure transaction element */
> -    rpmte p = rpmteNew(ts, h, TR_REMOVED, NULL, NULL);
> +    rpmte p = rpmteNew(ts, h, TR_REMOVED, NULL, NULL, NULL);
> 
>    if (p != NULL) {
>        rpmteSetHeader(p, h);
> -- 

Changing verify.c is rather pointless here.

Write some test cases if you wish to see this interface added.

You will quickly find that:
1) only CHAR typed tags are going to "work".
2) attempts to replace existing tags in the immutable region are likely going 
to have unusual behaviors.

Hth

73 de Jeff
> 2.10.5
> 
> _______________________________________________
> Rpm-maint mailing list
> Rpm-maint@lists.rpm.org
> http://lists.rpm.org/mailman/listinfo/rpm-maint
_______________________________________________
Rpm-maint mailing list
Rpm-maint@lists.rpm.org
http://lists.rpm.org/mailman/listinfo/rpm-maint

Reply via email to