Linux Language System and a Controller

22/02/2022 • 4 min read

  • How Does the Language System Work?
    • Commands
    • Files
    • Summary
  • Locale Controller

How Does the Language System Work?

There are 3 commands and 2 files to know about:

Commands

  1. locale: It shows the locale values of the different parts of the system.
  2. locale -a: Lists the language packages which already exist on the system.
  3. sudo locale-gen: Installs the packages inside /etc/locale.gen which aren't already installed.

Files

  1. /etc/default/locale: the file which gets referred by the locale command. It stores the values of the locales categorized by POSIX and GNU C library. if the locale packages aren't already installed, it installs them when needed according to these values. The LANG value, determines the main locale of the system.

    The first four lines are as follows:

LANG=tr_TR.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="tr_TR.UTF-8"
...
  1. /etc/locale.gen: It stores the codes of the locale packages marked as to be installed. When the command sudo locale-gen is called, it read the values that aren't commented (#) out and installs them. By default, it takes the locale list from /usr/share/i18n/SUPPORTED and comments out the ones which aren't installed.

    The content of the file looks like below:

...
# tr_TR ISO-8859-9
tr_TR.UTF-8 UTF-8
# ts_ZA UTF-8
# tt_RU UTF-8
...

Summary

While the system is starting, it reads the language of the system parts from locale file. Then it applies the language from the installed locales. The language of the system parts could be changed by changing the values inside of that file and restarting it. The available language packages can be checked with the locale -a command. If you want to use a locale package that is not available, you should add the locale value to the locale.gen file. Then, run the sudo locale-gen command so that the package gets installed.

Locale Controller

This program checks the system language and verifies it as Turkish or English. Installs the locale packages if not installed. If the values are prone to error, it fixes them. Programmed with C and Shell Scripting.

By preference, we used to leave some parts of the system in English, and the rest Turkish for consistency. Therefore you can set your own preferences as such.

After checking if the program has enough permissions, it learns the system language by checking the LANG value from locale'.

// Get the locale LANG
char *lang_value = run_command("cat /etc/default/locale 2> /dev/null | grep '^LANG=' | cut -d '=' -f2 | tr '\\n' '\\0'");

By running the char* run_command(char* command) function, it runs the Shell commands and returns the output. After assigning LANG to lang_value, it decides which locale packages should be installed. If it can't recognize the LANG value, it defaults to English.

#define LANG_TR_TR "tr_TR.UTF-8" // Locale code
#define LOCALE_TURKISH // Unverified 'locale' value
...
// Extract the LANGs needed to be installed after verifying
size_t ln_count; // ln == locales_needed
char **locales_needed = !strcmp(lang_value, LANG_TR_TR) ?
	extract_charmaps(LOCALE_TURKISH, &ln_count) : extract_charmaps(LOCALE_ENGLISH, &ln_count);

After assigning the required locale packages is assigned to the locales_needed variable, it checks one by one if the needed packages are installed. If there aren't installed packages it warns the user and adds the locale code to the locale.gen list with the void add_lang_to_localegen(char* lang) function.

// Check if the LANG is installed -> locale -a
char *locale_installed;
bool is_locale_gen_needed = false;
for(int ln_i = 0; ln_i < ln_count-1; ln_i++){ //-1 for null
  // $ locale -a 2> /dev/null | grep -i LANG
  locale_installed = search_locale_installed(*(locales_needed+ln_i));
  if (*locale_installed == '\0'){
    printf("Locale '%s' is not installed.\n", *(locales_needed+ln_i));
    is_locale_gen_needed = true;
    add_lang_to_localegen(*(locales_needed+ln_i));
  }
  free(locale_installed);
}// for

The void add_lang_to_localegen(char* lang) function above runs a Shell command which corresponds to the code below. This command checks the locale codes from the list at /usr/share/i18n/SUPPORTED. Adds the returned locale codes to the locale.gen list without multiple copies of themselves.

$ search="^lang\.";
result=$(grep $search /usr/share/i18n/SUPPORTED);
grep -v "$result" /etc/locale.gen | sudo tee /etc/locale.gen > /dev/null;
echo $result | sudo tee -a /etc/locale.gen > /dev/null

After adding the required locale packages to the locale.gen list, the packages are installed with the run_command("sudo locale-gen") function. It determines the locale values from the lang_value variable after verifying. According to the verified values (ex: LOCALE_TURKISH) it writes them to the locale.

"Linux Language System and a Controller", 22/02/2022, 10:11:00

#C, #i18n, #linux, #project