diff options
author | Pavlina Moravcova Varekova <pmoravco@redhat.com> | 2017-04-19 18:16:18 +0200 |
---|---|---|
committer | Pavlina Moravcova Varekova <pmoravco@redhat.com> | 2017-04-19 18:16:18 +0200 |
commit | b9178e43c355e1b60280937737d96a50f7597c1e (patch) | |
tree | beca606fee93cba1ae92e60d2a9b324885211a49 /lib/rpmfi.c | |
parent | a239ddefa90575ce80ed4436beb4005a97e32644 (diff) | |
download | rpm-pavlinas_p122.tar.gz |
Add %mutable and %noupdate update policies (#152)pavlinas_p122
%mutable
- is defined for files and links. It means update until modified.
In more details:
- if a file/link is the same as in new package then touch it,
- if a file/link is the same as in old package then upgrade it as "normal" file/link,
- else do nothing.
%noupdate
- is defined for all file types used internally by rpm. It is for cases, where packager wants just the initial content, never to be touched by rpm again.
In more details:
- if the file does not exist, then create it,
- if the file exists, then do nothing.
Diffstat (limited to 'lib/rpmfi.c')
-rw-r--r-- | lib/rpmfi.c | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/lib/rpmfi.c b/lib/rpmfi.c index 320296a4d..93970ea05 100644 --- a/lib/rpmfi.c +++ b/lib/rpmfi.c @@ -1089,6 +1089,142 @@ exit: return action; } + +rpmFileAction rpmfilesSetMutableAction(rpmfiles ofi, int oix, + rpmfiles nfi, int nix) +{ + char * fn = rpmfilesFN(nfi, nix); + rpmFileTypes diskWhat; + struct stat sb; + int action = FA_UNKNOWN; + + /* The file doesn't exist on the disk. Create it. */ + if (lstat(fn, &sb)) { + action = FA_CREATE; + goto exit; + } + + diskWhat = rpmfiWhatis((rpm_mode_t)sb.st_mode); + + if ((diskWhat == REG) && + (rpmfiWhatis(rpmfilesFMode(ofi, oix)) == REG) && + (rpmfiWhatis(rpmfilesFMode(nfi, nix)) == REG) ) { + char buffer[1024]; + int oalgo, nalgo; + size_t odiglen, ndiglen; + const unsigned char * odigest, * ndigest; + const char * nfuser, * ofuser; + uid_t uid; + const char * nfgroup, * ofgroup; + gid_t gid; + + /* If the file on disk is identical to the one in new pkg, then touch it */ + if (rpmfilesFSize(nfi, nix) == sb.st_size) { + + if (rpmfilesFMode(nfi, nix) == ((rpm_mode_t)sb.st_mode)) { + + nfuser = rpmfilesFUser(nfi, nix); + if ((nfuser && rpmugUid(nfuser, &uid) == 0) && + (uid == sb.st_uid)) { + + nfgroup = rpmfilesFGroup(nfi, nix); + if ((nfgroup && rpmugGid(nfgroup, &gid) == 0) && + (gid == sb.st_gid)) { + + ndigest = rpmfilesFDigest(nfi, nix, &nalgo, &ndiglen); + if ((!rpmDoDigest(nalgo, fn, 0, (unsigned char *)buffer, NULL)) && + (ndigest && memcmp(ndigest, buffer, ndiglen) == 0)) { + action = FA_TOUCH; + goto exit; + } + } + } + } + } + + /* If the file on disk is identical to the one in old pkg, then create it */ + if (rpmfilesFSize(ofi, oix) == sb.st_size) { + + if (rpmfilesFMode(ofi, oix) == ((rpm_mode_t)sb.st_mode)) { + + ofuser = rpmfilesFUser(ofi, oix); + if ((ofuser && rpmugUid(ofuser, &uid) == 0) && + (uid == sb.st_uid)) { + + ofgroup = rpmfilesFGroup(ofi, oix); + if ((ofgroup && rpmugGid(ofgroup, &gid) == 0) && + (gid == sb.st_gid)) { + + odigest = rpmfilesFDigest(ofi, oix, &oalgo, &odiglen); + if ((!rpmDoDigest(oalgo, fn, 0, (unsigned char *)buffer, NULL)) && + (odigest && memcmp(odigest, buffer, odiglen) == 0)) { + action = FA_CREATE; + goto exit; + } + } + } + } + } + + /* file is changed, let it be */ + action = FA_SKIP; + + } else if ((diskWhat == LINK) && + (rpmfiWhatis(rpmfilesFMode(ofi, oix)) == LINK) && + (rpmfiWhatis(rpmfilesFMode(nfi, nix)) == LINK) ) { + + char buffer[1024]; + const char * oFLink, * nFLink; + + /* if the link on disk is identical to the one in new pkg, then touch it */ + nFLink = rpmfilesFLink(nfi, nix); + + ssize_t link_len = readlink(fn, buffer, sizeof(buffer) - 1); + if (link_len != -1) { + buffer[link_len] = '\0'; + if (nFLink && rstreq(nFLink, buffer)) { + action = FA_TOUCH; + goto exit; + } + } + + /* if the link on disk is identical to the one in old pkg, then create it */ + oFLink = rpmfilesFLink(ofi, oix); + if ((link_len != -1) && (oFLink && rstreq(oFLink, buffer))) { + action = FA_CREATE; + goto exit; + } + + /* link is changed, let it be */ + action = FA_SKIP; + } + +exit: + free(fn); + return action; + } + + +rpmFileAction rpmfilesSetNoupdateAction(rpmfiles ofi, int oix, + rpmfiles nfi, int nix) +{ + char * fn = rpmfilesFN(nfi, nix); + struct stat sb; + int action = FA_UNKNOWN; + + if (lstat(fn, &sb)) { + /* The file/link/ doesn't exist on the disk. Create it. */ + action = FA_CREATE; + } else { + /* The file exists, let it be. */ + action = FA_SKIP; + } + + free(fn); + return action; + } + + int rpmfilesConfigConflict(rpmfiles fi, int ix) { char * fn = NULL; |