--- loader/lang.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++- scripts/upd-instroot | 16 +++++------ 2 files changed, 80 insertions(+), 10 deletions(-) diff --git a/loader/lang.c b/loader/lang.c index a84c2ec..f3e00df 100644 --- a/loader/lang.c +++ b/loader/lang.c @@ -32,6 +32,8 @@ #include <stdlib.h> #include <string.h> #include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/wait.h> #include <unistd.h> #include <wchar.h> @@ -224,7 +226,13 @@ static void setLangEnv (int i) { /* choice is the index of the chosen language in languages */ static int setupLanguage(int choice, int forced) { char * buf; + char *locale_def = NULL; /* locale lang name */ + char *locale_charset = NULL;/* locale charset */ + char *locale_mod = NULL; /* locale variant */ + char *locale_p = NULL; /* last known locale separator */ + char *locale_i = NULL; /* string iterator */ int i; + pid_t localedef_pid; logMessage(DEBUGLVL, "going to set language to %s", languages[choice].lc_all); /* load the language only if it is displayable. if they're using @@ -241,7 +249,71 @@ static int setupLanguage(int choice, int forced) { setLangEnv(english); return 0; } - + + /* Parse locale parts out of locale name. + + Locale examples: + en + en_US + cz_CS.UTF-8 + cz_CS.UTF-8@latin + */ + + locale_p = locale_i = languages[choice].lc_all; + while (1) { + // we found new separator + if (*locale_i == '.' || *locale_i == '@' || *locale_i == '\0') { + // last separator was annotating charset + if (*locale_p == '.') locale_charset = strndup(locale_p + 1, locale_i - locale_p - 1); + // last separator was annotating modifier + else if (*locale_p == '@') locale_mod = strndup(locale_p + 1, locale_i - locale_p - 1); + // there was no known separator last time + else locale_def = strndup(locale_p, locale_i - locale_p); + + // save last known separator + locale_p = locale_i; + + if(*locale_i == '\0') break; // end of the string + } + + // test next character + locale_i++; + } + + logMessage(DEBUGLVL, "locale %s: base: %s, mod: %s, charset: %s", languages[choice].lc_all, locale_def, locale_mod, locale_charset); + + /* prepare locale name without charset */ + i = strlen(locale_def); + if (locale_mod) i+= strlen(locale_mod) + 1; /* +1 for the @ char */ + locale_p = (char*)calloc(i+1, sizeof(char)); + locale_p = strcpy(locale_p, locale_def); + if (locale_mod){ + locale_p[strlen(locale_p)] = '@'; + locale_p = strcat(locale_p, locale_mod); + } + + /* generate locale record */ + logMessage(INFO, "going to prepare locales for %s (locale: %s, charset: %s)", languages[choice].lc_all, locale_p, locale_charset); + if ((localedef_pid = fork()) == 0) { + execl("/usr/bin/localedef", "localedef", + "-i", locale_p, + "-f", (locale_charset) ? locale_charset : "UTF-8", + languages[choice].lc_all, NULL); + exit(254); + } + + if (localedef_pid < 0) logMessage(ERROR, "failed forking localedef for %s", languages[choice].lc_all); + else{ + waitpid(localedef_pid, &i, 0); + if (WEXITSTATUS(i) != 0) logMessage(ERROR, "failed preparing locales %s [%d]", languages[choice].lc_all, WEXITSTATUS(i)); + } + + /* cleanup */ + if (locale_charset) free(locale_charset); + if (locale_def) free(locale_def); + if (locale_mod) free(locale_mod); + if (locale_p) free(locale_p); + setLangEnv (choice); isysLoadFont(); diff --git a/scripts/upd-instroot b/scripts/upd-instroot index 5c8d5b5..2b2fc4a 100755 --- a/scripts/upd-instroot +++ b/scripts/upd-instroot @@ -634,6 +634,7 @@ usr/bin/hmount usr/bin/humount usr/bin/killall usr/bin/logger +usr/bin/localedef usr/bin/lsattr* usr/bin/maketilo usr/bin/md5sum @@ -754,6 +755,7 @@ usr/share/hwdata/pci.ids usr/share/hwdata/usb.ids usr/share/hwdata/videoaliases usr/share/hwdata/videodrivers +usr/share/i18n usr/share/icons/hicolor/*/apps/nm-* usr/share/icons/hicolor/index.theme usr/share/locale/*/LC_MESSAGES/anaconda.mo @@ -1113,10 +1115,13 @@ chmod 04755 $DEST/usr/libexec/polkit-1/polkit-agent-helper-1 chown root:dbus $DEST/$LIBDIR/dbus-1/dbus-daemon-launch-helper chmod 04750 $DEST/$LIBDIR/dbus-1/dbus-daemon-launch-helper -# Remove locales unused during the install +# Generate default locale in case runtime doesn't work +# /usr/share/i18n/ contains sources install -m 644 $DEST/usr/share/anaconda/lang-table $DEST/etc/lang-table +rm -f $DEST/usr/lib/locale/locale-archive localedef -c -i en_US -f UTF-8 --prefix $DEST en_US +# Remove unsupported translations cat $DEST/usr/share/anaconda/lang-table* | awk ' { gsub("-", "", $4); print $4; @@ -1135,14 +1140,7 @@ for p in lib share; do ( } ); done -# Now shrink the locale-archive to contain just the minimum. -localedef --prefix $DEST --list-archive > $DEST/locales.glibc -LC_ALL=C unsupported="$(comm -13 $DEST/locales $DEST/locales.glibc)" -localedef --prefix $DEST --delete-from-archive $unsupported -mv $DEST/usr/lib/locale/locale-archive $DEST/usr/lib/locale/locale-archive.tmpl -/usr/sbin/chroot $DEST /usr/sbin/build-locale-archive - -rm -f $DEST/locales $DEST/locales.list $DEST/locales.glibc +rm -f $DEST/locales $DEST/locales.list # fix up some links for man page related stuff for file in nroff groff iconv geqn gtbl gpic grefer ; do -- 1.7.4 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list