Here is an improved patch, it has been tested and looks fine.
Currently language choice is performed by a DEBCONF_LANG environment
variable.
In src/modules/db/textdb/textdb.c, the textdb_template_get_real needs
more work.

Denis
Index: debian/changelog
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/debian/changelog,v
retrieving revision 1.40
diff -u -r1.40 changelog
--- debian/changelog    6 Nov 2002 10:11:37 -0000       1.40
+++ debian/changelog    9 Nov 2002 01:21:18 -0000
@@ -29,6 +29,13 @@
     - fix confmodule.c and commands.c to not use fixed-size
       buffers. (closes: #167312)
   * Denis Barbier:
+    - change internal template structure in src/template.h in order
+      to help managing localized fields, and fix doc/modules.txt
+      accordingly
+    - define accessors to get and set template values, should be used
+      everywhere instead of direct access to structure members
+    - partially handle localized fields, only UTF-8 templates files
+      are considered
     - convert to po-debconf, set Build-Depends: debhelper (>= 4.1.13)
       to ensure that generated templates are right, and set output encoding
       to UTF-8.
Index: doc/modules.txt
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/doc/modules.txt,v
retrieving revision 1.7
diff -u -r1.7 modules.txt
--- doc/modules.txt     1 Jul 2002 06:58:37 -0000       1.7
+++ doc/modules.txt     9 Nov 2002 01:21:18 -0000
@@ -36,20 +36,37 @@
 A template has the following publically accessible fields:
 
 - char *tag: the template's tag
-- char *type: the template's type XXX can be one of ...
-- char *defaultval: the template's default value, as a string
-- char *choices: if the template's type is choices based, here the choices
-                 are listed in a single string, seperated by commas XXX right?
-- char *description: a description of the template XXX must be under ... chars?
-- char *extended_description: a longer description 
-- struct language_description *localized descriptions - has following fields:
-  - struct language_description *next: NULL or another localized description
-  - char *language: ISO tag for language XXX right?
-  - char *choices, char *description, char *extended_description: as above,
-    only in specified language
-  
+- char *type: the template's type, can be one of select, multiselect,
+              string, boolean, note, text and password
+- struct template_l10n_fields *fields - has following fields:
+  - struct template_l10n_fields *next: NULL or another localized field
+                                       structure
+  - char *language: ISO code for language (ll or ll_LL)
+  - char *defaultval: the template's default value, as a string
+  - char *choices: if the template's type is choices based, here the choices
+                   are listed in a single string, seperated by commas
+  - char *description: a description of the template XXX must be under ... chars?
+  - char *extended_description: a longer description 
+
+The first template_l10n_fields structure must always be in English, and
+its ISO code is set to C.
+
 XXX not covering "next", I assume it is private
 XXX not covering memory management or deletion
+
+Publically accessible methods:
+
+const char *lget(struct template *, const char *lang, const char *field):
+   Return a string value for given field in a language, or NULL if not found
+
+void lset(struct template *, const char *lang, const char *field, const char *value):
+   Save string value at field for a given language
+
+const char *get(struct template *, const char *field):
+   Return a string value for given field in English
+
+void set(struct template *, const char *field, const char *value):
+   Save string value at English field
 
 question API
 ~~~~~~~~~~~~
Index: src/commands.c
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/commands.c,v
retrieving revision 1.24
diff -u -r1.24 commands.c
--- src/commands.c      5 Nov 2002 02:55:13 -0000       1.24
+++ src/commands.c      9 Nov 2002 01:21:18 -0000
@@ -614,14 +614,14 @@
                if (strcmp(field, "value") == 0)
                        snprintf(out, outsize, "%u %s", CMDSTATUS_SUCCESS, q->value);
                else if (strcmp(field, "description") == 0)
-                       snprintf(out, outsize, "%u %s", CMDSTATUS_SUCCESS, 
question_description(q));
+                       snprintf(out, outsize, "%u %s", CMDSTATUS_SUCCESS, 
+question_get_translated_field(q, field));
                else if (strcmp(field, "extended_description") == 0)
                        /* NOTE: this probably is wrong, because the extended
                         * description is likely multiline
                         */
-                       snprintf(out, outsize, "%u %s", CMDSTATUS_SUCCESS, 
question_extended_description(q));
+                       snprintf(out, outsize, "%u %s", CMDSTATUS_SUCCESS, 
+question_get_translated_field(q, field));
                else if (strcmp(field, "choices") == 0)
-                       snprintf(out, outsize, "%u %s", CMDSTATUS_SUCCESS, 
question_choices(q));
+                       snprintf(out, outsize, "%u %s", CMDSTATUS_SUCCESS, 
+question_get_translated_field(q, field));
                else
                        snprintf(out, outsize, "%u %s does not exist", 
CMDSTATUS_BADPARAM, field);
        }
Index: src/question.c
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/question.c,v
retrieving revision 1.12
diff -u -r1.12 question.c
--- src/question.c      7 Aug 2002 16:34:01 -0000       1.12
+++ src/question.c      9 Nov 2002 01:21:18 -0000
@@ -43,6 +43,8 @@
 #include "configuration.h"
 #include "database.h"
 
+static char cur_lang[6] = {0};
+
 struct question *question_new(const char *tag)
 {
        struct question *q;
@@ -228,126 +230,44 @@
        return DC_OK;
 }
 
-/*
- * Function: getlanguage
- * Input: none
- * Output: const char* (size == 3) the language code of the currently 
- *         selected language
- * Description: find the currently selected language
- * Assumptions: config_new and database_new succeeds, 
- *              debian-installer/language exists
- */
-
-const char *getlanguage()
-{
-#if 0   /* FIXME */
-    static struct database *db = NULL;
-    static struct configuration *config = NULL;
-       static char language[3];
-       /* We need to directly access the configuration, since I couldn't
-          get debconfclient to work from in here. */
-       struct question *q2 = NULL;
-        memset(language,'\0',3);
-
-       if (! config) /* Then db isn't set either.. */
-       {
-               config = config_new();
-                if (config == 0) 
-                        DIE("Error initializing configuration item (%s %d)", 
__FILE__,__LINE__);
-               if (config->read(config, DEBCONFCONFIG) == 0)
-                       DIE("Error reading configuration information");
-               if ((db = database_new(config)) == 0)
-                       DIE("Cannot initialize DebConf database");
-               db->load(db);
-       }
-       q2 = db->question_get(db, "debian-installer/language");
-        if (q2 != NULL) {
-                if (q2->value != NULL)
-                        snprintf(language,3,"%.2s",q2->value);
-                question_deref(q2);
-        }
-       return language;
-#else
-    return "";
-#endif
-}
-
-const char *question_description(struct question *q)
-{
-       static char buf[4096] = {0};
-       struct language_description *langdesc;
-
-       langdesc = q->template->localized_descriptions;
-       while (langdesc)
-       {
-               if (strcmp(langdesc->language,getlanguage()) == 0) 
-               {
-                       question_expand_vars(q, langdesc->description, buf, 
sizeof(buf));
-                       return buf;
-               }
-               langdesc = langdesc->next;
-       }
-       question_expand_vars(q, q->template->description, buf, sizeof(buf));
-       return buf;
-}
-
-const char *question_extended_description(struct question *q)
-{
-       static char buf[4096] = {0};
-       question_expand_vars(q, q->template->extended_description, buf, sizeof(buf));
-       return buf;
-}
-
-const char *question_extended_description_translated(struct question *q)
+const char *getlanguage(void)
 {
-       static char buf[4096] = {0};
-       struct language_description *langdesc;
-
-       langdesc = q->template->localized_descriptions;
-       while (langdesc)
+       if (cur_lang[0] == 0)
        {
-               if (strcmp(langdesc->language,getlanguage()) == 0 && 
langdesc->description != NULL)
-               {
-                       question_expand_vars(q, langdesc->extended_description, buf, 
sizeof(buf));
-                       return buf;
-               }
-               langdesc = langdesc->next;
+               if (getenv("DEBCONF_LANG")) 
+                       strncpy(cur_lang, getenv("DEBCONF_LANG"), 5);
+               else
+                       strcpy(cur_lang, "C");
        }
-       question_expand_vars(q, q->template->extended_description, buf, sizeof(buf));
-       return buf;
+       return cur_lang;
 }
 
