2002-03-25 20:16:26 +00:00
/** \ingroup rpmbuild
* \ file build / reqprov . c
* Add dependency tags to package header ( s ) .
*/
# include "system.h"
# include "rpmbuild.h"
# include "debug.h"
2004-01-29 13:46:42 +00:00
static int
deps_opt_enabled ( void )
{
2014-11-19 16:17:58 +00:00
static int enabled = - 1 ;
2004-01-29 13:46:42 +00:00
2014-11-19 16:17:58 +00:00
if ( enabled = = - 1 )
enabled = rpmExpandNumeric ( " %{?_deps_optimization}%{?!_deps_optimization:2} " ) > = 2 ;
2004-01-29 13:46:42 +00:00
return enabled ;
}
2013-01-27 23:21:16 +00:00
static int
tag_is_reqprov ( rpmTag tag )
{
switch ( tag ) {
case RPMTAG_REQUIREFLAGS :
case RPMTAG_PROVIDEFLAGS :
return 1 ;
default :
return 0 ;
}
}
2013-01-27 21:11:18 +00:00
static dep_compare_t
2013-01-28 00:52:24 +00:00
compare_sense_flags ( rpmTag tag , int cmp , int wcmp , rpmsenseFlags a , rpmsenseFlags b )
2004-01-26 18:01:37 +00:00
{
2013-01-27 23:21:16 +00:00
if ( cmp > 0 ) {
2004-01-26 18:01:37 +00:00
/* Aevr > Bevr */
2013-01-28 00:52:24 +00:00
return - compare_sense_flags ( tag , - cmp , - wcmp , b , a ) ;
2013-01-27 23:21:16 +00:00
} else if ( cmp = = 0 ) {
2004-01-26 18:01:37 +00:00
/* Aevr == Bevr */
2013-01-28 00:52:24 +00:00
if ( a = = b ) {
if ( wcmp = = 0 )
return DEP_EQ ;
else if ( wcmp < 0 )
return tag_is_reqprov ( tag ) ? DEP_ST : DEP_WK ;
else
return tag_is_reqprov ( tag ) ? DEP_WK : DEP_ST ;
}
if ( a & & ( ( a & b ) = = a ) ) {
/* b contains a */
/* LT,LE || EQ,LE || EQ,GE || GT,GE */
if ( wcmp < = 0 )
return ( tag = = RPMTAG_REQUIREFLAGS ) ? DEP_ST : DEP_WK ;
if ( a = = RPMSENSE_EQUAL )
return DEP_UN ;
2004-01-27 12:45:26 +00:00
return ( tag = = RPMTAG_REQUIREFLAGS ) ? DEP_ST : DEP_WK ;
2013-01-28 00:52:24 +00:00
}
if ( b & & ( ( a & b ) = = b ) ) /* a contains b */
return - compare_sense_flags ( tag , - cmp , - wcmp , b , a ) ;
2004-01-27 12:45:26 +00:00
return DEP_UN ;
2004-01-26 18:01:37 +00:00
}
2013-01-27 23:21:16 +00:00
/* cmp < 0 => Aevr < Bevr */
if ( a = = 0 ) {
/* a == 0 && cmp < 0 means b != 0 */
return tag_is_reqprov ( tag ) ? DEP_WK : DEP_ST ;
}
if ( tag = = RPMTAG_REQUIREFLAGS ) {
/* EQ || LE || LT is stronger than LE || LT */
if ( ! ( a & RPMSENSE_GREATER ) & & ( b & RPMSENSE_LESS ) )
return DEP_ST ;
/* GE || GT is weaker than EQ || GE || GT */
if ( ( a & RPMSENSE_GREATER ) & & ! ( b & RPMSENSE_LESS ) )
return DEP_WK ;
return DEP_UN ;
} else {
/* GE || GT is stronger than EQ || GE || GT */
if ( ( a & RPMSENSE_GREATER ) & & ! ( b & RPMSENSE_LESS ) )
return DEP_ST ;
/* EQ || LE || LT is weaker than LE || LT */
if ( ! ( a & RPMSENSE_GREATER ) & & ( b & RPMSENSE_LESS ) )
return DEP_WK ;
return DEP_UN ;
}
2004-01-26 18:01:37 +00:00
}
2010-10-04 02:11:13 +04:00
# include "set.h"
2013-01-27 21:11:18 +00:00
dep_compare_t
compare_deps ( rpmTag tag , const char * Aevr , rpmsenseFlags Aflags ,
const char * Bevr , rpmsenseFlags Bflags )
2004-01-26 18:01:37 +00:00
{
2004-01-27 12:45:26 +00:00
dep_compare_t rc = DEP_UN , cmp_rc ;
2004-01-26 18:01:37 +00:00
rpmsenseFlags Asense , Bsense ;
2013-01-28 00:52:24 +00:00
int sense , wcmp = 0 ;
2013-01-29 16:14:54 +00:00
char * aEVR = NULL , * bEVR = NULL ;
2018-12-20 04:36:24 +03:00
const char * aE , * aV , * aR , * aD , * bE , * bV , * bR , * bD ;
2004-01-26 18:01:37 +00:00
2004-01-27 12:45:26 +00:00
/* 1. filter out noise */
Aflags & = ~ ( RPMSENSE_FIND_REQUIRES | RPMSENSE_FIND_PROVIDES ) ;
Bflags & = ~ ( RPMSENSE_FIND_REQUIRES | RPMSENSE_FIND_PROVIDES ) ;
/* 2. identical? */
if ( Aflags = = Bflags & & ! strcmp ( Aevr , Bevr ) )
return DEP_EQ ;
2004-01-26 18:01:37 +00:00
2004-01-29 13:46:42 +00:00
/* 3. whether dependency optimization is enabled? */
if ( ! deps_opt_enabled ( ) )
return DEP_UN ;
2004-01-26 18:01:37 +00:00
Asense = Aflags & RPMSENSE_SENSEMASK ;
Bsense = Bflags & RPMSENSE_SENSEMASK ;
2004-01-29 13:46:42 +00:00
/* 4. check for supported tags. */
2004-01-26 18:01:37 +00:00
switch ( tag ) {
case RPMTAG_PROVIDEFLAGS :
case RPMTAG_OBSOLETEFLAGS :
case RPMTAG_CONFLICTFLAGS :
case RPMTAG_REQUIREFLAGS :
break ;
default :
/* no way to optimize this case. */
2004-01-27 12:45:26 +00:00
return DEP_UN ;
2004-01-26 18:01:37 +00:00
}
2004-01-27 12:45:26 +00:00
2004-01-29 13:46:42 +00:00
/* 5. sanity checks */
2004-01-26 18:01:37 +00:00
if (
( ( Asense & RPMSENSE_LESS ) & & ( Asense & RPMSENSE_GREATER ) ) | |
( ( Bsense & RPMSENSE_LESS ) & & ( Bsense & RPMSENSE_GREATER ) ) | |
( ( Asense = = 0 ) ^ ( Aevr [ 0 ] = = 0 ) ) | |
( ( Bsense = = 0 ) ^ ( Bevr [ 0 ] = = 0 ) )
)
2004-01-27 12:45:26 +00:00
return DEP_UN ;
2004-01-26 18:01:37 +00:00
2013-01-27 21:11:18 +00:00
/* 5. filter out essentially different versions. */
2004-01-26 18:01:37 +00:00
if (
( ( Asense & RPMSENSE_LESS ) & & ( Bsense & RPMSENSE_GREATER ) ) | |
( ( Bsense & RPMSENSE_LESS ) & & ( Asense & RPMSENSE_GREATER ) )
)
2004-01-27 12:45:26 +00:00
return DEP_UN ;
2004-01-26 18:01:37 +00:00
2013-01-27 21:11:18 +00:00
/* 7. filter out essentially different flags. */
2004-01-26 18:01:37 +00:00
if ( ( Aflags & ~ RPMSENSE_SENSEMASK ) ! = ( Bflags & ~ RPMSENSE_SENSEMASK ) )
{
rpmsenseFlags Areq , Breq ;
2013-01-27 21:11:18 +00:00
/* 7a. no way to optimize different non-REQUIREFLAGS */
2004-01-26 18:01:37 +00:00
if ( tag ! = RPMTAG_REQUIREFLAGS )
2004-01-27 12:45:26 +00:00
return DEP_UN ;
2004-01-26 18:01:37 +00:00
2013-01-27 21:11:18 +00:00
/* 7b. filter out essentially different requires. */
2004-01-26 18:01:37 +00:00
if ( ( Aflags & ~ RPMSENSE_SENSEMASK & ~ _ALL_REQUIRES_MASK ) ! =
( Bflags & ~ RPMSENSE_SENSEMASK & ~ _ALL_REQUIRES_MASK ) )
2004-01-27 12:45:26 +00:00
return DEP_UN ;
2004-01-26 18:01:37 +00:00
Areq = Aflags & _ALL_REQUIRES_MASK ;
Breq = Bflags & _ALL_REQUIRES_MASK ;
2013-01-27 21:11:18 +00:00
/* it is established fact that Areq != Breq */
2004-01-26 18:01:37 +00:00
2019-01-14 20:56:55 +00:00
/* 7c. Aflags contains Bflags? */
if ( Breq & & ( Areq & Breq ) = = Breq )
2004-01-27 12:45:26 +00:00
rc = DEP_ST ;
2019-01-14 20:56:55 +00:00
/* 7d. Bflags contains Aflags? */
2008-09-22 10:34:53 +00:00
else if ( Areq & & ( Areq & Breq ) = = Areq )
2004-01-27 12:45:26 +00:00
rc = DEP_WK ;
2004-01-26 18:01:37 +00:00
else
2004-01-27 12:45:26 +00:00
return DEP_UN ;
2004-01-26 18:01:37 +00:00
}
2004-01-29 13:46:42 +00:00
/* 8. compare versions. */
2010-10-04 02:11:13 +04:00
int aset = strncmp ( Aevr , " set: " , 4 ) = = 0 ;
int bset = strncmp ( Bevr , " set: " , 4 ) = = 0 ;
if ( aset & & bset ) {
sense = rpmsetcmp ( Aevr , Bevr ) ;
if ( sense < - 1 )
return DEP_UN ;
}
else if ( aset ) {
if ( * Bevr )
return DEP_UN ;
sense = 1 ;
}
else if ( bset ) {
if ( * Aevr )
return DEP_UN ;
sense = - 1 ;
}
else {
aEVR = xstrdup ( Aevr ) ;
2018-12-20 04:36:24 +03:00
parseEVRD ( aEVR , & aE , & aV , & aR , & aD ) ;
2010-10-04 02:11:13 +04:00
bEVR = xstrdup ( Bevr ) ;
2018-12-20 04:36:24 +03:00
parseEVRD ( bEVR , & bE , & bV , & bR , & bD ) ;
2010-10-04 02:11:13 +04:00
2013-01-26 16:44:06 +00:00
/*
2013-01-27 22:21:28 +00:00
* Promote Epoch by giving it special treatment :
* if one of deps has Epoch and another one hasn ' t ,
* we first compare them without Epoch , and if it happens
* that they are equal , then the dep that has Epoch wins .
2013-01-26 16:44:06 +00:00
*/
const char * ae = aE , * be = bE ;
2018-01-05 23:20:22 +00:00
if ( ( ! ( aE & & * aE ) | | ! ( bE & & * bE ) ) ) {
2013-01-26 16:44:06 +00:00
ae = NULL ; be = NULL ;
2018-01-05 23:20:22 +00:00
}
2013-01-26 16:44:06 +00:00
2013-01-28 00:52:24 +00:00
if ( ( aR & & * aR ) & & ! ( bR & & * bR ) )
wcmp = - 1 ;
else if ( ( bR & & * bR ) & & ! ( aR & & * aR ) )
wcmp = 1 ;
2013-01-26 16:44:06 +00:00
sense = rpmEVRcmp ( ae , aV , aR , Aevr , be , bV , bR , Bevr ) ;
2010-10-04 02:11:13 +04:00
}
2004-01-26 18:01:37 +00:00
2004-01-29 13:46:42 +00:00
/* 9. detect overlaps. */
2013-01-28 00:52:24 +00:00
cmp_rc = compare_sense_flags ( tag , sense , wcmp , Asense , Bsense ) ;
2004-01-26 18:01:37 +00:00
2013-01-26 16:44:06 +00:00
/* 10. EVRs with Epoch are stronger. */
2004-01-27 12:45:26 +00:00
if ( cmp_rc = = DEP_EQ )
2004-01-26 18:01:37 +00:00
{
2004-01-27 12:45:26 +00:00
if ( ( aE & & * aE ) & & ! ( bE & & * bE ) )
cmp_rc = DEP_ST ;
else if ( ( bE & & * bE ) & & ! ( aE & & * aE ) )
cmp_rc = DEP_WK ;
2004-01-26 18:01:37 +00:00
}
2019-02-27 05:53:52 +03:00
/* 10b. EVRs with DistTag are stronger. */
2018-12-20 04:36:24 +03:00
if ( cmp_rc = = DEP_EQ )
{
if ( ( aD & & * aD ) & & ! ( bD & & * bD ) )
cmp_rc = DEP_ST ;
else if ( ( bD & & * bD ) & & ! ( aD & & * aD ) )
cmp_rc = DEP_WK ;
}
2004-01-26 18:01:37 +00:00
2013-01-29 16:14:54 +00:00
aEVR = _free ( aEVR ) ;
bEVR = _free ( bEVR ) ;
2004-01-27 12:45:26 +00:00
#if 0
2013-01-28 00:52:24 +00:00
fprintf ( stderr , " D: compare_sense_flags=%d: tag=%d, sense=%d, wcmp=%d, Asense=%#x, Bsense=%#x \n " ,
cmp_rc , tag , sense , wcmp , Asense , Bsense ) ;
2004-01-27 12:45:26 +00:00
# endif
2013-01-27 21:11:18 +00:00
/* 11. compare expected with received. */
2004-01-27 12:45:26 +00:00
if ( cmp_rc = = DEP_UN | | rc = = DEP_UN )
return cmp_rc ;
if ( cmp_rc ! = rc & & cmp_rc ! = DEP_EQ )
return DEP_UN ;
2004-01-26 18:01:37 +00:00
return rc ;
}
2002-03-25 20:16:26 +00:00
int addReqProv ( /*@unused@*/ Spec spec , Header h ,
rpmsenseFlags depFlags , const char * depName , const char * depEVR ,
int index )
{
HGE_t hge = ( HGE_t ) headerGetEntryMinMemory ;
HFD_t hfd = headerFreeData ;
const char * * names ;
rpmTagType dnt ;
rpmTag nametag = 0 ;
rpmTag versiontag = 0 ;
rpmTag flagtag = 0 ;
rpmTag indextag = 0 ;
int len ;
rpmsenseFlags extra = RPMSENSE_ANY ;
int xx ;
2020-11-11 08:00:00 +00:00
/*@-branchstate@*/
if ( depEVR = = NULL )
depEVR = " " ;
/*@=branchstate@*/
2002-03-25 20:16:26 +00:00
if ( depFlags & RPMSENSE_PROVIDES ) {
2020-11-11 08:00:00 +00:00
const char * name = NULL ;
headerName ( h , & name ) ;
if ( name ! = NULL & & strcmp ( name , depName ) = = 0 ) {
char dep_flags_str [ 4 ] ;
unsigned int i = 0 ;
if ( depFlags & RPMSENSE_LESS )
dep_flags_str [ i + + ] = ' < ' ;
if ( depFlags & RPMSENSE_GREATER )
dep_flags_str [ i + + ] = ' > ' ;
if ( depFlags & RPMSENSE_EQUAL )
dep_flags_str [ i + + ] = ' = ' ;
dep_flags_str [ i ] = ' \0 ' ;
rpmMessage ( RPMMESS_WARNING , " ignored self-provides: %s %s %s \n " ,
depName , dep_flags_str , depEVR ) ;
return 0 ;
}
2002-03-25 20:16:26 +00:00
nametag = RPMTAG_PROVIDENAME ;
versiontag = RPMTAG_PROVIDEVERSION ;
flagtag = RPMTAG_PROVIDEFLAGS ;
extra = depFlags & RPMSENSE_FIND_PROVIDES ;
} else if ( depFlags & RPMSENSE_OBSOLETES ) {
nametag = RPMTAG_OBSOLETENAME ;
versiontag = RPMTAG_OBSOLETEVERSION ;
flagtag = RPMTAG_OBSOLETEFLAGS ;
} else if ( depFlags & RPMSENSE_CONFLICTS ) {
nametag = RPMTAG_CONFLICTNAME ;
versiontag = RPMTAG_CONFLICTVERSION ;
flagtag = RPMTAG_CONFLICTFLAGS ;
} else if ( depFlags & RPMSENSE_PREREQ ) {
nametag = RPMTAG_REQUIRENAME ;
versiontag = RPMTAG_REQUIREVERSION ;
flagtag = RPMTAG_REQUIREFLAGS ;
extra = depFlags & _ALL_REQUIRES_MASK ;
} else if ( depFlags & RPMSENSE_TRIGGER ) {
nametag = RPMTAG_TRIGGERNAME ;
versiontag = RPMTAG_TRIGGERVERSION ;
flagtag = RPMTAG_TRIGGERFLAGS ;
indextag = RPMTAG_TRIGGERINDEX ;
extra = depFlags & RPMSENSE_TRIGGER ;
} else {
nametag = RPMTAG_REQUIRENAME ;
versiontag = RPMTAG_REQUIREVERSION ;
flagtag = RPMTAG_REQUIREFLAGS ;
extra = depFlags & _ALL_REQUIRES_MASK ;
}
2004-01-27 12:45:26 +00:00
depFlags = ( depFlags & ( RPMSENSE_SENSEMASK ) ) | extra ;
2002-03-25 20:16:26 +00:00
/* Check for duplicate dependencies. */
2004-01-27 12:45:26 +00:00
if ( hge ( h , nametag , & dnt , ( void * * ) & names , & len ) & & len > 0 ) {
2002-03-25 20:16:26 +00:00
const char * * versions = NULL ;
rpmTagType dvt = RPM_STRING_ARRAY_TYPE ;
int * flags = NULL ;
int * indexes = NULL ;
2004-01-27 14:54:15 +00:00
int i , o_cnt = 0 , duplicate = 0 ;
char obsolete [ len ] ;
memset ( obsolete , 0 , sizeof obsolete ) ;
2002-03-25 20:16:26 +00:00
if ( flagtag ) {
xx = hge ( h , versiontag , & dvt , ( void * * ) & versions , NULL ) ;
xx = hge ( h , flagtag , NULL , ( void * * ) & flags , NULL ) ;
}
if ( indextag )
xx = hge ( h , indextag , NULL , ( void * * ) & indexes , NULL ) ;
2004-01-27 12:45:26 +00:00
for ( i = len - 1 ; i > = 0 ; - - i ) {
if ( indextag & & indexes & & indexes [ i ] ! = index )
2002-03-25 20:16:26 +00:00
continue ;
2004-01-24 19:05:04 +00:00
2004-01-27 12:45:26 +00:00
if ( strcmp ( names [ i ] , depName ) )
2002-03-25 20:16:26 +00:00
continue ;
2004-01-26 18:01:37 +00:00
if ( flagtag & & flags & & versions ) {
2019-01-10 23:20:03 +00:00
dep_compare_t rc = compare_deps ( flagtag , versions [ i ] , flags [ i ] ,
depEVR , depFlags ) ;
2004-01-24 19:05:04 +00:00
2004-01-26 18:01:37 +00:00
#if 0
2004-01-27 12:45:26 +00:00
fprintf ( stderr , " D: name=%s, compare_deps=%d: tag=%d, AEVR=%s, Aflags=%#x, BEVR=%s, Bflags=%#x \n " ,
depName , rc , flagtag , versions [ i ] , flags [ i ] , depEVR , depFlags ) ;
2004-01-26 18:01:37 +00:00
# endif
2019-01-14 20:56:55 +00:00
if ( rc = = DEP_UN & & flagtag = = RPMTAG_REQUIREFLAGS ) {
2019-01-13 22:39:58 +00:00
const rpmsenseFlags mergedFlags =
( flags [ i ] & _ALL_REQUIRES_MASK ) |
( depFlags & ~ RPMSENSE_FIND_REQUIRES ) ;
2019-01-10 23:20:03 +00:00
if ( mergedFlags ! = depFlags & &
compare_deps ( flagtag , versions [ i ] , flags [ i ] ,
depEVR , mergedFlags ) = = DEP_WK ) {
rpmMessage ( RPMMESS_DEBUG ,
" new dep \" %s \" flags %#x upgraded to %#x \n " ,
depName , depFlags , mergedFlags ) ;
depFlags = mergedFlags ;
rc = DEP_WK ;
}
}
switch ( rc ) {
2004-01-27 12:45:26 +00:00
case DEP_EQ :
rpmMessage ( RPMMESS_DEBUG ,
2004-01-29 12:57:54 +00:00
" new dep \" %s \" already exists, optimized out \n " ,
2004-01-27 12:45:26 +00:00
depName ) ;
2004-01-26 18:01:37 +00:00
break ;
2004-01-27 12:45:26 +00:00
case DEP_ST :
rpmMessage ( RPMMESS_DEBUG ,
2004-01-29 12:57:54 +00:00
" new dep \" %s \" is weaker, optimized out \n " ,
2004-01-27 12:45:26 +00:00
depName ) ;
break ;
case DEP_WK :
2004-01-27 14:54:15 +00:00
+ + o_cnt ;
obsolete [ i ] = 1 ;
2004-01-26 18:01:37 +00:00
default :
continue ;
}
2004-01-24 19:05:04 +00:00
}
2002-03-25 20:16:26 +00:00
/* This is a duplicate dependency. */
duplicate = 1 ;
2004-01-27 14:54:15 +00:00
if ( o_cnt ) {
rpmMessage ( RPMMESS_WARNING , " %d obsolete deps left " , o_cnt ) ;
o_cnt = 0 ;
}
2002-03-25 20:16:26 +00:00
break ;
2004-01-27 14:54:15 +00:00
} /* end of main loop */
if ( o_cnt )
{
2004-01-29 13:46:42 +00:00
int j , new_len = len - o_cnt ;
2004-01-27 14:54:15 +00:00
const char * new_names [ new_len ] ;
const char * new_versions [ new_len ] ;
2004-01-29 13:46:42 +00:00
int new_flags [ new_len ] ;
2004-01-27 14:54:15 +00:00
rpmMessage ( RPMMESS_DEBUG , " %d old deps to be optimized out \n " , o_cnt ) ;
for ( i = 0 , j = 0 ; i < len ; + + i )
{
2004-01-29 13:46:42 +00:00
char * p ;
2004-01-27 14:54:15 +00:00
if ( obsolete [ i ] )
{
2004-01-29 13:46:42 +00:00
rpmMessage ( RPMMESS_DEBUG , " old dep \" %s \" optimized out \n " , names [ i ] ) ;
2004-01-27 14:54:15 +00:00
continue ;
}
p = alloca ( 1 + strlen ( names [ i ] ) ) ;
strcpy ( p , names [ i ] ) ;
new_names [ j ] = p ;
p = alloca ( 1 + strlen ( versions [ i ] ) ) ;
strcpy ( p , versions [ i ] ) ;
new_versions [ j ] = p ;
new_flags [ j ] = flags [ i ] ;
+ + j ;
}
2004-01-29 13:46:42 +00:00
if ( ! headerModifyEntry ( h , nametag , RPM_STRING_ARRAY_TYPE , new_names , new_len )
| | ! headerModifyEntry ( h , versiontag , RPM_STRING_ARRAY_TYPE , new_versions , new_len )
| | ! headerModifyEntry ( h , flagtag , RPM_INT32_TYPE , new_flags , new_len ) )
rpmError ( RPMERR_BADHEADER , " addReqProv: error modifying entry for dep %s \n " , depName ) ;
2004-01-27 14:54:15 +00:00
rpmMessage ( RPMMESS_DEBUG , " %d old deps optimized out, %d left \n " , o_cnt , new_len ) ;
2002-03-25 20:16:26 +00:00
}
2004-01-27 14:54:15 +00:00
2002-03-25 20:16:26 +00:00
versions = hfd ( versions , dvt ) ;
2004-01-25 10:50:18 +00:00
names = hfd ( names , dnt ) ;
2002-03-25 20:16:26 +00:00
if ( duplicate )
2010-09-11 01:00:13 +04:00
return 1 ;
2002-03-25 20:16:26 +00:00
}
2004-01-29 13:46:42 +00:00
/* Do not add NEW provided requires. */
if ( deps_opt_enabled ( )
& & ( nametag = = RPMTAG_REQUIRENAME )
& & ! ( depFlags & _notpre ( RPMSENSE_RPMLIB | RPMSENSE_KEYRING |
2007-11-22 15:28:16 +03:00
RPMSENSE_SCRIPT_PRE | RPMSENSE_SCRIPT_POSTUN ) ) )
2004-01-29 12:57:54 +00:00
{
2004-01-24 23:31:06 +00:00
2004-01-29 12:57:54 +00:00
int skip = 0 ;
int * flags = 0 ;
const char * * versions = 0 ;
rpmTagType dvt = RPM_STRING_ARRAY_TYPE ;
2004-01-24 23:31:06 +00:00
2007-11-22 15:28:16 +03:00
names = NULL ;
hge ( h , RPMTAG_PROVIDENAME , & dnt , ( void * * ) & names , & len ) ;
2004-01-29 12:57:54 +00:00
hge ( h , RPMTAG_PROVIDEVERSION , & dvt , ( void * * ) & versions , NULL ) ;
hge ( h , RPMTAG_PROVIDEFLAGS , NULL , ( void * * ) & flags , NULL ) ;
2004-01-24 23:31:06 +00:00
2007-11-22 15:28:16 +03:00
while ( names & & flags & & versions & & ( len > 0 ) )
2004-01-29 12:57:54 +00:00
{
- - len ;
2004-01-24 23:31:06 +00:00
2004-01-29 12:57:54 +00:00
if ( strcmp ( depName , names [ len ] ) )
continue ;
if ( ! ( depFlags & RPMSENSE_SENSEMASK ) )
{
skip = 1 ;
break ;
}
if ( ! ( flags [ len ] & RPMSENSE_SENSEMASK ) )
continue ;
if ( rpmRangesOverlap ( " " , versions [ len ] , flags [ len ] ,
" " , depEVR , depFlags ) )
{
rpmMessage ( RPMMESS_DEBUG ,
" new dep \" %s \" already provided, optimized out \n " ,
depName ) ;
skip = 1 ;
break ;
}
}
2004-01-24 23:31:06 +00:00
2004-01-29 12:57:54 +00:00
versions = hfd ( versions , dvt ) ;
names = hfd ( names , dnt ) ;
if ( skip )
2010-09-11 01:00:13 +04:00
return 1 ;
2007-11-22 16:45:02 +03:00
if ( * depName = = ' / ' & & ! ( depFlags & RPMSENSE_SENSEMASK ) )
{
const char * * bn = NULL , * * dn = NULL ;
const int_32 * di = NULL ;
rpmTagType bnt = 0 , dnt = 0 , dit = 0 ;
int_32 bnc = 0 ;
int i ;
( void ) ( hge ( h , RPMTAG_DIRNAMES , & dnt , ( void * * ) & dn , NULL ) & &
hge ( h , RPMTAG_DIRINDEXES , & dit , ( void * * ) & di , NULL ) & &
hge ( h , RPMTAG_BASENAMES , & bnt , ( void * * ) & bn , & bnc ) ) ;
for ( i = 0 ; i < bnc ; i + + ) {
const char * d = dn [ di [ i ] ] , * b = bn [ i ] ;
size_t dl = strlen ( d ) ;
if ( strncmp ( depName , d , dl ) | |
strcmp ( depName + dl , b ) )
continue ;
rpmMessage ( RPMMESS_DEBUG ,
" new dep \" %s \" is packaged file, optimized out \n " ,
depName ) ;
skip = 1 ;
break ;
}
hfd ( dn , dnt ) ;
hfd ( di , dit ) ;
hfd ( bn , bnt ) ;
}
2007-11-23 10:26:50 +03:00
else {
2019-02-25 06:40:58 +03:00
const char * N = NULL , * V = NULL , * R = NULL , * D = NULL ;
headerNVRD ( h , & N , & V , & R , & D ) ;
2007-11-23 10:26:50 +03:00
if ( N & & strcmp ( depName , N ) = = 0 ) {
if ( ! ( depFlags & RPMSENSE_SENSEMASK ) )
skip = 1 ;
else if ( V & & R ) {
int_32 * E = NULL ;
2019-02-25 06:40:58 +03:00
const char * EVR , * EVRD = NULL ;
2007-11-23 10:26:50 +03:00
hge ( h , RPMTAG_EPOCH , NULL , ( void * * ) & E , NULL ) ;
if ( E )
2019-02-25 06:40:58 +03:00
EVR = xasprintf ( " %d:%s-%s " , * E , V , R ) ;
2007-11-23 10:26:50 +03:00
else
2019-02-25 06:40:58 +03:00
EVR = xasprintf ( " %s-%s " , V , R ) ;
if ( D )
EVRD = xasprintf ( " %s:%s " , EVR , D ) ;
if ( rpmRangesOverlap ( " " , EVRD ? : EVR , RPMSENSE_EQUAL ,
2007-11-23 10:26:50 +03:00
" " , depEVR , depFlags ) )
skip = 1 ;
2019-02-25 06:40:58 +03:00
EVRD = _free ( EVRD ) ;
EVR = _free ( EVR ) ;
2007-11-23 10:26:50 +03:00
}
2011-03-14 01:49:42 +00:00
else
skip = 1 ;
2007-11-23 10:26:50 +03:00
if ( skip )
rpmMessage ( RPMMESS_DEBUG ,
" new dep \" %s \" is the package name, optimized out \n " ,
depName ) ;
}
}
if ( skip )
2010-09-11 01:00:13 +04:00
return 1 ;
2004-01-29 12:57:54 +00:00
}
2004-01-24 23:31:06 +00:00
2004-01-29 13:46:42 +00:00
/* Remove OLD provided requires. */
if ( deps_opt_enabled ( )
& & ( nametag = = RPMTAG_PROVIDENAME )
& & hge ( h , RPMTAG_REQUIRENAME , & dnt , ( void * * ) & names , & len ) )
{
int * flags = 0 ;
const char * * versions = 0 ;
rpmTagType dvt = RPM_STRING_ARRAY_TYPE ;
int i , o_cnt = 0 ;
char obsolete [ len ] ;
memset ( obsolete , 0 , sizeof obsolete ) ;
hge ( h , RPMTAG_REQUIREVERSION , & dvt , ( void * * ) & versions , NULL ) ;
hge ( h , RPMTAG_REQUIREFLAGS , NULL , ( void * * ) & flags , NULL ) ;
for ( i = len - 1 ; flags & & versions & & ( i > = 0 ) ; - - i )
{
rpmsenseFlags f = flags [ i ] ;
if ( ( f & _notpre ( RPMSENSE_RPMLIB | RPMSENSE_KEYRING |
2019-01-14 20:56:55 +00:00
RPMSENSE_SCRIPT_PRE | RPMSENSE_SCRIPT_POSTUN ) ) )
2004-01-29 13:46:42 +00:00
continue ;
if ( strcmp ( depName , names [ i ] ) )
continue ;
if ( ! ( f & RPMSENSE_SENSEMASK ) )
{
+ + o_cnt ;
obsolete [ i ] = 1 ;
continue ;
}
if ( ! ( depFlags & RPMSENSE_SENSEMASK ) )
continue ;
if ( rpmRangesOverlap ( " " , depEVR , depFlags ,
" " , versions [ i ] , f ) )
{
+ + o_cnt ;
obsolete [ i ] = 1 ;
continue ;
}
}
if ( o_cnt )
{
int j , new_len = len - o_cnt ;
const char * new_names [ new_len ] ;
const char * new_versions [ new_len ] ;
int new_flags [ new_len ] ;
rpmMessage ( RPMMESS_DEBUG , " %d old deps to be optimized out \n " , o_cnt ) ;
for ( i = 0 , j = 0 ; i < len ; + + i )
{
char * p ;
if ( obsolete [ i ] )
{
rpmMessage ( RPMMESS_DEBUG , " old dep \" %s \" optimized out \n " , names [ i ] ) ;
continue ;
}
p = alloca ( 1 + strlen ( names [ i ] ) ) ;
strcpy ( p , names [ i ] ) ;
new_names [ j ] = p ;
p = alloca ( 1 + strlen ( versions [ i ] ) ) ;
strcpy ( p , versions [ i ] ) ;
new_versions [ j ] = p ;
new_flags [ j ] = flags [ i ] ;
+ + j ;
}
if ( ! headerModifyEntry ( h , RPMTAG_REQUIRENAME , RPM_STRING_ARRAY_TYPE , new_names , new_len ) | |
! headerModifyEntry ( h , RPMTAG_REQUIREVERSION , RPM_STRING_ARRAY_TYPE , new_versions , new_len ) | |
! headerModifyEntry ( h , RPMTAG_REQUIREFLAGS , RPM_INT32_TYPE , new_flags , new_len ) )
rpmError ( RPMERR_BADHEADER , " addReqProv: error modifying entry for dep %s \n " , depName ) ;
rpmMessage ( RPMMESS_DEBUG , " %d old deps optimized out, %d left \n " , o_cnt , new_len ) ;
}
versions = hfd ( versions , dvt ) ;
names = hfd ( names , dnt ) ;
}
2002-03-25 20:16:26 +00:00
/* Add this dependency. */
xx = headerAddOrAppendEntry ( h , nametag , RPM_STRING_ARRAY_TYPE , & depName , 1 ) ;
if ( flagtag ) {
xx = headerAddOrAppendEntry ( h , versiontag ,
RPM_STRING_ARRAY_TYPE , & depEVR , 1 ) ;
xx = headerAddOrAppendEntry ( h , flagtag ,
RPM_INT32_TYPE , & depFlags , 1 ) ;
}
if ( indextag )
xx = headerAddOrAppendEntry ( h , indextag , RPM_INT32_TYPE , & index , 1 ) ;
return 0 ;
}
int rpmlibNeedsFeature ( Header h , const char * feature , const char * featureEVR )
{
char * reqname = alloca ( sizeof ( " rpmlib() " ) + strlen ( feature ) ) ;
( void ) stpcpy ( stpcpy ( stpcpy ( reqname , " rpmlib( " ) , feature ) , " ) " ) ;
2009-06-16 19:17:19 +04:00
rpmsenseFlags depFlags = RPMSENSE_RPMLIB ;
if ( featureEVR )
depFlags | = RPMSENSE_LESS | RPMSENSE_EQUAL ;
2002-03-25 20:16:26 +00:00
/* XXX 1st arg is unused */
2009-06-16 19:17:19 +04:00
return addReqProv ( NULL , h , depFlags , reqname , featureEVR , 0 ) ;
2002-03-25 20:16:26 +00:00
}