From fc8d38770aa4385dabafdc5be18d2fa18a5a78a9 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 18 Jan 2021 11:14:10 +0100 Subject: [PATCH] Call setlocale(LC_CTYPE, locale) before calling kiconv_*() to make filename conversion work correctly. This fixes a bug where creating a file on a FAT32 after the first initialization of msdosfs_iconv, produces an invalid lowercase shortname. --- dsbmd.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/dsbmd.c b/dsbmd.c index fe20a20..6d06f9b 100644 --- a/dsbmd.c +++ b/dsbmd.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -1634,8 +1635,10 @@ ssystem(uid_t uid, const char *cmd) static int set_msdosfs_locale(const char *locale, struct iovec **iov, size_t *iovlen) { + char *prev_locale; const char *cs; + prev_locale = setlocale(LC_CTYPE, NULL); if (modfind("msdosfs_iconv") == -1) { if (errno != ENOENT) { logprint("modfind(msdosfs_iconv) failed."); @@ -1650,17 +1653,25 @@ set_msdosfs_locale(const char *locale, struct iovec **iov, size_t *iovlen) logprintx("Invalid locale string '%s'", locale); return (-1); } + if (setlocale(LC_CTYPE, locale) == NULL) + die("setlocale(%s)", locale); locale = kiconv_quirkcs(cs + 1, KICONV_VENDOR_MICSFT); + if (kiconv_add_xlat16_cspairs(ENCODING_UNICODE, locale) != 0 && + errno != EEXIST) + die("kiconv_add_xlat16_cspairs(ENCODING_UNICODE)"); if (kiconv_add_xlat16_cspair(locale, locale, KICONV_FROM_UPPER | KICONV_LOWER) != 0) { logprint("kiconv_add_xlat16_cspair()"); + if (prev_locale != NULL) + setlocale(LC_CTYPE, prev_locale); return (-1); } extend_iovec(iov, iovlen, "cs_win", ENCODING_UNICODE); extend_iovec(iov, iovlen, "cs_local", locale); extend_iovec(iov, iovlen, "cs_dos", locale); extend_iovec(iov, iovlen, "kiconv", ""); - + if (prev_locale != NULL) + setlocale(LC_CTYPE, prev_locale); return (0); }