4.0.4-alt98.1

- alt97.M50 release series is for branch 5.0, alt98 is for Sisyphus.
- Updated %config algorithm to avoid unnecessary *.rpmnew, *.rpmsave,
  and *.rpmorig files (credits: Panu Matilainen, Tomas Mraz).
  + If new package keeps the same config file, updating the file on disk
    is skipped (rhbz#194246).  This provides limited support for replacing
    config files with custom symbolic links.
  + If pre-existing file is the same as the one being installed for
    the first time, backup action is suppress (rhbz#128622).
  + Backup action is also disabled but for regular files and symlinks.
This commit is contained in:
Alexey Tourbin 2009-03-09 21:08:59 +03:00
commit 356d3d7027
5 changed files with 102 additions and 85 deletions

View File

@ -161,11 +161,11 @@ int domd5(const char * fn, /*@out@*/ unsigned char * digest, int asAscii)
* @return 0 on success, 1 on error
*/
/*@unused@*/ static inline
int mdfile(const char * fn, /*@out@*/ unsigned char * digest)
int mdfile(const char * fn, /*@out@*/ char * digest)
/*@globals fileSystem@*/
/*@modifies digest, fileSystem @*/
{
return domd5(fn, digest, 1);
return domd5(fn, (unsigned char *) digest, 1);
}
/**

View File

@ -782,88 +782,66 @@ static int sharedCmp(const void * one, const void * two)
return 0;
}
static fileAction decideFileFate(const char * dirName,
const char * baseName, short dbMode,
const char * dbMd5, const char * dbLink, short newMode,
const char * newMd5, const char * newLink, int newFlags,
rpmtransFlags transFlags)
static fileAction decideConfigFate(TFI_t dbfi, const int dbix,
TFI_t newfi, const int newix, rpmtransFlags transFlags)
/*@*/
{
char buffer[1024];
const char * dbAttr, * newAttr;
fileTypes dbWhat, newWhat, diskWhat;
const char *dn = newfi->dnl[newfi->dil[newix]];
const char *bn = newfi->bnl[newix];
char *fn = alloca(strlen(dn) + strlen(bn) + 1);
(void) stpcpy( stpcpy(fn, dn), bn);
struct stat sb;
int i, rc;
int save = (newFlags & RPMFILE_NOREPLACE) ? FA_ALTNAME : FA_SAVE;
char * filespec = alloca(strlen(dirName) + strlen(baseName) + 1);
(void) stpcpy( stpcpy(filespec, dirName), baseName);
if (lstat(filespec, &sb)) {
if (lstat(fn, &sb)) {
/*
* The file doesn't exist on the disk. Create it unless the new
* package has marked it as missingok, or allfiles is requested.
*/
if (!(transFlags & RPMTRANS_FLAG_ALLFILES) &&
(newFlags & RPMFILE_MISSINGOK)) {
rpmMessage(RPMMESS_DEBUG, _("%s skipped due to missingok flag\n"),
filespec);
(newfi->fflags[newix] & RPMFILE_MISSINGOK)) {
rpmMessage(RPMMESS_DEBUG, _("%s skipped due to missingok flag\n"), fn);
return FA_SKIP;
} else {
return FA_CREATE;
}
}
diskWhat = whatis(sb.st_mode);
dbWhat = whatis(dbMode);
newWhat = whatis(newMode);
fileTypes diskWhat = whatis(sb.st_mode);
fileTypes dbWhat = whatis(dbfi->fmodes[dbix]);
fileTypes newWhat = whatis(newfi->fmodes[newix]);
/* RPM >= 2.3.10 shouldn't create config directories -- we'll ignore
them in older packages as well */
if (newWhat == XDIR) {
if (newWhat == XDIR)
return FA_CREATE;
}
if (diskWhat != newWhat) {
return save;
} else if (newWhat != dbWhat && diskWhat != dbWhat) {
return save;
} else if (dbWhat != newWhat) {
return FA_CREATE;
} else if (dbWhat != LINK && dbWhat != REG) {
return FA_CREATE;
}
if (dbWhat == REG) {
rc = domd5(filespec, buffer, 1);
if (rc) {
/* assume the file has been removed, don't freak */
return FA_CREATE;
/* this order matters - we'd prefer to CREATE the file if at all
possible in case something else (like the timestamp) has changed */
if (diskWhat == REG) {
char mdsum[50];
if (mdfile(fn, mdsum) != 0)
return FA_CREATE; /* assume file has been removed */
if (strcmp(dbfi->fmd5s[dbix], mdsum) == 0)
return FA_CREATE; /* unmodified config file, replace. */
}
dbAttr = dbMd5;
newAttr = newMd5;
} else /* dbWhat == LINK */ {
memset(buffer, 0, sizeof(buffer));
i = readlink(filespec, buffer, sizeof(buffer) - 1);
if (i == -1) {
/* assume the file has been removed, don't freak */
return FA_CREATE;
if (newWhat == REG) {
if (strcmp(dbfi->fmd5s[dbix], newfi->fmd5s[newix]) == 0)
return FA_SKIP; /* identical file, don't bother. */
}
dbAttr = dbLink;
newAttr = newLink;
}
/* this order matters - we'd prefer to CREATE the file if at all
possible in case something else (like the timestamp) has changed */
if (!strcmp(dbAttr, buffer)) {
/* this config file has never been modified, so just replace it */
return FA_CREATE;
}
if (!strcmp(dbAttr, newAttr)) {
/* this file is the same in all versions of this package */
return FA_SKIP;
if (dbWhat == LINK) {
if (diskWhat == LINK) {
char linkto[PATH_MAX+1] = "";
if (readlink(fn, linkto, sizeof(linkto) - 1) < 0)
return FA_CREATE;
if (strcmp(dbfi->flinks[dbix], linkto) == 0)
return FA_CREATE;
}
if (newWhat == LINK) {
if (strcmp(dbfi->flinks[dbix], newfi->flinks[newix]) == 0)
return FA_SKIP;
}
}
/*
@ -872,7 +850,50 @@ static fileAction decideFileFate(const char * dirName,
* be nice if RPM was smart enough to at least try and
* merge the difference ala CVS, but...
*/
return save;
if (newfi->fflags[newix] & RPMFILE_NOREPLACE)
return FA_ALTNAME;
if (diskWhat != REG && diskWhat != LINK)
return FA_CREATE;
return FA_SAVE;
}
static int configConflict(TFI_t fi, const int ix)
{
if ((fi->fflags[ix] & RPMFILE_CONFIG) == 0)
return 0;
const char *bn = fi->bnl[ix];
const char *dn = fi->dnl[fi->dil[ix]];
char *fn = alloca(strlen(dn) + strlen(bn) + 1);
(void) stpcpy( stpcpy(fn, dn), bn);
struct stat sb;
if (lstat(fn, &sb) != 0)
return 0;
fileTypes diskWhat = whatis(sb.st_mode);
fileTypes newWhat = whatis(fi->fmodes[ix]);
if (diskWhat == REG && newWhat == REG) {
char mdsum[50];
if (mdfile(fn, mdsum) != 0)
return 0; /* assume file has been removed */
if (strcmp(fi->fmd5s[ix], mdsum) == 0)
return 0; /* unmodified config file */
}
if (diskWhat == LINK && newWhat == LINK) {
char linkto[PATH_MAX+1] = "";
if (readlink(fn, linkto, sizeof(linkto) - 1) < 0)
return 0;
if (strcmp(fi->flinks[ix], linkto) == 0)
return 0;
}
if (fi->fflags[ix] & RPMFILE_NOREPLACE)
return 1;
if (diskWhat != REG && diskWhat != LINK)
return 0;
return 1;
}
static int filecmp(const TFI_t fi1, const int ix1, const TFI_t fi2, const int ix2)
@ -967,19 +988,8 @@ static int handleInstInstalledFiles(const TFI_t fi, /*@null@*/ rpmdb db,
}
}
if (isCfgFile) {
fi->actions[fileNum] = decideFileFate(
fi->dnl[fi->dil[fileNum]],
fi->bnl[fileNum],
otherFi->fmodes[otherFileNum],
otherFi->fmd5s[otherFileNum],
otherFi->flinks[otherFileNum],
fi->fmodes[fileNum],
fi->fmd5s[fileNum],
fi->flinks[fileNum],
fi->fflags[fileNum],
transFlags);
}
if (isCfgFile)
fi->actions[fileNum] = decideConfigFate(otherFi, otherFileNum, fi, fileNum, transFlags);
fi->replacedSizes[fileNum] = otherFi->fsizes[otherFileNum];
}
@ -1129,13 +1139,11 @@ static void handleOverlappedFiles(TFI_t fi, hashTable ht,
switch (fi->type) {
case TR_ADDED:
{ struct stat sb;
if (otherPkgNum < 0) {
/* XXX is this test still necessary? */
if (fi->actions[i] != FA_UNKNOWN)
break;
if ((fi->fflags[i] & RPMFILE_CONFIG) &&
!lstat(filespec, &sb)) {
if (configConflict(fi, i)) {
/* Here is a non-overlapped pre-existing config file. */
fi->actions[i] = (fi->fflags[i] & RPMFILE_NOREPLACE)
? FA_ALTNAME : FA_BACKUP;
@ -1154,14 +1162,14 @@ static void handleOverlappedFiles(TFI_t fi, hashTable ht,
/* Try to get the disk accounting correct even if a conflict. */
fixupSize = recs[otherPkgNum]->fsizes[otherFileNum];
if ((fi->fflags[i] & RPMFILE_CONFIG) && !lstat(filespec, &sb)) {
if (configConflict(fi, i)) {
/* Here is an overlapped pre-existing config file. */
fi->actions[i] = (fi->fflags[i] & RPMFILE_NOREPLACE)
? FA_ALTNAME : FA_SKIP;
} else {
fi->actions[i] = FA_CREATE;
}
} break;
break;
case TR_REMOVED:
if (otherPkgNum >= 0) {
/* Here is an overlapped added file we don't want to nuke. */

View File

@ -143,8 +143,8 @@ static PyObject * hdrVerifyFile(hdrObject * s, PyObject * args) {
&count);
}
char buf[2048];
if (mdfile(s->fileList[fileNumber], (unsigned char *) buf)) {
char buf[50];
if (mdfile(s->fileList[fileNumber], buf)) {
strcpy(buf, "(unknown)");
}

View File

@ -31,8 +31,6 @@ extern int _rpmio_debug;
#define PyObject_HEAD int _PyObjectHead
#endif
extern int mdfile(const char *fn, unsigned char *digest);
void initrpm(void);
/* from lib/misc.c */

View File

@ -4,7 +4,7 @@
Name: %rpm_name
Version: %rpm_version
Release: alt96.16
Release: alt98.1
%define ifdef() %if %{expand:%%{?%{1}:1}%%{!?%{1}:0}}
%define get_dep() %(rpm -q --qf '%%{NAME} >= %%|SERIAL?{%%{SERIAL}:}|%%{VERSION}-%%{RELEASE}' %1 2>/dev/null || echo '%1 >= unknown')
@ -547,6 +547,17 @@ fi
%endif #with contrib
%changelog
* Mon Mar 09 2009 Alexey Tourbin <at@altlinux.ru> 4.0.4-alt98.1
- alt97.M50 release series is for branch 5.0, alt98 is for Sisyphus.
- Updated %%config algorithm to avoid unnecessary *.rpmnew, *.rpmsave,
and *.rpmorig files (credits: Panu Matilainen, Tomas Mraz).
+ If new package keeps the same config file, updating the file on disk
is skipped (rhbz#194246). This provides limited support for replacing
config files with custom symbolic links.
+ If pre-existing file is the same as the one being installed for
the first time, backup action is suppress (rhbz#128622).
+ Backup action is also disabled but for regular files and symlinks.
* Wed Feb 25 2009 Dmitry V. Levin <ldv@altlinux.org> 4.0.4-alt96.16
- platform.in: Imported %%makeinstall_std macro from rpm-build-perl.
- 0common-files.req.list: Removed /etc/tex-fonts.d directory.