More helpful messages when locale not found or wrong (closes #209)
This commit is contained in:
@@ -245,6 +245,10 @@ int main( int argc, char *argv[] )
|
|||||||
/* Adopt implementation locale */
|
/* Adopt implementation locale */
|
||||||
set_native_locale();
|
set_native_locale();
|
||||||
if ( !is_utf8_locale() ) {
|
if ( !is_utf8_locale() ) {
|
||||||
|
/* save details for diagnostic */
|
||||||
|
LocaleVar native_ctype = get_ctype();
|
||||||
|
string native_charset( locale_charset() );
|
||||||
|
|
||||||
/* apply locale-related environment variables from client */
|
/* apply locale-related environment variables from client */
|
||||||
clear_locale_variables();
|
clear_locale_variables();
|
||||||
for ( list<string>::const_iterator i = locale_vars.begin();
|
for ( list<string>::const_iterator i = locale_vars.begin();
|
||||||
@@ -260,8 +264,12 @@ int main( int argc, char *argv[] )
|
|||||||
/* check again */
|
/* check again */
|
||||||
set_native_locale();
|
set_native_locale();
|
||||||
if ( !is_utf8_locale() ) {
|
if ( !is_utf8_locale() ) {
|
||||||
|
LocaleVar client_ctype = get_ctype();
|
||||||
|
string client_charset( locale_charset() );
|
||||||
|
|
||||||
fprintf( stderr, "mosh-server needs a UTF-8 native locale to run.\n\n" );
|
fprintf( stderr, "mosh-server needs a UTF-8 native locale to run.\n\n" );
|
||||||
fprintf( stderr, "Unfortunately, the locale environment variables currently specify\nthe character set \"%s\".\n\n", locale_charset() );
|
fprintf( stderr, "Unfortunately, the local environment (%s) specifies\nthe character set \"%s\",\n\n", native_ctype.str().c_str(), native_charset.c_str() );
|
||||||
|
fprintf( stderr, "The client-supplied environment (%s) specifies\nthe character set \"%s\".\n\n", client_ctype.str().c_str(), client_charset.c_str() );
|
||||||
int unused __attribute((unused)) = system( "locale" );
|
int unused __attribute((unused)) = system( "locale" );
|
||||||
exit( 1 );
|
exit( 1 );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,8 +50,11 @@
|
|||||||
void STMClient::init( void )
|
void STMClient::init( void )
|
||||||
{
|
{
|
||||||
if ( !is_utf8_locale() ) {
|
if ( !is_utf8_locale() ) {
|
||||||
|
LocaleVar native_ctype = get_ctype();
|
||||||
|
string native_charset( locale_charset() );
|
||||||
|
|
||||||
fprintf( stderr, "mosh-client needs a UTF-8 native locale to run.\n\n" );
|
fprintf( stderr, "mosh-client needs a UTF-8 native locale to run.\n\n" );
|
||||||
fprintf( stderr, "Unfortunately, the locale environment variables currently specify\nthe character set \"%s\".\n\n", locale_charset() );
|
fprintf( stderr, "Unfortunately, the client's environemnt (%s) specifies\nthe character set \"%s\".\n\n", native_ctype.str().c_str(), native_charset.c_str() );
|
||||||
int unused __attribute((unused)) = system( "locale" );
|
int unused __attribute((unused)) = system( "locale" );
|
||||||
exit( 1 );
|
exit( 1 );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#if HAVE_LANGINFO_H
|
#if HAVE_LANGINFO_H
|
||||||
#include <langinfo.h>
|
#include <langinfo.h>
|
||||||
@@ -29,9 +31,34 @@
|
|||||||
|
|
||||||
#include "locale_utils.h"
|
#include "locale_utils.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
const string LocaleVar::str( void ) const
|
||||||
|
{
|
||||||
|
if ( name.empty() ) {
|
||||||
|
return string( "[no charset variables]" );
|
||||||
|
} else {
|
||||||
|
return name + "=" + value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const LocaleVar get_ctype( void )
|
||||||
|
{
|
||||||
|
/* Reimplement the search logic, just for diagnostics */
|
||||||
|
if ( const char *all = getenv( "LC_ALL" ) ) {
|
||||||
|
return LocaleVar( "LC_ALL", all );
|
||||||
|
} else if ( const char *ctype = getenv( "LC_CTYPE" ) ) {
|
||||||
|
return LocaleVar( "LC_CTYPE", ctype );
|
||||||
|
} else if ( const char *lang = getenv( "LANG" ) ) {
|
||||||
|
return LocaleVar( "LANG", lang );
|
||||||
|
} else {
|
||||||
|
return LocaleVar( "", "" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const char *locale_charset( void )
|
const char *locale_charset( void )
|
||||||
{
|
{
|
||||||
static const char ASCII_name[] = "US-ASCII (ANSI_X3.4-1968)";
|
static const char ASCII_name[] = "US-ASCII";
|
||||||
|
|
||||||
/* Produce more pleasant name of US-ASCII */
|
/* Produce more pleasant name of US-ASCII */
|
||||||
const char *ret = nl_langinfo( CODESET );
|
const char *ret = nl_langinfo( CODESET );
|
||||||
@@ -55,7 +82,18 @@ bool is_utf8_locale( void ) {
|
|||||||
void set_native_locale( void ) {
|
void set_native_locale( void ) {
|
||||||
/* Adopt native locale */
|
/* Adopt native locale */
|
||||||
if ( NULL == setlocale( LC_ALL, "" ) ) {
|
if ( NULL == setlocale( LC_ALL, "" ) ) {
|
||||||
perror( "setlocale" );
|
int saved_errno = errno;
|
||||||
|
if ( saved_errno == ENOENT ) {
|
||||||
|
LocaleVar ctype( get_ctype() );
|
||||||
|
fprintf( stderr, "The locale requested by %s isn't available here.\n", ctype.str().c_str() );
|
||||||
|
if ( !ctype.name.empty() ) {
|
||||||
|
fprintf( stderr, "Running `locale-gen %s' may be necessary.\n\n",
|
||||||
|
ctype.value.c_str() );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errno = saved_errno;
|
||||||
|
perror( "setlocale" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,18 @@
|
|||||||
#ifndef LOCALE_UTILS_HPP
|
#ifndef LOCALE_UTILS_HPP
|
||||||
#define LOCALE_UTILS_HPP
|
#define LOCALE_UTILS_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class LocaleVar {
|
||||||
|
public:
|
||||||
|
const std::string name, value;
|
||||||
|
LocaleVar( const char *s_name, const char *s_value )
|
||||||
|
: name( s_name ), value( s_value )
|
||||||
|
{}
|
||||||
|
const std::string str( void ) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
const LocaleVar get_ctype( void );
|
||||||
const char *locale_charset( void );
|
const char *locale_charset( void );
|
||||||
bool is_utf8_locale( void );
|
bool is_utf8_locale( void );
|
||||||
void set_native_locale( void );
|
void set_native_locale( void );
|
||||||
|
|||||||
Reference in New Issue
Block a user