-const char *question_choices_translated(struct question *q)
+const char *question_get_field(struct question *q, const char *field)
 {
        static char buf[4096] = {0};
-       struct language_description *langdesc;
-
-       langdesc = q->template->localized_descriptions;
-       while (langdesc)
-       {
-               if (strcmp(langdesc->language,getlanguage()) == 0 && langdesc->choices 
!= NULL)
-               {
-                       question_expand_vars(q, langdesc->choices, buf, sizeof(buf));
-                       return buf;
-               }
-               langdesc = langdesc->next;
-       }
-       question_expand_vars(q, q->template->choices, buf, sizeof(buf));
+       if (strcmp(field, "default") == 0) {
+               if (q->value != 0 && *q->value != 0)
+                       return q->value;
+               else
+                       return q->template->get(q->template, field);
+       }
+       question_expand_vars(q,
+               q->template->get(q->template, field),
+               buf, sizeof(buf));
        return buf;
 }
 
-const char *question_choices(struct question *q)
+const char *question_get_translated_field(struct question *q, const char *field)
 {
        static char buf[4096] = {0};
-       question_expand_vars(q, q->template->choices, buf, sizeof(buf));
+       if (strcmp(field, "default") == 0) {
+               if (q->value != 0 && *q->value != 0)
+                       return q->value;
+               else
+                       return q->template->lget(q->template, getlanguage(), field);
+       }
+       question_expand_vars(q,
+               q->template->lget(q->template, getlanguage(), field),
+               buf, sizeof(buf));
        return buf;
 }
-
-const char *question_defaultval(struct question *q)
-{
-       if (q->value != 0 && *q->value != 0)
-               return q->value;
-       else
-               return q->template->defaultval;
-}
-
Index: src/question.h
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/question.h,v
retrieving revision 1.9
diff -u -r1.9 question.h
--- src/question.h      12 Aug 2002 13:38:34 -0000      1.9
+++ src/question.h      9 Nov 2002 01:21:18 -0000
@@ -45,10 +45,7 @@
        const char *value);
 void question_owner_add(struct question *q, const char *owner);
 void question_owner_delete(struct question *q, const char *owner);
-const char *question_description(struct question *q);
-const char *question_extended_description(struct question *q);
-const char *question_choices_translated(struct question *q);
-const char *question_choices(struct question *q);
-const char *question_defaultval(struct question *q);
+const char *question_get_field(struct question *q, const char *field);
+const char *question_get_translated_field(struct question *q, const char *field);
 
 #endif
Index: src/template.c
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/template.c,v
retrieving revision 1.8
diff -u -r1.8 template.c
--- src/template.c      1 Jul 2002 06:58:37 -0000       1.8
+++ src/template.c      9 Nov 2002 01:21:19 -0000
@@ -42,11 +42,31 @@
 
 #include <stdio.h>
 
