diff -ur -x Makefile -x Makefile.in -x configure -x po rpm-4.4.2.org/rpmio/Makefile.am rpm-4.4.2/rpmio/Makefile.am --- rpm-4.4.2.org/rpmio/Makefile.am 2007-02-13 20:51:36.290623000 +0100 +++ rpm-4.4.2/rpmio/Makefile.am 2007-02-13 20:42:52.362623000 +0100 @@ -31,7 +31,7 @@ librpmio_la_SOURCES = \ LzmaDecode.c argv.c digest.c fts.c macro.c rpmdav.c \ rpmhook.c rpmio.c rpmlog.c rpmlua.c rpmmalloc.c \ - rpmpgp.c rpmrpc.c rpmsq.c rpmsw.c strcasecmp.c stubs.c url.c ugid.c + rpmpgp.c rpmrpc.c rpmsq.c rpmsw.c strcasecmp.c strtolocale.c stubs.c url.c ugid.c librpmio_la_LDFLAGS = -release 4.4 $(LDFLAGS) \ @WITH_BEECRYPT_LIB@ \ @WITH_NEON_LIB@ \ diff -ur -x Makefile -x Makefile.in -x configure -x po rpm-4.4.2.org/rpmio/rpmio.h rpm-4.4.2/rpmio/rpmio.h --- rpm-4.4.2.org/rpmio/rpmio.h 2007-02-13 20:51:36.290623000 +0100 +++ rpm-4.4.2/rpmio/rpmio.h 2007-02-13 20:43:52.742623000 +0100 @@ -709,6 +709,13 @@ */ int xstrncasecmp(const char *s1, const char * s2, size_t n) /*@*/; +/** \ingroup rpmio + * Force encoding of string. + */ +/*@only@*/ /*@null@*/ +const char * xstrtolocale(/*@only@*/ const char *str) + /*@modifies *str @*/; + #ifdef __cplusplus } #endif --- /dev/null 2007-02-07 08:10:39.238623000 +0100 +++ rpm-4.4.2/rpmio/strtolocale.c 2007-02-13 20:42:06.650623000 +0100 @@ -0,0 +1,65 @@ +/** \ingroup rpmio + * \file rpmio/strtolocale.c + */ + +#include "system.h" +#include +#include +#include "debug.h" + +static char *locale_encoding = NULL; +static int locale_encoding_is_utf8; + +const char * xstrtolocale(const char *str) +{ + iconv_t cd; + size_t src_size, dest_size; + char *result, *src, *dest; + + if (locale_encoding == NULL) { + const char *encoding = nl_langinfo(CODESET); + locale_encoding = xmalloc(strlen(encoding) + 11); + sprintf(locale_encoding, "%s//TRANSLIT", encoding); + locale_encoding_is_utf8 = strcasecmp(encoding, "UTF-8") == 0; + } + + if (!str || !*str || locale_encoding_is_utf8) + return str; + + cd = iconv_open(locale_encoding, "UTF-8"); + if (cd == (iconv_t)-1) + return str; + + src_size = strlen(str); + dest_size = src_size + 1; + result = xmalloc(dest_size); + src = (char *)str; + dest = result; + for(;;) { + size_t status = iconv(cd, &src, &src_size, &dest, &dest_size); + if (status == (size_t)-1) { + size_t dest_offset; + if (errno != E2BIG) { + free(result); + iconv_close(cd); + return str; + } + dest_offset = dest - result; + dest_size += 16; + result = xrealloc(result, dest_offset + dest_size); + dest = result + dest_offset; + } else if (src_size == 0) { + if (src == NULL) break; + src = NULL; + } + } + iconv_close(cd); + free((void *)str); + if (dest_size == 0) { + size_t dest_offset = dest - result; + result = xrealloc(result, dest_offset + 1); + dest = result + dest_offset; + } + *dest = '\0'; + return result; +}