Index: src/commands.c =================================================================== --- src/commands.c (revision 47632) +++ src/commands.c (working copy) @@ -293,6 +293,7 @@ command_set(struct confmodule *mod, char { /* Pass the value on to getlanguage() in templates.c */ debug_printf(0, "Setting debconf/language to %s", argv[1]); setenv("LANGUAGE", argv[1], 1); + mod->templates->methods.reload(mod->templates); } else if (strcmp(argv[0], "debconf/priority") == 0) { Index: src/template.c =================================================================== --- src/template.c (revision 47632) +++ src/template.c (working copy) @@ -91,6 +91,19 @@ static bool allow_i18n(void) return true; } +static bool load_all_translations(void) +{ + static int translations = -1; + if (translations == -1) { + const char *translations_env = getenv("DEBCONF_DROP_TRANSLATIONS"); + if (translations_env && !strcmp(translations_env, "1")) + translations = 0; + else + translations = 1; + } + return (translations == 1); +} + /* * Function: template_new * Input: a tag, describing which template this is. Can be null. @@ -490,8 +503,29 @@ void template_lset(struct template *t, c if (*lang == 0) curlang = getlanguage(); - else + else if (load_all_translations() || strcmp(lang, "C") == 0) curlang = lang; + else { + const char *wantlang_full = getlanguage(); + char *wantlang; + char *p; + + if (wantlang_full) { + wantlang = strdup(wantlang_full); + p = strpbrk(wantlang, "_.@"); + if (p) + *p = '\0'; + if (strncmp(lang, wantlang, strlen(wantlang)) == 0) + curlang = lang; + else { + INFO(INFO_VERBOSE, "Dropping %s/%s for %s (wantlang=%s)", t->tag, field, lang, wantlang); + free(wantlang); + return; + } + free(wantlang); + } else + curlang = lang; + } p = t->fields; last = p; Index: src/modules/db/rfc822db/rfc822db.c =================================================================== --- src/modules/db/rfc822db/rfc822db.c (revision 47632) +++ src/modules/db/rfc822db/rfc822db.c (working copy) @@ -22,6 +22,9 @@ FILE *outf = NULL; +static struct template *rfc822db_template_get(struct template_db *db, + const char *ltag); + int nodetemplatecomp(const void *pa, const void *pb) { return strcmp(((struct template *)pa)->tag, ((struct template *)pb)->tag); @@ -194,6 +197,71 @@ static int rfc822db_template_load(struct return DC_OK; } +/* + * Function: rfc822db_template_reload + * Input: template database + * Output: DC_OK/DC_NOTOK + * Description: reparse a template db file and update the cache; used when + * the language is changed + * Assumptions: the file is in valid rfc822 format + */ +static int rfc822db_template_reload(struct template_db *db) +{ + struct template_db_cache *dbdata = db->data; + char tmp[1024]; + const char *path; + FILE *inf; + struct rfc822_header *header = NULL; + INFO(INFO_VERBOSE, "rfc822db_template_reload(db)"); + snprintf(tmp, sizeof(tmp), "%s::path", db->configpath); + path = db->config->get(db->config, tmp, 0); + if (path == NULL || + (inf = fopen(path, "r")) == NULL) + { + INFO(INFO_VERBOSE, "Cannot open template file %s", + path ? path : ""); + return DC_NOTOK; + } + + while ((header = rfc822_parse_stanza(inf)) != NULL) + { + struct template *tmp; + bool is_new = false; + const char *name; + struct rfc822_header *h; + + name = rfc822_header_lookup(header, "name"); + if (name == NULL) + { + INFO(INFO_ERROR, "Read a stanza without a name"); + DELETE(header); + continue; + } + + INFO(INFO_VERBOSE, "Template %s:", name); + tmp = rfc822db_template_get(db, name); + if (!tmp) { + tmp = template_new(name); + is_new = true; + } + for (h = header; h != NULL; h = h->next) + if (strcmp(h->header, "Name") != 0) { + INFO(INFO_VERBOSE, " %s=%s", h->header, h->value); + template_lset(tmp, NULL, h->header, h->value); + } + + tmp->next = NULL; + if (is_new) + tsearch(tmp, &dbdata->root, nodetemplatecomp); + else + template_deref(tmp); + } + + fclose(inf); + + return DC_OK; +} + void rfc822db_template_dump(const void *node, const VISIT which, const int depth) { const char *p, *lang; @@ -709,6 +777,7 @@ static struct question *rfc822db_questio struct template_db_module debconf_template_db_module = { initialize: rfc822db_template_initialize, load: rfc822db_template_load, + reload: rfc822db_template_reload, save: rfc822db_template_save, set: rfc822db_template_set, get: rfc822db_template_get, Index: src/test/test.config =================================================================== --- src/test/test.config (revision 47632) +++ src/test/test.config (working copy) @@ -42,6 +42,10 @@ debug "register ANS: $ans" askquestion test/string-register critical +echo "SET debconf/language fr" + +askquestion test/string-register critical + echo "SET debconf/language en" read ans Index: src/test/test.templates =================================================================== --- src/test/test.templates (revision 47632) +++ src/test/test.templates (working copy) @@ -45,11 +45,19 @@ Choices-C: foo bar (C), baz quux (C), fo Choices: foo bar, baz quux, foo baz, bar quux, moo cow, alpha, beta, gamma, delta, epsilon, i don't remember what the next one is, ${EXTRA-TRANS} Description: Select one option This is the prompt for a select-type question +Description-de.UTF-8: Selecten Sie eine Option + Dies ist die Eingabeaufforderung für eine Selectfrage +Description-fr.UTF-8: Select one option (French) + This is the prompt for a select-type question (French) Template: test/string Type: string Description: Enter a string This is the prompt for a string-type question +Description-de.UTF-8: Angeben Sie ein String + Dies ist die Eingabeaufforderung für eine Stringfrage +Description-fr.UTF-8: Enter a string (French) + This is the prompt for a string-type question (French) Template: test/text Type: text Index: src/database.c =================================================================== --- src/database.c (revision 47632) +++ src/database.c (working copy) @@ -62,6 +62,11 @@ static int template_db_load(struct templ return DC_OK; } +static int template_db_reload(struct template_db *db) +{ + return DC_OK; +} + static int template_db_save(struct template_db *db) { return DC_OK; @@ -174,6 +179,7 @@ struct template_db *template_db_new(stru SETMETHOD(initialize); SETMETHOD(shutdown); SETMETHOD(load); + SETMETHOD(reload); SETMETHOD(save); SETMETHOD(set); SETMETHOD(get); Index: src/debconf-loadtemplate.c =================================================================== --- src/debconf-loadtemplate.c (revision 47632) +++ src/debconf-loadtemplate.c (working copy) @@ -85,6 +85,9 @@ int main(int argc, char **argv) config = config_new(); parsecmdline(config, argc, argv); + /* always load all translations if running standalone */ + unsetenv("DEBCONF_DROP_TRANSLATIONS"); + /* If debconf is already running, use debconfclient to load * the templates; * This is a hack until we introduce a standard debconf Index: src/database.h =================================================================== --- src/database.h (revision 47632) +++ src/database.h (working copy) @@ -22,6 +22,7 @@ struct template_db_module { int (*initialize)(struct template_db *db, struct configuration *cfg); int (*shutdown)(struct template_db *db); int (*load)(struct template_db *db); + int (*reload)(struct template_db *db); int (*save)(struct template_db *db); int (*set)(struct template_db *db, struct template *t); struct template *(*get)(struct template_db *db, const char *name);