+static const char *template_lget(struct template *t, const char *lang,
+                const char *field);
+static const char *template_get(struct template *t, const char *field);
+static void template_lset(struct template *t, const char *lang,
+                const char *field, const char *value);
+static void template_set(struct template *t, const char *field,
+                const char *value);
+static const char *template_next_lang(struct template *t, const char *l);
+
+const char *template_fields_list[] = {
+        "tag",
+        "type",
+        "default",
+        "choices",
+        "description",
+        "extended_description",
+        NULL
+};
+
 /*
  * Function: template_new
  * Input: a tag, describing which template this is.  Can be null.
  * Output: a blank template struct.  Tag is strdup-ed, so the original
            string may change without harm.
+           The fields structure is also allocated to store English fields
  * Description: allocate a new, empty struct template.
  * Assumptions: NEW succeeds
  * Todo: 
@@ -54,22 +74,40 @@
 
 struct template *template_new(const char *tag)
 {
+       struct template_l10n_fields *f = NEW(struct template_l10n_fields);
        struct template *t = NEW(struct template);
+       memset(f, 0, sizeof(struct template_l10n_fields));
+       f->language = STRDUP("C");
        memset(t, 0, sizeof(struct template));
        t->ref = 1;
        t->tag = STRDUP(tag);
+       t->get = template_get;
+       t->set = template_set;
+       t->lget = template_lget;
+       t->lset = template_lset;
+       t->next_lang = template_next_lang;
+       t->fields = f;
        return t;
 }
 
 void template_delete(struct template *t)
 {
+       struct template_l10n_fields *p, *q;
+
        DELETE(t->tag);
        DELETE(t->type);
-       DELETE(t->defaultval);
-       DELETE(t->choices);
-       DELETE(t->description);
-       DELETE(t->extended_description);
+       p = t->fields;
        DELETE(t);
+       while (p != NULL)
+       {
+               q = p->next;
+               DELETE(p->defaultval);
+               DELETE(p->choices);
+               DELETE(p->description);
+               DELETE(p->extended_description);
+               DELETE(p);
+               p = q;
+       }
 }
 
 void template_ref(struct template *t)
@@ -89,23 +127,251 @@
  * Output: a copy of the template passed as input
  * Description: duplicate a template
  * Assumptions: template_new succeeds, STRDUP succeeds.
- * Todo: Handle localization
  */
 
 struct template *template_dup(struct template *t)
 {
         struct template *ret = template_new(t->tag);
+        struct template_l10n_fields *from, *to;
+
         ret->type = STRDUP(t->type);
-        ret->defaultval = STRDUP(t->defaultval);
-        ret->choices = STRDUP(t->choices);
-        ret->description = STRDUP(t->description);
-        ret->extended_description = STRDUP(t->extended_description);
+        if (t->fields == NULL)
+                return ret;
+
+        ret->fields = NEW(struct template_l10n_fields);
+
+        from = t->fields;
+        to = ret->fields;
+        /*  Iterate over available languages  */
+        while (1)
+        {
+                to->defaultval = STRDUP(from->defaultval);
+                to->choices = STRDUP(from->choices);
+                to->description = STRDUP(from->description);
+                to->extended_description = STRDUP(from->extended_description);
+
+                if (from->next == NULL)
+                {
+                        to->next = NULL;
+                        break;
+                }
+                to->next = NEW(struct template_l10n_fields);
+                from = from->next;
+                to = to->next;
+        }
+        return ret;
+}
+
+static const char *template_field_get(struct template_l10n_fields *p,
+                const char *field)
+{
+    if (strcasecmp(field, "default") == 0)
+        return p->defaultval;
+    else if (strcasecmp(field, "choices") == 0)
+        return p->choices;
+    else if (strcasecmp(field, "description") == 0)
+        return p->description;
+    else if (strcasecmp(field, "extended_description") == 0)
+        return p->extended_description;
+    return NULL;
+}
+
+static void template_field_set(struct template_l10n_fields *p,
+                const char *field, const char *value)
+{
+    if (strcasecmp(field, "default") == 0)
+    {
+        DELETE(p->defaultval);
+        p->defaultval = STRDUP(value);
+    }
+    else if (strcasecmp(field, "choices") == 0)
+    {
+        DELETE(p->choices);
+        p->choices = STRDUP(value);
+    }
+    else if (strcasecmp(field, "description") == 0)
+    {
+        DELETE(p->description);
+        p->description = STRDUP(value);
+    }
+    else if (strcasecmp(field, "extended_description") == 0)
+    {
+        DELETE(p->extended_description);
+        p->extended_description = STRDUP(value);
+    }
+}
+
+/*
+ * Function: template_get
+ * Input: a template
+ * Input: a language name
+ * Input: a field name
+ * Output: the value of the given field in the given language, field
+ *         name may be any of type, default, choices, description and
+ *         extended_description
+ * Description: get field value
+ * Assumptions: 
+ */
+
+static const char *template_lget(struct template *t, const char *lang,
+                const char *field)
+{
+    struct template_l10n_fields *p;
+    const char *ret = NULL, *altret = NULL;
+
+    if (strcmp(lang, "C") == 0 && strcasecmp(field, "tag") == 0)
+        return t->tag;
+    else if (strcmp(lang, "C") == 0 && strcasecmp(field, "type") == 0)
+        return t->type;
+
+    p = t->fields;
+    while (p != NULL)
+    {
+        /*  Exact match  */
+        if (strcmp(p->language, lang) == 0)
+            return template_field_get(p, field);
+
+        /*  Language is xx_XX and a xx field is found  */
+        if (strlen(p->language) == 2 && strncmp(lang, p->language, 2) == 0)
+            altret = template_field_get(p, field);
+
+        p = p->next;
+    }
+    if (altret != NULL)
+        return altret;
+    if (ret)
         return ret;
+    /*  Default value  */
+    return template_field_get(t->fields, field);
+}
+
+static const char *template_get(struct template *t, const char *field)
+{
+    char *orig_field;
+    char *lang;
+    char *p;
+    const char *ret = NULL;
+
+    p = strchr(field, '-');
+    if (p == NULL)
+        return template_lget(t, "C", field);
+
+    orig_field = strdup(field);
+    lang = strchr(orig_field, '-');
+    *lang = 0;
+    lang++;
+    if (strstr(lang, ".UTF-8") == lang + 2)
+    {
+        *(lang+2) = 0;
+        ret = template_lget(t, lang, orig_field);
+    }
+    else if (strstr(lang, ".UTF-8") == lang + 5)
+    {
+        *(lang+5) = 0;
+        ret = template_lget(t, lang, orig_field);
+    }
+#ifndef NODEBUG
+    else
+        fprintf(stderr, "Unknown localized field:\n%s\n", p);
+#endif
+    free(orig_field);
+    return ret;
+}
+
+static void template_lset(struct template *t, const char *lang,
+                const char *field, const char *value)
+{
+    struct template_l10n_fields *p, *last;
+
+    if (strcmp(lang, "C") == 0 && strcasecmp(field, "tag") == 0)
+    {
+        t->tag = STRDUP(value);
+        return;
+    }
+    else if (strcmp(lang, "C") == 0 && strcasecmp(field, "type") == 0)
+    {
+        t->type = STRDUP(value);
+        return;
+    }
+
+    p = t->fields;
+    last = p;
+    while (p != NULL)
+    {
+        if (strcmp(p->language, lang) == 0)
+        {
+            template_field_set(p, field, value);
+            return;
+        }
+        last = p;
+        p = p->next;
+    }
+    p = NEW(struct template_l10n_fields);
+    memset(p, 0, sizeof(struct template_l10n_fields));
+    p->language = STRDUP(lang);
+    last->next = p;
+    template_field_set(p, field, value);
+}
+
+static void template_set(struct template *t, const char *field,
+                const char *value)
+{
+    char *orig_field;
+    char *lang;
+    char *p;
+
+    p = strchr(field, '-');
+    if (p == NULL)
+        template_lset(t, "C", field, value);
+    else
+    {
+        orig_field = strdup(field);
+        lang = strchr(orig_field, '-');
+        *lang = 0;
+        lang++;
+        if (strstr(lang, ".UTF-8") == lang + 2)
+        {
+            *(lang+2) = 0;
+            template_lset(t, lang, orig_field, value);
+        }
+        else if (strstr(lang, ".UTF-8") == lang + 5)
+        {
+            *(lang+5) = 0;
+            template_lset(t, lang, orig_field, value);
+        }
+#ifndef NODEBUG
+        else
+            fprintf(stderr, "Unknown localized field:\n%s\n", p);
+#endif
+        free(orig_field);
+    }
+}
+
+static const char *template_next_lang(struct template *t, const char *lang)
+{
+    struct template_l10n_fields *p;
+
+    if (lang == NULL)
+        return NULL;
+
+    p = t->fields;
+    while (p != NULL)
+    {
+        if (strcmp(p->language, lang) == 0)
+        {
+            if (p->next == NULL)
+                return NULL;
+            return p->next->language;
+        }
+        p = p->next;
+    }
+    return NULL;
 }
 
 struct template *template_load(const char *filename)
 {
        char buf[2048], extdesc[8192];
+       char lang[6];
        char *p, *bufp;
        FILE *fp;
        struct template *tlist = NULL, *t = 0;
@@ -130,55 +396,36 @@
                        t = template_new(p+10);
                }
                else if (strstr(p, "Type: ") == p && t != 0)
-                       t->type = strdup(p+6);
+                       template_set(t, "type", p+6);
                else if (strstr(p, "Default: ") == p && t != 0)
-                       t->defaultval = strdup(p+9);
+                       template_set(t, "default", p+9);
                else if (strstr(p, "Choices: ") == p && t != 0)
-                       t->choices = strdup(p+9);
+                       template_set(t, "choices", p+9);
                else if (strstr(p, "Choices-") == p && t != 0) 
                {
-                       struct language_description *langdesc = malloc(sizeof(struct 
language_description));
-                       struct language_description *lng_tmp = 0;
-                       memset(langdesc,0,sizeof(struct language_description));
-                       /* We assume that the language codes are
-                          always 2 characters long, */
-
-                       langdesc->language = malloc(3);
-                       snprintf(langdesc->language,3,"%.2s",p+8);
-                       
-                       langdesc->choices = strdup(p+11);
-
-                       if (t->localized_descriptions == NULL) 
+                       if (strstr(p, ".UTF-8: ") == p + 10)
+                       {
+                               strncpy(lang, p+8, 2);
+                               lang[2] = 0;
+                               template_lset(t, lang, "choices", p+18);
+                       }
+                       else if (strstr(p, ".UTF-8: ") == p + 13)
                        {
-                               t->localized_descriptions = langdesc;
+                               strncpy(lang, p+8, 5);
+                               lang[5] = 0;
+                               template_lset(t, lang, "choices", p+21);
                        }
                        else
                        {
-                               lng_tmp = t->localized_descriptions;
-                               while (lng_tmp != NULL)
-                               {
-                                       if 
(strcmp(lng_tmp->language,langdesc->language) == 0)
-                                       {
-                                               if (lng_tmp->choices)
-                                                       free(lng_tmp->choices);
-                                               lng_tmp->choices = langdesc->choices;
-                                               free(langdesc->language);
-                                               free(langdesc);
-                                               langdesc = NULL;
-                                               break;
-                                       }
-                                       lng_tmp = lng_tmp->next;
-                               }
-                               if (langdesc != NULL) 
-                               {
-                                       langdesc->next = t->localized_descriptions;
-                                       t->localized_descriptions = langdesc;
-                               }
+#ifndef NODEBUG
+                               fprintf(stderr, "Unknown localized field:\n%s\n", p);
+#endif
+                                continue;
                        }
                }
                else if (strstr(p, "Description: ") == p && t != 0)
                {
-                       t->description = strdup(p+13);
+                       template_set(t, "description", p+13);
                        extdesc[0] = 0;
                        i = fgetc(fp);
                        /* Don't use fgets unless you _need_ to, a
@@ -219,22 +466,31 @@
                                                        *bufp = ' ';
                                        }
                                        
-                               t->extended_description = strdup(extdesc);
+                               template_set(t, "extended_description", extdesc);
                        }
                }
                else if (strstr(p, "Description-") == p && t != 0)
                {
-                       struct language_description *langdesc = malloc(sizeof(struct 
language_description));
-                       struct language_description *lng_tmp = 0;
-                       memset(langdesc,0,sizeof(struct language_description));
-
-                       /* We assume that the language codes are
-                          always 2 characters long, */
-
-                       langdesc->language = malloc(3);
-                       snprintf(langdesc->language,3,"%.2s",p+12);
-                       langdesc->description = strdup(p+16);
-
+                       if (strstr(p, ".UTF-8: ") == p + 14)
+                       {
+                               strncpy(lang, p+12, 2);
+                               lang[2] = 0;
+                               template_lset(t, lang, "description", p+22);
+                       }
+                       else if (strstr(p, ".UTF-8: ") == p + 17)
+                       {
+                               strncpy(lang, p+12, 5);
+                               lang[5] = 0;
+                               template_lset(t, lang, "description", p+25);
+                       }
+                       else
+                       {
+#ifndef NODEBUG
+                               fprintf(stderr, "Unknown localized field:\n%s\n", p);
+#endif
+                                /*  Skip extended description  */
+                                lang[0] = 0;
+                       }
                        extdesc[0] = 0;
                        i = fgetc(fp);
                        /* Don't use fgets unless you _need_ to, a
@@ -273,37 +529,8 @@
                                                        *bufp = ' ';
                                        }
                                
-                               langdesc->extended_description = strdup(extdesc);
-                       }
-                       if (t->localized_descriptions == NULL) 
-                       {
-                               t->localized_descriptions = langdesc;
-                       }
-                       else
-                       {
-                               lng_tmp = t->localized_descriptions;
-                               while (lng_tmp != NULL)
-                               {
-                                       if 
(strcmp(lng_tmp->language,langdesc->language) == 0)
-                                       {
-                                               if (lng_tmp->description != NULL)
-                                                       free(lng_tmp->description);
-                                               if (lng_tmp->extended_description != 
NULL)
-                                                       
free(lng_tmp->extended_description);
-                                               lng_tmp->description = 
langdesc->description;
-                                               lng_tmp->extended_description = 
langdesc->extended_description;
-                                               free(langdesc->language);
-                                               free(langdesc);
-                                               langdesc = NULL;
-                                               break;
-                                       }
-                                       lng_tmp = lng_tmp->next;
-                               }
-                               if (langdesc != NULL) 
-                               {
-                                       langdesc->next = t->localized_descriptions;
-                                       t->localized_descriptions = langdesc;
-                               }
+                               if (lang[0] != 0)
+                                       template_lset(t, lang, "extended_description", 
+extdesc);
                        }
                }
        }
Index: src/template.h
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/template.h,v
retrieving revision 1.3
diff -u -r1.3 template.h
--- src/template.h      12 Aug 2002 13:38:34 -0000      1.3
+++ src/template.h      9 Nov 2002 01:21:19 -0000
@@ -1,13 +1,14 @@
 #ifndef _TEMPLATE_H_
 #define _TEMPLATE_H_
 
-struct language_description 
+struct template_l10n_fields
 {
        char *language;
+       char *defaultval;
+       char *choices;
        char *description;
        char *extended_description;
-       char *choices;
-       struct language_description *next;
+       struct template_l10n_fields *next;
 };
 
 struct template
@@ -15,13 +16,17 @@
        char *tag;
        unsigned int ref;
        char *type;
-       char *defaultval;
-       char *choices;
-       char *description;
-       char *extended_description;
-       struct language_description *localized_descriptions;
+       struct template_l10n_fields *fields;
        struct template *next;
+       const char *(*lget)(struct template *, const char *l, const char *f);
+       const char *(*get)(struct template *, const char *f);
+        void (*lset)(struct template *, const char *l, const char *f,
+                        const char *v);
+        void (*set)(struct template *, const char *f, const char *v);
+       const char *(*next_lang)(struct template *, const char *l);
 };
+
+extern const char *template_fields_list[];
 
 struct template *template_new(const char *tag);
 void template_delete(struct template *t);
Index: src/modules/db/rfc822db/rfc822db.c
===================================================================
RCS file: 
/cvs/debian-boot/debian-installer/tools/cdebconf/src/modules/db/rfc822db/rfc822db.c,v
retrieving revision 1.9
diff -u -r1.9 rfc822db.c
--- src/modules/db/rfc822db/rfc822db.c  3 Nov 2002 14:58:19 -0000       1.9
+++ src/modules/db/rfc822db/rfc822db.c  9 Nov 2002 01:21:19 -0000
@@ -239,7 +239,6 @@
  * Output: DC_OK/DC_NOTOK
  * Description: parse a template db file and put it into the cache
  * Assumptions: the file is in valid rfc822 format
- * TODO: handle localized templates
  */
 static int rfc822db_template_load(struct template_db *db)
 {
@@ -262,8 +261,7 @@
     {
         struct template *tmp;
         const char *name;
-        char tbuf[1024];
-        memset(&tbuf,0,1024);
+        struct rfc822_header *h;
 
         name = rfc822db_header_lookup(header, "name");
         if (name == NULL)
@@ -274,13 +272,10 @@
         }
 
         tmp = template_new(name);
+        for (h = header; h != NULL; h = h->next)
+            if (strcmp(h->header, "Name") != 0)
+                tmp->set(tmp, h->header, h->value);
 
-        tmp->type = rfc822db_header_lookup(header, "type");
-        tmp->defaultval = rfc822db_header_lookup(header, "default");
-        tmp->choices = rfc822db_header_lookup(header, "choices");
-        tmp->description = rfc822db_header_lookup(header, "description");
-        tmp->extended_description = rfc822db_header_lookup(header, 
"extended_description");
-/*  struct language_description *localized_descriptions; */
         tmp->next = NULL;
         tsearch(tmp, &dbdata->root, nodetemplatecomp);
     }
@@ -292,52 +287,54 @@
 
 void rfc822db_template_dump(const void *node, const VISIT which, const int depth)
 {
-  struct language_description *langdesc;
-  const struct template *t = (*(struct template **) node);
-  switch (which) {
-  case preorder:
-    break;
-  case endorder:
-    break;
-  case postorder: 
-  case leaf:
-        INFO(INFO_VERBOSE, "dumping template %s\n", (t)->tag);
-        
-        fprintf(outf, "Name: %s\n", escapestr((t)->tag));
-        fprintf(outf, "Type: %s\n", escapestr((t)->type));
-        if ((t)->defaultval != NULL)
-            fprintf(outf, "Default: %s\n", escapestr((t)->defaultval));
-        if ((t)->choices != NULL)
-            fprintf(outf, "Choices: %s\n", escapestr((t)->choices));
-        if ((t)->description != NULL)
-            fprintf(outf, "Description: %s\n", escapestr((t)->description));
-        if ((t)->extended_description != NULL)
-            fprintf(outf, "Extended_description: %s\n", 
escapestr((t)->extended_description));
-        
-        langdesc = (t)->localized_descriptions;
-        while (langdesc) 
+    const char *p, *lang;
+    const char **field;
+    const struct template *t = (*(struct template **) node);
+
+    switch (which) {
+    case preorder:
+        break;
+    case endorder:
+        break;
+    case postorder: 
+    case leaf:
+        p = t->get((struct template *) t, "tag");
+        INFO(INFO_VERBOSE, "dumping template %s\n", p);
+
+        for (field = template_fields_list; *field != NULL; field++)
         {
-            if (langdesc->description != NULL) 
-                fprintf(outf, "Description-%s: %s\n", 
-                    langdesc->language, 
-                    escapestr(langdesc->description));
-            
-            if (langdesc->extended_description != NULL)
-                fprintf(outf, "Extended_description-%s: %s\n", 
-                    langdesc->language, 
-                    escapestr(langdesc->extended_description));
-            
-            if (langdesc->choices != NULL) 
-                fprintf(outf, "Choices-%s: %s\n", 
-                    langdesc->language, 
-                    escapestr(langdesc->choices));
-            
-            langdesc = langdesc->next;
+            p = t->get((struct template *) t, *field);
+            if (p != NULL)
+            {
+                if (strcmp(*field, "tag") == 0)
+                    fprintf(outf, "Name: %s\n", escapestr(p));
+                            else
+                    fprintf(outf, "%c%s: %s\n",
+                        toupper((*field)[0]),
+                        (*field)+1, escapestr(p));
+            }
+        }
+    
+        lang = t->next_lang((struct template *) t, "C");
+        while (lang) 
+        {
+            for (field = template_fields_list; *field != NULL; field++)
+            {
+                p = t->lget((struct template *) t, lang, *field);
+                if (p != NULL)
+                {
+                    if (strcmp(*field, "tag") != 0)
+                        fprintf(outf, "%c%s-%s.UTF-8: %s\n",
+                            toupper((*field)[0]), (*field)+1,
+                            lang, escapestr(p));
+                }
+            }
+            lang = t->next_lang((struct template *) t, lang);
         }
         fprintf(outf, "\n");
-  }
-  
+    }
 }
+  
 static int rfc822db_template_save(struct template_db *db)
 {
     struct template_db_cache *dbdata = db->data;
@@ -596,7 +593,7 @@
     struct question *q, q2;
 
     memset(&q2, 0, sizeof (struct question));
-    q2.tag = ltag;
+    q2.tag = (char *) ltag;
     q = tfind(&q2, &dbdata->root, nodequestioncomp);
     if (q != NULL)
     {
Index: src/modules/db/textdb/textdb.c
===================================================================
RCS file: 
/cvs/debian-boot/debian-installer/tools/cdebconf/src/modules/db/textdb/textdb.c,v
retrieving revision 1.5
diff -u -r1.5 textdb.c
--- src/modules/db/textdb/textdb.c      30 Jul 2002 05:55:27 -0000      1.5
+++ src/modules/db/textdb/textdb.c      9 Nov 2002 01:21:19 -0000
@@ -135,38 +135,35 @@
 {
        FILE *outf;
        char *filename;
-       struct language_description *langdesc;
+       const char *p, *lang;
+       const char **field;
 
-       if (t->tag == NULL) return DC_NOTOK;
-       filename = template_filename(db, t->tag);
+       if (t->get(t, "tag") == NULL) return DC_NOTOK;
+       filename = template_filename(db, t->get(t, "tag"));
        
        if ((outf = fopen(filename, "w")) == NULL)
                return DC_NOTOK;
 
        fprintf(outf, "template {\n");
 
-       fprintf(outf, "\ttag \"%s\";\n", escapestr(t->tag));
-       fprintf(outf, "\ttype \"%s\";\n", escapestr(t->type));
-       if (t->defaultval != NULL)
-               fprintf(outf, "\tdefault \"%s\";\n", escapestr(t->defaultval));
-       if (t->choices != NULL)
-               fprintf(outf, "\tchoices \"%s\";\n", escapestr(t->choices));
-       if (t->description != NULL)
-               fprintf(outf, "\tdescription \"%s\";\n", escapestr(t->description));
-       if (t->extended_description != NULL)
-               fprintf(outf, "\textended_description \"%s\";\n", 
escapestr(t->extended_description));
-
-       langdesc = t->localized_descriptions;
-       while (langdesc) 
+       for (field = template_fields_list; *field != NULL; field++)
        {
-               if (langdesc->description != NULL) 
-                       fprintf(outf, "\tdescription-%s \"%s\";\n", 
langdesc->language, escapestr(langdesc->description));
-               if (langdesc->extended_description != NULL)
-                       fprintf(outf, "\textended_description-%s \"%s\";\n", 
langdesc->language, escapestr(langdesc->extended_description));
-               if (langdesc->choices != NULL) 
-                       fprintf(outf, "\tchoices-%s \"%s\";\n", langdesc->language, 
escapestr(langdesc->choices));
+               p = t->get(t, *field);
+               if (p != NULL)
+                       fprintf(outf, "\t%s \"%s\";\n", *field, escapestr(p));
+       }
 
-               langdesc = langdesc->next;
+       lang = t->next_lang(t, "C");
+       while (lang) 
+       {
+               for (field = template_fields_list; *field != NULL; field++)
+               {
+                       p = t->lget(t, lang, *field);
+                       if (p != NULL)
+                               fprintf(outf, "\t%s-%s \"%s\";\n", *field,
+                                                lang, escapestr(p));
+               }
+               lang = t->next_lang(t, lang);
        }
 
        fprintf(outf, "};\n");
@@ -204,16 +201,17 @@
        }
        else
        {
-               t->type = STRDUP(unescapestr(rec->get(rec, "template::type", 
"string")));
-               t->defaultval = STRDUP(unescapestr(rec->get(rec, "template::default", 
0)));
-               t->choices = STRDUP(unescapestr(rec->get(rec, "template::choices", 
0)));
-               t->description = STRDUP(unescapestr(rec->get(rec, 
"template::description", 0)));
-               t->extended_description = STRDUP(unescapestr(rec->get(rec, 
"template::extended_description", 0)));
+               t->set(t, "type", STRDUP(unescapestr(rec->get(rec, "template::type", 
+"string"))));
+               t->set(t, "default", STRDUP(unescapestr(rec->get(rec, 
+"template::default", 0))));
+               t->set(t, "choices", STRDUP(unescapestr(rec->get(rec, 
+"template::choices", 0))));
+               t->set(t, "description", STRDUP(unescapestr(rec->get(rec, 
+"template::description", 0))));
+               t->set(t, "extended_description", STRDUP(unescapestr(rec->get(rec, 
+"template::extended_description", 0))));
 
                /* We can't ask for all the localized descriptions so we need to
                 * brute-force this.
                 * This is stupid and ugly and should be fixed, FIXME
                 */
+#if 0
                for (a = 'a'; a <= 'z'; a++)
                        for (b = 'a'; b <= 'z'; b++)
                        {
@@ -239,6 +237,7 @@
                                        t->localized_descriptions = langdesc;
                                }
                        }
+#endif
        }
                
 
Index: src/modules/frontend/bogl/bogl.c
===================================================================
RCS file: 
/cvs/debian-boot/debian-installer/tools/cdebconf/src/modules/frontend/bogl/bogl.c,v
retrieving revision 1.4
diff -u -r1.4 bogl.c
--- src/modules/frontend/bogl/bogl.c    2 Jul 2002 06:53:47 -0000       1.4
+++ src/modules/frontend/bogl/bogl.c    9 Nov 2002 01:21:19 -0000
@@ -58,12 +58,12 @@
 static void drawdesctop(struct frontend *ui, struct question *q)
 {
        bowl_title(ui->title);
-       bowl_new_text(question_description(q));
+       bowl_new_text(question_get_translated_field(q, "description"));
 }
 
 static void drawdescbot(struct frontend *ui, struct question *q)
 {
-       bowl_new_text(question_extended_description(q));
+       bowl_new_text(question_get_translated_field(q, "extended_description"));
 }
 
 /* boolean requires a new widget, the radio button :( */
@@ -71,7 +71,7 @@
 int bogl_handler_boolean(struct frontend *ui, struct question *q)
 {
        /* Should just make bowl_new_checkbox be properly const-qualified. */
-       char *desc = strdup(question_description(q));
+       char *desc = strdup(question_get_translated_field(q, "description"));
        int ret;
        
 #if 0
@@ -120,40 +120,50 @@
 
 int bogl_handler_multiselect(struct frontend *ui, struct question *q)
 {
-       int nchoices, ndefs, ret, i, j;
+       char **choices, **choices_translated, **defaults, *selected;
+       int i, j, count, dcount, ret;
        const char *p;
-       char **choices, **defaults, *selected;
-       
-       nchoices = 1;
-       for(p = question_choices(q); *p; p++)
-               if(*p == ',')
-                       nchoices++;
-       choices = malloc(sizeof(char *) * nchoices);
-       nchoices = strchoicesplit(question_choices(q), choices, nchoices);
-       selected = malloc(sizeof(char) * nchoices);
-       memset(selected, ' ', nchoices);
 
-       ndefs = 1;
-       for(p = question_defaultval(q); *p; p++)
+       count = 0;
+       p = question_get_field(q, "choices");
+       if (*p)
+       {
+               count++;
+               for(; *p; p++)
+                       if(*p == ',')
+                               count++;
+       }
+
+       if (count <= 0) return DC_NOTOK;
+
+       choices = malloc(sizeof(char *) * count);
+       strchoicesplit(question_get_field(q, "choices"), choices, count);
+       choices_translated = malloc(sizeof(char *) * count);
+       strchoicesplit(question_get_field(q, "choices"), choices_translated, count);
+       selected = malloc(sizeof(char) * count);
+       memset(selected, ' ', count);
+
+       dcount = 1;
+       for(p = question_get_field(q, "default"); *p; p++)
                if(*p == ',')
-                       ndefs++;
-       defaults = malloc(sizeof(char *) * ndefs);
-       ndefs = strchoicesplit(question_defaultval(q), defaults, ndefs);
-       for(i = 0; i < ndefs; i++)
+                       dcount++;
+       defaults = malloc(sizeof(char *) * dcount);
+       dcount = strchoicesplit(question_get_field(q, "default"), defaults, dcount);
+       for(j = 0; j < dcount; j++)
        {
-               for(j = 0; j < nchoices; j++)
-                       if(strcmp(choices[j], defaults[i]) == 0)
+               for(i = 0; i < count; i++)
+                       if(strcmp(choices[i], defaults[j]) == 0)
                        {
-                               selected[j] = '*';
+                               selected[i] = '*';
                                break;
                        }
-               free(defaults[i]);
+               free(defaults[j]);
        }
        free(defaults);
 
        bowl_flush();
        drawdesctop(ui, q);
-       bowl_new_checkbox(choices, selected, nchoices, (nchoices > 15) ? 15 : 
nchoices);
+       bowl_new_checkbox(choices, selected, count, (count > 15) ? 15 : count);
        drawnavbuttons(ui, q);
        drawdescbot(ui, q);
        
@@ -163,19 +173,19 @@
        if(ret == DC_OK)
        {
                /* Be safe - allow for commas and spaces. */
-               char *answer = malloc(strlen(question_choices(q)) + 1 + nchoices);
+               char *answer = malloc(strlen(question_get_translated_field(q, 
+"choices")) + 1 + count);
                answer[0] = 0;
-               for(i = 0; i < nchoices; i++)
+               for(i = 0; i < count; i++)
                        if (selected[i] == '*')
                        {
                                if(answer[0] != 0)
                                        strcat(answer, ", ");
-                               strcat(answer, choices[i]);
+                               strcat(answer, choices_translated[i]);
                        }
                question_setvalue(q, answer);
        }
 
-       for(i = 0; i < nchoices; i++)
+       for(i = 0; i < count; i++)
                free(choices[i]);
        free(choices);
 
@@ -189,7 +199,7 @@
 
        bowl_flush();
        drawdesctop(ui, q);
-       bowl_new_input(&s, question_defaultval(q));
+       bowl_new_input(&s, question_get_field(q, "default"));
        drawnavbuttons(ui, q);
        drawdescbot(ui, q);
        bowl_layout();
Index: src/modules/frontend/ncurses/ncurses.c
===================================================================
RCS file: 
/cvs/debian-boot/debian-installer/tools/cdebconf/src/modules/frontend/ncurses/ncurses.c,v
retrieving revision 1.9
diff -u -r1.9 ncurses.c
--- src/modules/frontend/ncurses/ncurses.c      9 Jul 2002 05:25:04 -0000       1.9
+++ src/modules/frontend/ncurses/ncurses.c      9 Nov 2002 01:21:19 -0000
@@ -223,8 +223,8 @@
        WINDOW *descwin = UIDATA(ui)->descwin;
 
        drawframe(ui, WIN_QUERY, ui->title);
-       wrapprint(qrywin, question_description(q), 0, COLS-2);
-       wrapprint(descwin, question_extended_description(q), 0, COLS-2);
+       wrapprint(qrywin, question_get_translated_field(q, "description"), 0, COLS-2);
+       wrapprint(descwin, question_get_translated_field(q, "extended_description"), 
+0, COLS-2);
        wclrtobot(qrywin);
        wclrtobot(descwin);
        wrefresh(stdscr);
@@ -237,12 +237,17 @@
        char *value = "true";
        int ret = 0, ans, pos = 2;
        int ybut = UIDATA(ui)->qrylines - 6;
+       char *dft;
        WINDOW *win = UIDATA(ui)->qrywin;
 
        if (q->value != 0 && *q->value != 0)
                value = q->value;
-       else if (q->template->defaultval != 0 && *q->template->defaultval != 0)
-               value = q->template->defaultval;
+       else
+       {
+               dft = (char *) q->template->get(q->template, "default");
+               if (dft != 0 && *dft != 0)
+                       value = dft;
+       }
 
        ans = (strcmp(value, "true") == 0);
 
@@ -351,29 +356,33 @@
 
 static int nchandler_select(struct frontend *ui, struct question *q)
 {
-       char *value = NULL;
        char *choices[100] = {0};
-       int i, count, ret = 0, val = 0, pos = 2, xpos, ypos;
+       char *choices_translated[100] = {0};
+       char *defaults[100] = {0};
+       const char *defval = question_get_field(q, "default");
+
+       int i, count, dcount, ret = 0, def = -1, pos = 2, xpos, ypos;
        int top, bottom, longest;
        WINDOW *win = UIDATA(ui)->qrywin;
 
        /* Parse out all the choices */
-       count = strchoicesplit((char *)question_choices(q), choices, DIM(choices));
+       count = strchoicesplit(question_get_field(q, "choices"), choices, 
+DIM(choices));
        if (count <= 0) return DC_NOTOK;
 
+       strchoicesplit(question_get_translated_field(q, "choices"), 
+choices_translated, DIM(choices_translated));
+       dcount = strchoicesplit(question_get_field(q, "default"), defaults, 
+DIM(defaults));
+
        /* See what the currently selected value should be -- either a
         * previously selected value, or the default for the question
         */
-       if ((q->value != 0 && *q->value != 0 && (value = q->value)) ||
-           (q->template->defaultval != 0 && *q->template->defaultval != 0 && 
-               (value = q->template->defaultval)))
+       if (defval != NULL)
        {
                for (i = 0; i < count; i++)
-                       if (strcmp(choices[i], value) == 0)
-                               val = i;
+                       if (strcmp(choices[i], defval) == 0)
+                               def = i + 1;
        }
 
-       longest = longestlen(choices, count);
+       longest = longestlen(choices_translated, count);
        top = 0; bottom = MIN(count, UIDATA(ui)->qrylines-5);
        xpos = (COLS-longest)/2-1;
 
@@ -382,11 +391,11 @@
                ypos = 2;
                for (i = top; i < bottom; i++)
                {
-                       if (pos == 2 && i == val) 
+                       if (pos == 2 && i == def) 
                                wstandout(win); 
                        else 
                                wstandend(win);
-                       mvwprintw(win, ypos++, xpos, " %-*s ", longest, choices[i]);
+                       mvwprintw(win, ypos++, xpos, " %-*s ", longest, 
+choices_translated[i]);
                }
                wstandend(win);
 
@@ -398,17 +407,17 @@
                {
                case KEY_LEFT:
                case KEY_UP:
-                       val--;
-                       if (val < 0) val = count-1;
+                       def--;
+                       if (def < 0) def = count-1;
 
-                       /* check val against top/bottom */
+                       /* check def against top/bottom */
                        break;
                case KEY_RIGHT:
                case KEY_DOWN:
-                       val++;
-                       if (val >= count) val = 0;
+                       def++;
+                       if (def >= count) def = 0;
 
-                       /* check val against top/bottom */
+                       /* check def against top/bottom */
                        break;
                case 9: /* TAB */
                        pos++;
@@ -432,7 +441,7 @@
                }
        }
        if (ret == DC_OK)
-               question_setvalue(q, choices[val]);
+               question_setvalue(q, choices[def]);
        return ret;
 }
 
Index: src/modules/frontend/slang/slang.c
===================================================================
RCS file: 
/cvs/debian-boot/debian-installer/tools/cdebconf/src/modules/frontend/slang/slang.c,v
retrieving revision 1.11
diff -u -r1.11 slang.c
--- src/modules/frontend/slang/slang.c  9 Jul 2002 05:25:04 -0000       1.11
+++ src/modules/frontend/slang/slang.c  9 Nov 2002 01:21:20 -0000
@@ -197,8 +197,8 @@
        slang_drawwin(&uid->qrywin);
        slang_drawwin(&uid->descwin);
        /* Draw in the descriptions */
-       slang_wrapprint(&uid->qrywin, question_description(q), 0);
-       slang_wrapprint(&uid->descwin, question_extended_description(q),
+       slang_wrapprint(&uid->qrywin, question_get_translated_field(q, "description"), 
+0);
+       slang_wrapprint(&uid->descwin, question_get_translated_field(q, 
+"extended_description"),
                uid->descstart);
 
        /* caller should call slang_flush() ! */
@@ -319,7 +319,7 @@
        const char *value = "true";
        int ret = 0, ans, pos = 2;
 
-       value = question_defaultval(q);
+       value = question_get_field(q, "default");
 
        ans = (strcmp(value, "true") == 0);
 
@@ -373,6 +373,7 @@
 static int slang_getselect(struct frontend *ui, struct question *q, int multi)
 {
        char *choices[100] = {0};
+       char *choices_translated[100] = {0};
        char *defaults[100] = {0};
        char selected[100] = {0};
        char answer[1024] = {0};
@@ -382,8 +383,9 @@
        struct slwindow *win = &uid->qrywin;
 
        /* Parse out all the choices */
-       count = strchoicesplit(question_choices(q), choices, DIM(choices));
-       dcount = strchoicesplit(question_defaultval(q), defaults, DIM(defaults));
+       count = strchoicesplit(question_get_field(q, "choices"), choices, 
+DIM(choices));
+       strchoicesplit(question_get_translated_field(q, "choices"), 
+choices_translated, DIM(choices_translated));
+       dcount = strchoicesplit(question_get_field(q, "default"), defaults, 
+DIM(defaults));
        INFO(INFO_VERBOSE, "Parsed out %d choices, %d defaults\n", count, dcount);
        if (count <= 0) return DC_NOTOK;
 
@@ -391,11 +393,9 @@
         * previously selected value, or the default for the question
         */
        for (j = 0; j < dcount; j++)
-       {
                for (i = 0; i < count; i++)
                        if (strcmp(choices[i], defaults[j]) == 0)
                                selected[i] = 1;
-       }
 
        longest = strlongest(choices, count);
        top = 0;
@@ -414,10 +414,10 @@
                        slang_printf(ypos++, xpos, ((pos == 2 && i == val) ?
                                win->selectedcolor : win->drawcolor),
                                "(%c) %-*s ", (selected[i] ? '*' : ' '), 
-                               longest, choices[i]);
+                               longest, choices_translated[i]);
 
                        INFO(INFO_VERBOSE, "(%c) %-*s\n", (selected[i] ? '*' : 
-                               ' '), longest, choices[i]);
+                               ' '), longest, choices_translated[i]);
                }
 
                slang_navbuttons(ui, q, pos);
@@ -454,7 +454,7 @@
                        case 0: ret = DC_GOBACK; break;
                        case 1: ret = DC_OK; break;
                        default: 
-                               if (multi == 0)
+                               if (multi == 1)
                                {
                                        memset(selected, 0, sizeof(selected));
                                        selected[val] = 1;
@@ -477,10 +477,12 @@
                        strvacat(answer, sizeof(answer), choices[i], NULL);
                }
                free(choices[i]);
+               free(choices_translated[i]);
        }
        for (i = 0; i < dcount; i++)
                free(defaults[i]);
        question_setvalue(q, answer);
+
        return DC_OK;
 }
 
@@ -505,7 +507,7 @@
        int cursor;
        char *tmp;
 
-       STRCPY(value, question_defaultval(q));
+       STRCPY(value, question_get_field(q, "default"));
        cursor = strlen(value);
 
        /* TODO: scrolling */
Index: src/modules/frontend/text/text.c
===================================================================
RCS file: 
/cvs/debian-boot/debian-installer/tools/cdebconf/src/modules/frontend/text/text.c,v
retrieving revision 1.15
diff -u -r1.15 text.c
--- src/modules/frontend/text/text.c    5 Nov 2002 03:01:51 -0000       1.15
+++ src/modules/frontend/text/text.c    9 Nov 2002 01:21:20 -0000
@@ -119,8 +119,8 @@
  */
 static void texthandler_displaydesc(struct frontend *obj, struct question *q) 
 {
-       wrap_print(question_description(q));
-       wrap_print(question_extended_description(q));
+       wrap_print(question_get_translated_field(q, "description"));
+       wrap_print(question_get_translated_field(q, "extended_description"));
 }
 
 /*
@@ -138,7 +138,7 @@
        int def = -1;
        const char *defval;
 
-       defval = question_defaultval(q);
+       defval = question_get_field(q, "default");
        if (defval)
        {
                if (strcmp(defval, "true") == 0)
@@ -180,25 +180,28 @@
 static int texthandler_multiselect(struct frontend *obj, struct question *q)
 {
        char *choices[100] = {0};
+       char *choices_translated[100] = {0};
        char *defaults[100] = {0};
        char selected[100] = {0};
-       char answer[1024];
+       char answer[1024] = {0};
        int i, j, count, dcount, choice;
 
-       count = strchoicesplit(question_choices(q), choices, DIM(choices));
-       dcount = strchoicesplit(question_defaultval(q), defaults, DIM(defaults));
+       count = strchoicesplit(question_get_field(q, "choices"), choices, 
+DIM(choices));
+       if (count <= 0) return DC_NOTOK;
+
+       strchoicesplit(question_get_translated_field(q, "choices"), 
+choices_translated, DIM(choices_translated));
+       dcount = strchoicesplit(question_get_field(q, "default"), defaults, 
+DIM(defaults));
 
-       if (dcount > 0)
+       for (j = 0; j < dcount; j++)
                for (i = 0; i < count; i++)
-                       for (j = 0; j < dcount; j++)
-                               if (strcmp(choices[i], defaults[j]) == 0)
-                                       selected[i] = 1;
+                       if (strcmp(choices[i], defaults[j]) == 0)
+                               selected[i] = 1;
 
        while(1)
        {
                for (i = 0; i < count; i++)
                {
-                       printf("%3d. %s%s\n", i+1, choices[i], 
+                       printf("%3d. %s%s\n", i+1, choices_translated[i], 
                                (selected[i] ? _(" (selected)") : ""));
                        
                }
@@ -217,7 +220,6 @@
                }
        }
 
-       answer[0] = 0;
        for (i = 0; i < count; i++)
        {
                if (selected[i])
@@ -227,6 +229,7 @@
                        strvacat(answer, sizeof(answer), choices[i], NULL);
                }
                free(choices[i]);
+               free(choices_translated[i]);
        }
        for (i = 0; i < dcount; i++)
                free(defaults[i]);
@@ -301,34 +304,33 @@
        char *choices_translated[100] = {0};
        char answer[10];
        int i, count, choice = 1, def = -1;
-       const char *defval = question_defaultval(q);
+       const char *defval = question_get_field(q, "default");
+
+       count = strchoicesplit(question_get_field(q, "choices"), choices, 
+DIM(choices));
+       if (count <= 0) return DC_NOTOK;
 
-       count = strchoicesplit(question_choices(q), choices, DIM(choices));
-       strchoicesplit(question_choices_translated(q), choices_translated, 
DIM(choices_translated));
+       strchoicesplit(question_get_translated_field(q, "choices"), 
+choices_translated, DIM(choices_translated));
         /* fprintf(stderr,"In texthandler_select, count is: %d\n", count);*/
-       if (count > 1)
+       if (defval != NULL)
        {
-               if (defval != NULL)
-               {
-                       for (i = 0; i < count; i++)
-                               if (strcmp(choices[i], defval) == 0)
-                                       def = i + 1;
-               }
-
-               do
-               {
-                       for (i = 0; i < count; i++)
-                               printf("%3d. %s%s\n", i+1, choices_translated[i],
-                                       (def == i + 1 ? _(" (default)") : ""));
-
-                       printf(_("Prompt: 1 - %d> "), count);
-                       fgets(answer, sizeof(answer), stdin);
-                       if (answer[0] == '\n')
-                               choice = def;
-                       else
-                               choice = atoi(answer);
-               } while (choice <= 0 || choice > count);
+               for (i = 0; i < count; i++)
+                       if (strcmp(choices[i], defval) == 0)
+                               def = i + 1;
        }
+
+       do
+       {
+               for (i = 0; i < count; i++)
+                       printf("%3d. %s%s\n", i+1, choices_translated[i],
+                               (def == i + 1 ? _(" (default)") : ""));
+
+               printf(_("Prompt: 1 - %d> "), count);
+               fgets(answer, sizeof(answer), stdin);
+               if (answer[0] == '\n')
+                       choice = def;
+               else
+                       choice = atoi(answer);
+       } while (choice <= 0 || choice > count);
        /*      fprintf(stderr,"In %s, line: %d\n\tanswer: %s, choice[choice]: %s\n",
                __FILE__,__LINE__,answer, choices[choice - 1]);*/
        question_setvalue(q, choices[choice - 1]);
@@ -352,7 +354,7 @@
 static int texthandler_string(struct frontend *obj, struct question *q)
 {
        char buf[1024] = {0};
-       const char *defval = question_defaultval(q);
+       const char *defval = question_get_field(q, "default");
        if (defval)
                printf(_("[default = %s]"), defval);
        printf("> "); fflush(stdout);

Reply via email to