RPM Community Forums

Mailing List Message of <rpm-devel>

Re: [CVS] RPM: rpm/ CHANGES rpm/lib/ psm.c rpmds.c

From: Jeff Johnson <n3npq@mac.com>
Date: Wed 15 Oct 2008 - 18:44:34 CEST
Message-id: <90C02AE2-6324-48BB-B27A-F398B9E43CEE@mac.com>
With this patch, the file/dir triggers implementation
is likely as close as I'm going to get.

The one remaining flaw is one of design. These two glob
patterns are equivalent (wrto fnmatch globbing)
	/parent/dir*
	/parent/dir*/

However, the first pattern is appled (by rpm) to the Basenames/Filepaths
index, while the 2nd pattern is (or should be) applied to the  
Dirnames index.

But there's no way (that I see) to prevent the glob pattern from  
matching twice.

(aside)
The are also differences in the set of directory paths included in
Filepaths and Dirnames. Specifically, the Dirnames contains
all parent directories, not just the directories contained in
the package. There's the secondary problem of lack of
data normalization, directory paths can be found in
any/all of Providename/Filepaths/Dirnames and its
not at all clear what criteria can be used to identify
the single index where a directory path retrieval
key is located.

Here's the one remaining conundrum in the implementation. Note
that a trigger is fired twice, once by the Dirnames index, finally by  
the
Basenames/Filepaths index. Arguably this is "correct" behavior although
clearly not what would be expected intuitively:

...
/X/src/wdj/rpm --macros /X/src/wdj/macros:/X/src/wdj/tests/macros -Uv  
--noparentdirs --nodeps triggers-DP/triggers-DP*.rpm
Preparing packages for installation...
triggers-DP-b-1.0-1.i386
--- triggerprein(b) -- /tmp/triggers-DP-[aq]/   arg 1 0 ...
--- triggerprein(b) -- /tmp/triggers-DP-[aq]/   arg 1 0 ...
--- triggerprein(a) -- /tmp/triggers-DP-[bq]/   arg 0 1 ...
triggers-DP-a-1.0-1.noarch
--- triggerin(b) -- /tmp/triggers-DP-[aq]/      arg 1 1 ...
--- triggerin(b) -- /tmp/triggers-DP-[aq]/      arg 1 1 ...
--- triggerin(a) -- /tmp/triggers-DP-[bq]/      arg 1 1 ...
/X/src/wdj/rpm --macros /X/src/wdj/macros:/X/src/wdj/tests/macros -ev  
--noparentdirs --nodeps triggers-DP-a triggers-DP-b
Wrote: /X/src/wdj/tests/tmp/repackage/1224088266/triggers-DP- 
b-1.0-1.i386.rpm
Wrote: /X/src/wdj/tests/tmp/repackage/1224088266/triggers-DP- 
a-1.0-1.noarch.rpm
--- triggerun(b) -- /tmp/triggers-DP-[aq]/      arg 0 1 ...
--- triggerun(a) -- /tmp/triggers-DP-[bq]/      arg 1 0 ...
--- triggerun(a) -- /tmp/triggers-DP-[bq]/      arg 1 0 ...
--- triggerpostun(a) -- /tmp/triggers-DP-[bq]/  arg 1 0 ...
--- triggerpostun(a) -- /tmp/triggers-DP-[bq]/  arg 1 0 ...
--- triggerpostun(b) -- /tmp/triggers-DP-[aq]/  arg 0 1 ...

I'll push the dile/dir trigger implementation to the rpm-5_1 branch  
while cleaning
up some details. I should have that completed later this week, unless  
some other
black hole swallows me ...

73 de Jeff

On Oct 15, 2008, at 11:41 AM, Jeff Johnson wrote:

