Avoid unnecessary .rpmnew and .rpmsave files (rhbz#128622)
Don't create .rpmnew and .rpmsave files when file/symlink on disk differs just by timestamp. Patch by Tomas Mraz.
This commit is contained in:
commit
a77f9d2cd1
44
lib/rpmfi.c
44
lib/rpmfi.c
|
@ -22,6 +22,7 @@
|
|||
#include "rpmte.h"
|
||||
#include "rpmts.h"
|
||||
|
||||
#include "legacy.h" /* XXX domd5 */
|
||||
#include "misc.h" /* XXX stripTrailingChar */
|
||||
#include "rpmmacro.h" /* XXX rpmCleanPath */
|
||||
#include "legacy.h"
|
||||
|
@ -628,6 +629,49 @@ fileAction rpmfiDecideFate(const rpmfi ofi, rpmfi nfi, int skipMissing)
|
|||
}
|
||||
/*@=boundsread@*/
|
||||
|
||||
/*@-boundsread@*/
|
||||
int rpmfiConfigConflict(const rpmfi fi)
|
||||
{
|
||||
const char * fn = rpmfiFN(fi);
|
||||
int flags = rpmfiFFlags(fi);
|
||||
char buffer[1024];
|
||||
fileTypes newWhat, diskWhat;
|
||||
struct stat sb;
|
||||
|
||||
if (!(flags & RPMFILE_CONFIG) || lstat(fn, &sb)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
diskWhat = whatis((int_16)sb.st_mode);
|
||||
newWhat = whatis(rpmfiFMode(fi));
|
||||
|
||||
if (newWhat != LINK && newWhat != REG)
|
||||
return 1;
|
||||
|
||||
if (diskWhat != newWhat)
|
||||
return 1;
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
if (newWhat == REG) {
|
||||
const unsigned char * nmd5;
|
||||
if (domd5(fn, (unsigned char *)buffer, 0, NULL))
|
||||
return 0; /* assume file has been removed */
|
||||
nmd5 = rpmfiMD5(fi);
|
||||
if (nmd5 && !memcmp(nmd5, buffer, 16))
|
||||
return 0; /* unmodified config file */
|
||||
} else /* newWhat == LINK */ {
|
||||
const char * nFLink;
|
||||
if (readlink(fn, buffer, sizeof(buffer) - 1) == -1)
|
||||
return 0; /* assume file has been removed */
|
||||
nFLink = rpmfiFLink(fi);
|
||||
if (nFLink && !strcmp(nFLink, buffer))
|
||||
return 0; /* unmodified config file */
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*@=boundsread@*/
|
||||
|
||||
/*@observer@*/
|
||||
const char * rpmfiTypeString(rpmfi fi)
|
||||
{
|
||||
|
|
|
@ -619,6 +619,14 @@ fileAction rpmfiDecideFate(const rpmfi ofi, rpmfi nfi, int skipMissing)
|
|||
/*@globals h_errno, fileSystem, internalState @*/
|
||||
/*@modifies nfi, fileSystem, internalState @*/;
|
||||
|
||||
/**
|
||||
* Return whether file is conflicting config
|
||||
* @param fi file info
|
||||
* @return 1 if config file and file on disk conflicts
|
||||
*/
|
||||
int rpmfiConfigConflict(const rpmfi fi)
|
||||
/*@*/;
|
||||
|
||||
/**
|
||||
* Return formatted string representation of package disposition.
|
||||
* @param fi file info set
|
||||
|
|
|
@ -547,7 +547,7 @@ static void handleOverlappedFiles(const rpmts ts,
|
|||
/*@-boundswrite@*/
|
||||
switch (rpmteType(p)) {
|
||||
case TR_ADDED:
|
||||
{ struct stat sb;
|
||||
{
|
||||
int reportConflicts =
|
||||
!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACENEWFILES);
|
||||
int done = 0;
|
||||
|
@ -556,7 +556,7 @@ static void handleOverlappedFiles(const rpmts ts,
|
|||
/* XXX is this test still necessary? */
|
||||
if (fi->actions[i] != FA_UNKNOWN)
|
||||
/*@switchbreak@*/ break;
|
||||
if ((FFlags & RPMFILE_CONFIG) && !lstat(fn, &sb)) {
|
||||
if (rpmfiConfigConflict(fi)) {
|
||||
/* Here is a non-overlapped pre-existing config file. */
|
||||
fi->actions[i] = (FFlags & RPMFILE_NOREPLACE)
|
||||
? FA_ALTNAME : FA_BACKUP;
|
||||
|
@ -613,7 +613,7 @@ assert(otherFi != NULL);
|
|||
/* Try to get the disk accounting correct even if a conflict. */
|
||||
fixupSize = rpmfiFSize(otherFi);
|
||||
|
||||
if ((FFlags & RPMFILE_CONFIG) && !lstat(fn, &sb)) {
|
||||
if (rpmfiConfigConflict(fi)) {
|
||||
/* Here is an overlapped pre-existing config file. */
|
||||
fi->actions[i] = (FFlags & RPMFILE_NOREPLACE)
|
||||
? FA_ALTNAME : FA_SKIP;
|
||||
|
|
Loading…
Reference in New Issue