[PATCH 4/6] Hook conffile database into dpkg unpack/configure/remove stages
In process_archive() (src/processarc.c), clean out the staged ("-new")
version of the package's conffile database.
In tarobject() (src/archives.c), some slight of hand is performed with
the backend pipe of the struct tarcontext to intercept conffiles and
place a copy in the staged ("new") conffile database for the package
before extracting it as usual.
In deferred_configure() (src/configure.c), commit the package's staged
conffile database is committed.
And finally, in checkforremoval() (src/remove.c), remove the package's
conffile database.
---
src/archives.c | 18 +++++++++++++++---
src/configure.c | 5 +++++
src/processarc.c | 4 ++++
src/remove.c | 3 +++
4 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/src/archives.c b/src/archives.c
index 48221a7..692c4ba 100644
--- a/src/archives.c
+++ b/src/archives.c
@@ -58,6 +58,7 @@ static security_context_t scontext = NULL;
#include "filesdb.h"
#include "main.h"
#include "archives.h"
+#include "conffiledb.h"
#define MAXCONFLICTORS 20
@@ -360,7 +361,7 @@ int tarobject(struct TarInfo *ti) {
struct conffile *conff;
struct tarcontext *tc= (struct tarcontext*)ti->UserData;
- int statr, i, existingdirectory, keepexisting;
+ int statr, i, existingdirectory, keepexisting, copyfd;
ssize_t r;
struct stat stab, stabtmp;
char databuf[TARBLKSZ];
@@ -623,10 +624,21 @@ int tarobject(struct TarInfo *ti) {
}
#endif /* WITH_SELINUX */
-
+ /* in the case of a conffile we may want to extract the file somewhere
+ * else first, thus we use a "middleman" variable to keep the code clean
+ * and generalizable
+ */
+ copyfd = tc->backendpipe;
/* Extract whatever it is as .dpkg-new ... */
switch (ti->Type) {
case NormalFile0: case NormalFile1:
+ /* if the file is a conffile... */
+ if (nifd->namenode->flags & fnnf_new_conff) {
+ conffiledb_register_new_conffile(tc->pkg->name, fnamevb.buf, copyfd,
+ ti->Size);
+ copyfd = conffiledb_get_conffile(tc->pkg->name, fnamevb.buf,
+ conffiledb_base_new);
+ }
/* We create the file with mode 0 to make sure nobody can do anything with
* it until we apply the proper mode, which might be a statoverride.
*/
@@ -637,7 +649,7 @@ int tarobject(struct TarInfo *ti) {
debug(dbg_eachfiledetail,"tarobject NormalFile[01] open size=%lu",
(unsigned long)ti->Size);
{ char fnamebuf[256];
- fd_fd_copy(tc->backendpipe, fd, ti->Size,
+ fd_fd_copy(copyfd, fd, ti->Size,
_("backend dpkg-deb during `%.255s'"),
path_quote_filename(fnamebuf, ti->Name, 256));
}
diff --git a/src/configure.c b/src/configure.c
index d01a856..8d69c66 100644
--- a/src/configure.c
+++ b/src/configure.c
@@ -50,6 +50,7 @@
#include <dpkg/file.h>
#include "filesdb.h"
+#include "conffiledb.h"
#include "main.h"
static int conffoptcells[2][2] = {
@@ -353,6 +354,10 @@ deferred_configure(struct pkginfo *pkg)
for (conff = pkg->installed.conffiles; conff; conff = conff->next)
deferred_configure_conffile(pkg, conff);
+ /* commit the new conffiledb for this package */
+ conffiledb_commit(pkg->name, conffiledb_base_new,
+ conffiledb_base_current);
+
pkg->status = stat_halfconfigured;
}
diff --git a/src/processarc.c b/src/processarc.c
index 2d6f320..15dd93a 100644
--- a/src/processarc.c
+++ b/src/processarc.c
@@ -48,6 +48,7 @@
#include "filesdb.h"
#include "main.h"
#include "archives.h"
+#include "conffiledb.h"
void process_archive(const char *filename) {
static const struct TarFunctions tf = {
@@ -316,6 +317,9 @@ void process_archive(const char *filename) {
* OK, we're going ahead.
*/
+ /* make sure the new conffiles dir does not exist at this point */
+ conffiledb_remove(pkg->name, conffiledb_base_new);
+
trig_activate_packageprocessing(pkg);
strcpy(cidirrest, TRIGGERSCIFILE);
trig_parse_ci(cidir, NULL, trig_cicb_statuschange_activate, pkg);
diff --git a/src/remove.c b/src/remove.c
index 44ff139..12e085e 100644
--- a/src/remove.c
+++ b/src/remove.c
@@ -42,6 +42,7 @@
#include <dpkg/myopt.h>
#include "filesdb.h"
+#include "conffiledb.h"
#include "main.h"
static void checkforremoval(struct pkginfo *pkgtoremove,
@@ -490,6 +491,8 @@ static void removal_bulk_remove_configfiles(struct pkginfo *pkg) {
pop_cleanup(ehflag_normaltidy); /* closedir */
}
+ /* remove the current conffile db for this package */
+ conffiledb_remove(pkg->name, conffiledb_base_current);
pkg->installed.conffiles = NULL;
modstatdb_note(pkg);
--
1.6.4.3
Reply to: