Attached patch seems to work (mirror works in auto mode), and the small test suite I added shows it does the right thing in all 4 cases. Could use some more testing, and my caveats about this being a hacky and suboptimal approach still apply. -- see shy jo
From 2e86f33f8439682894441139873cd917ede4736b Mon Sep 17 00:00:00 2001
From: Joey Hess <joey@kodama.kitenet.net>
Date: Thu, 19 Jun 2008 18:40:13 -0400
Subject: [PATCH] noninteractive select handling
* Add a separate queue for noninteractive questions, so that things can
be done when these questions would be displayed. This is a bit hackish;
debconf's method of letting questions determine if they are interactive or
not is really better. But this doesn't need huge changes to cdebconf.
* Handle the special case of a noninteractive select with no (or a bad)
default the same as debconf does; when such a question is asked,
set the value to the first item in the select list.
Closes: #486892, #247744
---
packages/cdebconf/debian/changelog | 13 ++++
packages/cdebconf/src/commands.c | 3 +
packages/cdebconf/src/frontend.c | 91 ++++++++++++++++++++++++++-
packages/cdebconf/src/frontend.h | 5 ++
packages/cdebconf/src/test/select.config | 58 +++++++++++++++++
packages/cdebconf/src/test/select.templates | 22 +++++++
6 files changed, 191 insertions(+), 1 deletions(-)
create mode 100755 packages/cdebconf/src/test/select.config
create mode 100644 packages/cdebconf/src/test/select.templates
diff --git a/packages/cdebconf/debian/changelog b/packages/cdebconf/debian/changelog
index c24225b..75ec1df 100644
--- a/packages/cdebconf/debian/changelog
+++ b/packages/cdebconf/debian/changelog
@@ -1,3 +1,16 @@
+cdebconf (0.132) UNRELEASED; urgency=low
+
+ * Add a separate queue for noninteractive questions, so that things can
+ be done when these questions would be displayed. This is a bit hackish;
+ debconf's method of letting questions determine if they are interactive or
+ not is really better. But this doesn't need huge changes to cdebconf.
+ * Handle the special case of a noninteractive select with no (or a bad)
+ default the same as debconf does; when such a question is asked,
+ set the value to the first item in the select list.
+ Closes: #486892, #247744
+
+ -- Joey Hess <joeyh@debian.org> Thu, 19 Jun 2008 17:18:08 -0400
+
cdebconf (0.131) unstable; urgency=low
[ Frans Pop ]
diff --git a/packages/cdebconf/src/commands.c b/packages/cdebconf/src/commands.c
index 878e0b2..a5235c2 100644
--- a/packages/cdebconf/src/commands.c
+++ b/packages/cdebconf/src/commands.c
@@ -54,6 +54,8 @@ command_input(struct confmodule *mod, char *arg)
if (visible)
visible = mod->frontend->methods.add(mod->frontend, q);
+ else
+ mod->frontend->methods.add_noninteractive(mod->frontend, q);
if (q->priority != NULL)
free(q->priority);
@@ -220,6 +222,7 @@ command_go(struct confmodule *mod, char *arg)
mod->frontend->questions = q;
}
+ mod->frontend->methods.go_noninteractive(mod->frontend);
ret = mod->frontend->methods.go(mod->frontend);
if (ret == CMDSTATUS_GOBACK || mod->backed_up != 0)
{
diff --git a/packages/cdebconf/src/frontend.c b/packages/cdebconf/src/frontend.c
index 59d83fe..3a21bf9 100644
--- a/packages/cdebconf/src/frontend.c
+++ b/packages/cdebconf/src/frontend.c
@@ -4,6 +4,8 @@
#include "database.h"
#include "frontend.h"
#include "question.h"
+#include "template.h"
+#include "strutl.h"
#include <dlfcn.h>
#include <string.h>
@@ -28,7 +30,7 @@ static int frontend_add(struct frontend *obj, struct question *q)
qlast = qlast->next;
}
/* Question asked twice. debconf ignores the second question and
- will we. */
+ so will we. */
if (qlast == q)
return DC_OK;
qlast->next = q;
@@ -40,11 +42,88 @@ static int frontend_add(struct frontend *obj, struct question *q)
return DC_OK;
}
+static int frontend_add_noninteractive(struct frontend *obj, struct question *q)
+{
+ struct question *qlast;
+ ASSERT(q != NULL);
+ ASSERT(q->prev == NULL);
+ ASSERT(q->next == NULL);
+
+ //INFO(INFO_DEBUG, "adding noninteractive question");
+
+ qlast = obj->questions_noninteractive;
+ if (qlast == NULL)
+ {
+ obj->questions_noninteractive = q;
+ }
+ else
+ {
+ while (qlast != q && qlast->next != NULL)
+ {
+ qlast = qlast->next;
+ }
+ qlast->next = q;
+ q->prev = qlast;
+ }
+
+ question_ref(q);
+
+ return DC_OK;
+}
+
static int frontend_go(struct frontend *obj)
{
return DC_OK;
}
+static int frontend_go_noninteractive(struct frontend *obj)
+{
+ struct question *q = obj->questions_noninteractive;
+
+ while (q != NULL) {
+ char *type = q->template->type;
+
+ //INFO(INFO_DEBUG, "frontend_go_noninteractive; type %s", type);
+
+ /* This is a hack to make noninteractive selects be set to
+ * the first item in the select list if their value is not
+ * set, or is set to something not in the list. This is for
+ * consistency with debconf. */
+ if (strcmp(type, "select") == 0) {
+ int i, ok=0;
+ char **choices=NULL;
+ char *val = (char *) question_getvalue(q, "");
+ int count = strgetargc(q_get_choices_vals(obj, q));
+ if (count) {
+ choices = malloc(sizeof(char *) * count);
+ if (strchoicesplit(q_get_choices_vals(obj, q), choices, count) != count)
+ return DC_NOTOK;
+
+ for (i = 0; i < count; i++) {
+ if (val && strcmp(val, choices[i]) == 0) {
+ ok=1;
+ break;
+ }
+ }
+ }
+
+ if (! ok) {
+ if (count)
+ question_setvalue(q, choices[0]);
+ else
+ question_setvalue(q, "");
+ }
+
+ if (choices)
+ free(choices);
+ }
+
+ q = q->next;
+ }
+
+ return DC_OK;
+}
+
static void frontend_clear(struct frontend *obj)
{
struct question *q;
@@ -56,6 +135,14 @@ static void frontend_clear(struct frontend *obj)
q->next = q->prev = NULL;
question_deref(q);
}
+
+ while (obj->questions_noninteractive != NULL)
+ {
+ q = obj->questions_noninteractive;
+ obj->questions_noninteractive = obj->questions_noninteractive->next;
+ q->next = q->prev = NULL;
+ question_deref(q);
+ }
}
static int frontend_initialize(struct frontend *obj, struct configuration *cfg)
@@ -227,6 +314,8 @@ struct frontend *frontend_new(struct configuration *cfg, struct template_db *tdb
SETMETHOD(progress_step);
SETMETHOD(progress_info);
SETMETHOD(progress_stop);
+ SETMETHOD(add_noninteractive);
+ SETMETHOD(go_noninteractive);
#undef SETMETHOD
diff --git a/packages/cdebconf/src/frontend.h b/packages/cdebconf/src/frontend.h
index 2f8e1aa..04a4dd7 100644
--- a/packages/cdebconf/src/frontend.h
+++ b/packages/cdebconf/src/frontend.h
@@ -43,6 +43,9 @@ struct frontend_module {
int (*progress_step)(struct frontend *fe, int step);
int (*progress_info)(struct frontend *fe, const char *info);
void (*progress_stop)(struct frontend *fe);
+
+ int (*go_noninteractive)(struct frontend *);
+ int (*add_noninteractive)(struct frontend *, struct question *q);
};
struct frontend {
@@ -75,6 +78,8 @@ struct frontend {
struct frontend_module methods;
/* path to plugins */
char *plugin_path;
+ /* separate list of noninteractive questions */
+ struct question *questions_noninteractive;
};
struct frontend *frontend_new(struct configuration *, struct template_db *, struct question_db *);
diff --git a/packages/cdebconf/src/test/select.config b/packages/cdebconf/src/test/select.config
new file mode 100755
index 0000000..ce443c1
--- /dev/null
+++ b/packages/cdebconf/src/test/select.config
@@ -0,0 +1,58 @@
+#!/bin/sh -e
+# Testing #486892
+. ../client/confmodule
+
+debug()
+{
+ echo $* >&2
+}
+
+askquestion()
+{
+ question=$1
+ priority=$2
+ db_fset $question seen false
+ db_input $priority $question || true
+ db_go || true
+ db_get $question
+}
+
+ok=1
+
+askquestion test/select/withdefault low
+if [ "$RET" = second ]; then
+ debug "ok withdefault"
+else
+ debug "fail withdefault ($RET)"
+ ok=0
+fi
+
+askquestion test/select/nodefault low
+if [ "$RET" = first ]; then
+ debug "ok nodefault"
+else
+ debug "fail nodefault ($RET)"
+ ok=0
+fi
+
+askquestion test/select/strangedefault low
+if [ "$RET" = first ]; then
+ debug "ok nodefault"
+else
+ debug "fail nodefault ($RET)"
+ ok=0
+fi
+
+askquestion test/select/nochoices low
+if [ "$RET" = "" ]; then
+ debug "ok nochoices"
+else
+ debug "fail nochoices ($RET)"
+ ok=0
+fi
+
+if [ "$ok" ]; then
+ exit 0
+else
+ exit 1
+fi
diff --git a/packages/cdebconf/src/test/select.templates b/packages/cdebconf/src/test/select.templates
new file mode 100644
index 0000000..e2076a4
--- /dev/null
+++ b/packages/cdebconf/src/test/select.templates
@@ -0,0 +1,22 @@
+Template: test/select/withdefault
+Type: select
+Default: second
+Choices: first, second, third
+Description: select with a default value
+
+Template: test/select/nodefault
+Type: select
+Choices: first, second, third
+Description: select with no default value
+
+Template: test/select/strangedefault
+Type: select
+Default: fourth
+Choices: first, second, third
+Description: select with a strange default value
+
+Template: test/select/nochoices
+Type: select
+Default: fourth
+Choices:
+Description: select with no choices
--
1.5.5.4
Attachment:
signature.asc
Description: Digital signature