>   RPM Package Manager, CVS Repository
>   http://rpm5.org/cvs/
>    
> ______________________________________________________________________ 
> ______
>
>   Server: rpm5.org                         Name:   Jeff Johnson
>   Root:   /v/rpm/cvs                       Email:  jbj@rpm5.org
>   Module: rpm                              Date:   15-Oct-2008  
> 17:41:57
>   Branch: HEAD                             Handle: 2008101515415601
>
>   Modified files:
>     rpm                     CHANGES
>     rpm/lib                 psm.c rpmds.c
>
>   Log:
>     - jbj: add flag to keep trailing slash in dirnames dependency set.
>
>   Summary:
>     Revision    Changes     Path
>     1.2614      +1  -0      rpm/CHANGES
>     2.334       +48 -44     rpm/lib/psm.c
>     2.110       +3  -0      rpm/lib/rpmds.c
>    
> ______________________________________________________________________ 
> ______
>
>   patch -p0 <<'@@ .'
>   Index: rpm/CHANGES
>    
> ====================================================================== 
> ======
>   $ cvs diff -u -r1.2613 -r1.2614 CHANGES
>   --- rpm/CHANGES	15 Oct 2008 05:27:22 -0000	1.2613
>   +++ rpm/CHANGES	15 Oct 2008 15:41:56 -0000	1.2614
>   @@ -1,5 +1,6 @@
>
>    5.2a1 -> 5.2a2:
>   +    - jbj: add flag to keep trailing slash in dirnames  
> dependency set.
>        - jbj: fix a memory leak by calling mireClean().
>        - jbj: save rpmdb trigger patterns in psm.c, eliminating 2nd  
> retrieve.
>        - jbj: use generic retrieval code for --group and -- 
> triggerdby too.
>   @@ .
>   patch -p0 <<'@@ .'
>   Index: rpm/lib/psm.c
>    
> ====================================================================== 
> ======
>   $ cvs diff -u -r2.333 -r2.334 psm.c
>   --- rpm/lib/psm.c	15 Oct 2008 05:27:23 -0000	2.333
>   +++ rpm/lib/psm.c	15 Oct 2008 15:41:57 -0000	2.334
>   @@ -1027,12 +1027,10 @@
>     * @param sourceH
>     * @param triggeredH
>     * @param arg2
>   - * @param delslash	delete trailing slash in trigger names?
>     * @return		RPMRC_OK on success
>     */
>    static rpmRC handleOneTrigger(const rpmpsm psm,
>   -			Header sourceH, Header triggeredH,
>   -			int arg2, int delslash)
>   +			Header sourceH, Header triggeredH, int arg2)
>    	/*@globals rpmGlobalMacroContext, h_errno, fileSystem,  
> internalState@*/
>    	/*@modifies psm, sourceH, triggeredH, *triggersAlreadyRun,
>    		rpmGlobalMacroContext, fileSystem, internalState @*/
>   @@ -1106,32 +1104,42 @@
>    	if (depName[0] == '/') {
>    	    size_t nb = strlen(depName);
>    	    if (Glob_pattern_p(depName, 0)) {
>   -
>   -		/* Initialize file names and pattern containers. */
>   -		if (Fds == NULL)
>   -		    Fds = rpmdsNew(sourceH, RPMTAG_BASENAMES, 0);
>   +		rpmds ds = NULL;
>   +		if (depName[nb-1] == '/') {
>   +		    /* XXX Dirnames w trailing "/" needed. */
>   +		    if (Dds == NULL)
>   +			Dds = rpmdsNew(sourceH, RPMTAG_DIRNAMES, 0x2);
>   +		    ds = rpmdsLink(Dds, "Triggers");
>   +		} else {
>   +		    if (Fds == NULL)
>   +			Fds = rpmdsNew(sourceH, RPMTAG_BASENAMES, 0);
>   +		    ds = rpmdsLink(Fds, "Triggers");
>   +		}
>    		if (mire == NULL)
>    		    mire = mireNew(RPMMIRE_GLOB, 0);
>
>    		xx = mireRegcomp(mire, depName);
>   -		if ((Fds = rpmdsInit(Fds)) != NULL)
>   -		while (rpmdsNext(Fds) >= 0) {
>   -		    if (mireRegexec(mire, rpmdsN(Fds), 0) < 0)
>   +		if ((ds = rpmdsInit(ds)) != NULL)
>   +		while (rpmdsNext(ds) >= 0) {
>   +		    const char * N = rpmdsN(ds);
>   +		    xx = mireRegexec(mire, N, 0);
>   +		    if (xx < 0)
>    			continue;
>    		    bingo = 1;
>    		    break;
>    		}
>   +		ds = rpmdsFree(ds);
>    		xx = mireClean(mire);
>   -	    } else {
>   -		if (delslash && depName[nb-1] == '/')
>   -		    depName[nb-1] = '\0';
>    	    }
>   +
>    	    /* If not matched, and directory trigger, try dir names. */
>    	    if (!bingo && depName[nb-1] == '/') {
>   +		/* XXX Dirnames w trailing "/" needed. */
>    		if (Dds == NULL)
>   -		    Dds = rpmdsNew(sourceH, RPMTAG_DIRNAMES, 0);
>   +		    Dds = rpmdsNew(sourceH, RPMTAG_DIRNAMES, 0x2);
>    		bingo = rpmdsMatch(Tds, Dds);
>    	    }
>   +
>    	    /* If not matched, try file paths. */
>    	    if (!bingo) {
>    		if (Fds == NULL)
>   @@ -1249,35 +1257,32 @@
>    	depName = _free(depName);
>    	depName = xmalloc(nName + 1 + 1);
>    	(void) stpcpy(depName, Name);
>   +	/* XXX re-add the pesky trailing '/' to dirnames. */
>    	depName[nName] = (tagno == RPMTAG_DIRNAMES ? '/' : '\0');
>    	depName[nName+1] = '\0';
>   +if (_jbj)
>   +fprintf(stderr, "*** looking for trigger \"%s\"\n", depName);
>
>   -	if (depName[0] == '/') {
>   -
>   -	    /* XXX Skip pattern <-> pattern match false triggers. */
>   -	    if (Glob_pattern_p(depName, 0))
>   -		continue;
>   -
>   -	    if (psm->Tmires) {
>   -		miRE mire;
>   -		int j;
>   -
>   -		/* XXX mireApply doesn't tell which pattern matched. */
>   -		for (j = 0, mire = psm->Tmires; j < psm->nTmires; j++, mire++) {
>   -		    const char * pattern = psm->Tpats[j];
>   -		    if (depName[nName-1] != '/') {
>   -			size_t npattern = strlen(pattern);
>   -			depName[nName] = (pattern[npattern-1] == '/')
>   -				? '/' : '\0';
>   -		    }
>   -		    if (mireRegexec(mire, depName, 0) < 0)
>   -			continue;
>   +	if (depName[0] == '/' && psm->Tmires != NULL) {
>   +	    miRE mire;
>   +	    int j;
>   +
>   +	    /* XXX mireApply doesn't tell which pattern matched. */
>   +	    for (j = 0, mire = psm->Tmires; j < psm->nTmires; j++, mire+ 
> +) {
>   +		const char * pattern = psm->Tpats[j];
>   +		if (depName[nName-1] != '/') {
>   +		    size_t npattern = strlen(pattern);
>   +		    depName[nName] = (pattern[npattern-1] == '/') ? '/' : '\0';
>   +		}
>   +		if (mireRegexec(mire, depName, 0) < 0)
>   +		    continue;
>    if (_jbj)
>    fprintf(stderr, "=== %p[%d] %s matched %s\n", psm->Tpats, j,  
> pattern, depName);
>   -		    depName = _free(depName);
>   -		    depName = xstrdup(pattern);
>   -		    break;
>   -		}
>   +
>   +		/* Reset the primary retrieval key to the pattern. */
>   +		depName = _free(depName);
>   +		depName = xstrdup(pattern);
>   +		break;
>    	    }
>    	}
>
>   @@ -1296,7 +1301,7 @@
>    	    instance = rpmdbGetIteratorOffset(mi);
>    	    if (prev == instance)
>    		continue;
>   -	    rc |= handleOneTrigger(psm, fi->h, triggeredH, arg2, 0);
>   +	    rc |= handleOneTrigger(psm, fi->h, triggeredH, arg2);
>    	    prev = instance;
>    	    xx = argiAdd(&instances, -1, instance);
>    	    xx = argiSort(instances, NULL);
>   @@ -1360,7 +1365,9 @@
>
>    	/* If not limited to NEVRA triggers, also try file/dir path  
> triggers. */
>    	if (tagno != RPMTAG_NAME) {
>   -	    int xx = rpmdbTriggerGlobs(psm);
>   +	    int xx;
>   +	    /* Retrieve trigger patterns from rpmdb. */
>   +	    xx = rpmdbTriggerGlobs(psm);
>
>    	    rc |= runTriggersLoop(psm, RPMTAG_BASENAMES, numPackage);
>    	    rc |= runTriggersLoop(psm, RPMTAG_DIRNAMES, numPackage);
>   @@ -1453,7 +1460,6 @@
>        for (i = 0; (Name = keys[i]) != NULL; i++) {
>    	unsigned prev, instance;
>    	unsigned nvals;
>   -	int delslash;
>    	ARGint_t vals;
>
>    	/* If not limited to NEVRA triggers, use file/dir index. */
>   @@ -1464,8 +1470,6 @@
>    			? RPMTAG_DIRNAMES : RPMTAG_FILEPATHS;
>    	}
>
>   -	delslash = (tagno == RPMTAG_DIRNAMES);
>   -
>    	mi = rpmtsInitIterator(ts, tagno, Name, 0);
>
>    if (_jbj)
>   @@ -1486,7 +1490,7 @@
>    		continue;
>
>    	    rc |= handleOneTrigger(psm, sourceH, fi->h,
>   -				rpmdbGetIteratorCount(mi), delslash);
>   +				rpmdbGetIteratorCount(mi));
>
>    	    /* Mark header instance as processed. */
>    	    prev = instance;
>   @@ .
>   patch -p0 <<'@@ .'
>   Index: rpm/lib/rpmds.c
>    
> ====================================================================== 
> ======
>   $ cvs diff -u -r2.109 -r2.110 rpmds.c
>   --- rpm/lib/rpmds.c	14 Oct 2008 20:59:17 -0000	2.109
>   +++ rpm/lib/rpmds.c	15 Oct 2008 15:41:57 -0000	2.110
>   @@ -246,6 +246,7 @@
>    rpmds rpmdsNew(Header h, rpmTag tagN, int flags)
>    {
>        int scareMem = (flags & 0x1);
>   +    int delslash = 1;
>        HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
>        rpmTag tagEVR, tagF;
>        rpmds ds = NULL;
>   @@ -294,6 +295,7 @@
>        case RPMTAG_DIRNAMES:
>    	tagEVR = 0;
>    	tagF = 0;
>   +	delslash = (flags & 0x2) ? 0 : 1;
>    	break;
>        case RPMTAG_BASENAMES:
>    	tagEVR = RPMTAG_DIRNAMES;
>   @@ -350,6 +352,7 @@
>    	    size_t len;
>    	    unsigned i;
>    	    /* XXX Dirnames always have trailing '/', trim that here. */
>   +	    if (delslash)
>    	    for (i = 0; i < Count; i++) {
>    		(void) urlPath(N[i], (const char **)&dn);
>    		if (dn > N[i])
>   @@ .
> ______________________________________________________________________
> RPM Package Manager                                    http://rpm5.org
> CVS Sources Repository                                rpm-cvs@rpm5.org
Received on Wed Oct 15 18:45:08 2008
Driven by Jeff Johnson and the RPM project team.
Hosted by OpenPKG and Ralf S. Engelschall.
Powered by FreeBSD and OpenPKG.