[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

frontend switching for cdebconf



Hello,

for various reasons [1] it is useful that we can switch the frontend of
cdebconf during the install process. I have a patch attached that
enhances cdebconf with this capability. Usage is simple, before each GO,
cdebconf checks whether the value of a question debconf/frontend differs
from the currently used frontend.

If this is so, cdebconf destroys the old frontend, creates a new one and
asks the question(s) of the GO-round with the new frontend.

Switching the frontend is then done with a simple setting of the above
question.

A little drawback: If the loading of the new frontend fails, cdebconf
will presently die. A fallback to the previous frontend would be
desirable but that involves quite a bit of restructuring.

Please test the patch and give comments. At this point I would like to
advertise for testing my other cdebconf patch, which was described in my
mail "Custom widgets for cdebconf". Theses two patches (or an
alternative) are essential for the implemetation of a graphical
installer.

Regards,
Sebastian

[1] E.g. these reasons:
     1. On the floppy we can drop the newt drontend, starting only with
        the text frontend. Do all the stuff for loading modules from a
        second floppy automatically, include the newt frontend there and
        switch to using it. That will save space on the first floppy.
     2. Since there is no way to put all prerequisites for a graphical
        installer onto one boot image, we need frontend switching for
        the inclusion of a graphical installer.

-- 
PGP-Key: http://www.mmweg.rwth-aachen.de/~sebastian.ley/public.key
Fingerprint: A46A 753F AEDC 2C01 BE6E  F6DB 97E0 3309 9FD6 E3E6
diff -u -r1.6 cdebconf-udeb.templates
--- debian/cdebconf-udeb.templates	30 Jul 2003 07:28:58 -0000	1.6
+++ debian/cdebconf-udeb.templates	4 Sep 2003 17:12:29 -0000
@@ -17,3 +17,9 @@
  .
  For example, this question is of medium priority, and if your priority
  were already 'high' or 'critical', you wouldn't see this question.
+
+Template: debconf/frontend
+Type: string
+Description: Frontend to use
+ This is an internal setting. Change this setting in your script to 
+ switch the  cdebconf frontend upon the next GO command.
diff -u -r1.49 commands.c
--- src/commands.c	28 Jul 2003 15:17:47 -0000	1.49
+++ src/commands.c	4 Sep 2003 17:12:29 -0000
@@ -6,6 +6,8 @@
 #include "template.h"
 #include "strutl.h"
 
+#include <dlfcn.h>
+
 #define CHECKARGC(pred) \
 ({\
     char *out; \
@@ -183,9 +185,30 @@
     char *argv[3];
     int argc;
     char *out;
+    char *running_frontend = NULL;
+    char *requested_frontend = NULL;
+    struct question *q;
 
     argc = strcmdsplit(arg, argv, DIM(argv) - 1);
     CHECKARGC(== 0);
+
+    q = mod->questions->methods.get(mod->questions, "debconf/frontend");
+    if (q)
+	requested_frontend = question_getvalue(q, "");
+    question_deref(q);
+
+    running_frontend = getenv("DEBIAN_FRONTEND");
+
+    if (requested_frontend && strcmp(running_frontend, requested_frontend) != 0) {
+	q = mod->frontend->questions;
+	mod->frontend->methods.shutdown(mod->frontend);
+	dlclose(mod->frontend->handle);
+	DELETE(mod->frontend);
+	setenv("DEBIAN_FRONTEND",requested_frontend,1);
+	mod->frontend = frontend_new(mod->config, mod->templates, mod->questions);
+	mod->frontend->questions = q;
+    }
+
     if (mod->frontend->methods.go(mod->frontend) == CMDSTATUS_GOBACK)
     {
         asprintf(&out, "%u backup", CMDSTATUS_GOBACK);
diff -u -r1.22 debconf.c
--- src/debconf.c	4 May 2003 09:09:23 -0000	1.22
+++ src/debconf.c	4 Sep 2003 17:12:29 -0000
@@ -40,14 +40,14 @@
 
 static void cleanup()
 {
-	if (frontend != NULL)
-		frontend_delete(frontend);
-	if (questions != NULL)
-		question_db_delete(questions);
-	if (templates != NULL)
-		template_db_delete(templates);
-	if (config != NULL)
-		config_delete(config);
+	if (confmodule->frontend != NULL)
+		frontend_delete(confmodule->frontend);
+	if (confmodule->questions != NULL)
+		question_db_delete(confmodule->questions);
+	if (confmodule->templates != NULL)
+		template_db_delete(confmodule->templates);
+	if (confmodule->config != NULL)
+		config_delete(confmodule->config);
 }
 
 void sighandler(int sig)
@@ -119,8 +119,10 @@
 	/* initialize database and frontend modules */
     if ((templates = template_db_new(config, NULL)) == 0)
         DIE("Cannot initialize DebConf template database");
+    	templates->methods.load(templates);
 	if ((questions = question_db_new(config, templates, NULL)) == 0)
 		DIE("Cannot initialize DebConf configuration database");
+	questions->methods.load(questions);
 	if ((frontend = frontend_new(config, templates, questions)) == 0)
 		DIE("Cannot initialize DebConf frontend");
 	/* set title */
@@ -137,10 +139,6 @@
 		snprintf(buf, sizeof(buf), "Configuring %s", pkg);
 		frontend->methods.set_title(frontend, buf);
 	}
-
-	/* load templates and config */
-	templates->methods.load(templates);
-        questions->methods.load(questions);
 
 	/* startup the confmodule; run the config script and talk to it */
 	confmodule = confmodule_new(config, templates, questions, frontend);
diff -u -r1.21 frontend.c
--- src/frontend.c	11 May 2003 13:43:22 -0000	1.21
+++ src/frontend.c	4 Sep 2003 17:12:29 -0000
@@ -122,6 +122,7 @@
 	struct frontend_module *mod;
 	char tmp[256];
 	const char *modpath, *modname;
+	struct question *q;
 
     modname = getenv("DEBIAN_FRONTEND");
     if (modname == NULL)
@@ -144,6 +145,10 @@
         DIE("Frontend instance driver not defined (%s)", tmp);
 
     setenv("DEBIAN_FRONTEND",modname,1);
+    q = qdb->methods.get(qdb, "debconf/frontend");
+    if (q)
+	question_setvalue(q, modname);
+    question_deref(q);
     snprintf(tmp, sizeof(tmp), "%s/%s.so", modpath, modname);
 	if ((dlh = dlopen(tmp, RTLD_NOW)) == NULL)
 		DIE("Cannot load frontend module %s: %s", tmp, dlerror());

Reply to: