From: TJ S. <cas...@us...> - 2008-12-23 19:29:09
|
Update of /cvsroot/proftp/proftpd/modules In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv31343/modules Modified Files: mod_lang.c Log Message: The ANSI C standard says that every process starts out in the C locale, regardless of LANG and other environment variables. To switch the process to using the locales specified by those environment variables, you need an explicit: setlocale(LC_ALL, ""); call. Make sure that mod_lang does this, prior to any other setlocale(3) calls. Also, when using setlocale(3) to query for a locale, make a copy of the returned string, instead of just stashing the pointer. The library may return a pointer whose value changes later, i.e. by subsequent setlocale(3) calls. Index: mod_lang.c =================================================================== RCS file: /cvsroot/proftp/proftpd/modules/mod_lang.c,v retrieving revision 1.20 retrieving revision 1.21 diff -u -r1.20 -r1.21 --- mod_lang.c 11 Dec 2008 18:59:29 -0000 1.20 +++ mod_lang.c 23 Dec 2008 19:29:03 -0000 1.21 @@ -119,14 +119,14 @@ pr_feat_remove(lang_feat); } -static int lang_set_lang(const char *lang) { +static int lang_set_lang(pool *p, const char *lang) { char *curr_locale; - curr_locale = setlocale(LC_ALL, NULL); + curr_locale = pstrdup(p, setlocale(LC_ALL, NULL)); if (setlocale(LC_ALL, lang) == NULL) { if (errno == ENOENT) { - /* The site may have an unknown/bad LC_ALL environment variable set. + /* The site may have an unknown/bad LANG environment variable set. * Report this, and fall back to using "C" as the locale. */ pr_log_pri(PR_LOG_NOTICE, @@ -311,13 +311,13 @@ pr_log_debug(DEBUG7, MOD_LANG_VERSION ": resetting to default language '%s'", lang_default); - if (lang_set_lang(lang_default) < 0) { + if (lang_set_lang(cmd->tmp_pool, lang_default) < 0) { pr_log_pri(PR_LOG_NOTICE, MOD_LANG_VERSION ": unable to use LangDefault '%s': %s", lang_default, strerror(errno)); pr_log_pri(PR_LOG_NOTICE, MOD_LANG_VERSION ": using LC_ALL environment variable value instead"); - if (lang_set_lang("") < 0) { + if (lang_set_lang(cmd->tmp_pool, "") < 0) { pr_log_pri(PR_LOG_WARNING, MOD_LANG_VERSION ": unable to use LC_ALL value for locale: %s", strerror(errno)); end_login(1); @@ -338,14 +338,14 @@ pr_log_debug(DEBUG7, MOD_LANG_VERSION ": setting to client-requested language '%s'", cmd->argv[1]); - if (lang_set_lang(cmd->argv[1]) < 0) { + if (lang_set_lang(cmd->tmp_pool, cmd->argv[1]) < 0) { pr_log_pri(PR_LOG_NOTICE, MOD_LANG_VERSION ": unable to use client-requested language '%s': %s", cmd->argv[1], strerror(errno)); pr_log_pri(PR_LOG_NOTICE, MOD_LANG_VERSION ": using LangDefault '%s' instead", lang_default); - if (lang_set_lang(lang_default) < 0) { + if (lang_set_lang(cmd->tmp_pool, lang_default) < 0) { pr_log_pri(PR_LOG_WARNING, MOD_LANG_VERSION ": unable to use LangDefault '%s': %s", lang_default, strerror(errno)); end_login(1); @@ -504,6 +504,17 @@ return; } + /* ANSI C says that every process starts off in the 'C' locale, regardless + * of any environment variable settings (e.g. LANG). Thus to honor the + * LANG et al environment variables, we need to explicitly call + * setlocale(3) appropriately. + */ + if (setlocale(LC_ALL, "") == NULL) { + pr_log_pri(PR_LOG_NOTICE, MOD_LANG_VERSION + ": error setting locale based on LANG and other environment " + "variables: %s", strerror(errno)); + } + /* Scan the LangPath for the .mo files to read in. */ c = find_config(main_server->conf, CONF_PARAM, "LangPath", FALSE); @@ -544,7 +555,7 @@ * * $lang/LC_MESSAGES/proftpd.mo * - * In addition, make sure the directory name is an locale acceptable to + * In addition, make sure the directory name is a locale acceptable to * setlocale(3). */ @@ -575,7 +586,7 @@ /* Check that dent->d_name is a valid language name according to * setlocale(3) before adding it to the list. */ - curr_locale = setlocale(LC_MESSAGES, NULL); + curr_locale = pstrdup(tmp_pool, setlocale(LC_MESSAGES, NULL)); if (setlocale(LC_MESSAGES, dent->d_name) != NULL) { *((char **) push_array(lang_list)) = pstrdup(lang_pool, dent->d_name); @@ -671,19 +682,30 @@ if (!lang_engine) return 0; + /* ANSI C says that every process starts off in the 'C' locale, regardless + * of any environment variable settings (e.g. LANG). Thus to honor the + * LANG et al environment variables, we need to explicitly call + * setlocale(3) appropriately. + */ + if (setlocale(LC_ALL, "") == NULL) { + pr_log_pri(PR_LOG_NOTICE, MOD_LANG_VERSION + ": error setting locale based on LANG and other environment " + "variables: %s", strerror(errno)); + } + c = find_config(main_server->conf, CONF_PARAM, "LangDefault", FALSE); if (c) { char *lang; lang = c->argv[0]; - if (lang_set_lang(lang) < 0) { + if (lang_set_lang(lang_pool, lang) < 0) { pr_log_pri(PR_LOG_NOTICE, MOD_LANG_VERSION ": unable to use LangDefault '%s': %s", lang, strerror(errno)); pr_log_pri(PR_LOG_NOTICE, MOD_LANG_VERSION ": using LC_ALL environment variable value instead"); - if (lang_set_lang("") < 0) { + if (lang_set_lang(lang_pool, "") < 0) { pr_log_pri(PR_LOG_WARNING, MOD_LANG_VERSION ": unable to use LC_ALL value for locale: %s", strerror(errno)); @@ -698,7 +720,7 @@ /* No explicit default language configured; rely on the environment * variables. */ - if (lang_set_lang("") < 0) { + if (lang_set_lang(lang_pool, "") < 0) { pr_log_pri(PR_LOG_WARNING, MOD_LANG_VERSION ": unable to use LC_ALL value for locale: %s", strerror(errno)); @@ -706,7 +728,7 @@ return -1; } - lang_curr = setlocale(LC_MESSAGES, NULL); + lang_curr = pstrdup(lang_pool, setlocale(LC_MESSAGES, NULL)); if (strcasecmp(lang_curr, "C") == 0) { lang_curr = LANG_DEFAULT_LANG; } |