r3169: unlink() is called on the listening unix socket every time a child process
[nivanova/samba-autobuild/.git] / source4 / lib / charcnv.c
index e5331b973ee25e75cae8d5ab49f468c418cccaff..3c27d596647e6719503f6c07b53cd5a8d2f1a9f2 100644 (file)
@@ -57,12 +57,38 @@ static const char *charset_name(charset_t ch)
 
 static smb_iconv_t conv_handles[NUM_CHARSETS][NUM_CHARSETS];
 
+/**
+ re-initialize iconv conversion descriptors
+**/
+void init_iconv(void)
+{
+       charset_t c1, c2;
+       for (c1=0;c1<NUM_CHARSETS;c1++) {
+               for (c2=0;c2<NUM_CHARSETS;c2++) {
+                       if (conv_handles[c1][c2] != NULL) {
+                               if (conv_handles[c1][c2] != (smb_iconv_t)-1) {
+                                       smb_iconv_close(conv_handles[c1][c2]);
+                               }
+                               conv_handles[c1][c2] = NULL;
+                       }
+               }
+       }
+
+}
+
 /*
   on-demand initialisation of conversion handles
 */
 static smb_iconv_t get_conv_handle(charset_t from, charset_t to)
 {
        const char *n1, *n2;
+       static int initialised;
+       /* auto-free iconv memory on exit so valgrind reports are easier
+          to look at */
+       if (initialised == 0) {
+               initialised = 1;
+               atexit(init_iconv);
+       }
 
        if (conv_handles[from][to]) {
                return conv_handles[from][to];
@@ -72,27 +98,22 @@ static smb_iconv_t get_conv_handle(charset_t from, charset_t to)
        n2 = charset_name(to);
 
        conv_handles[from][to] = smb_iconv_open(n2,n1);
-
-       return conv_handles[from][to];
-}
-
-/**
- re-initialize iconv conversion descriptors
-**/
-void init_iconv(void)
-{
-       charset_t c1, c2;
-       for (c1=0;c1<NUM_CHARSETS;c1++) {
-               for (c2=0;c2<NUM_CHARSETS;c2++) {
-                       if (conv_handles[c1][c2] != NULL) {
-                               if (conv_handles[c1][c2] != (smb_iconv_t)-1) {
-                                       smb_iconv_close(conv_handles[c1][c2]);
-                               }
-                               conv_handles[c1][c2] = NULL;
-                       }
+       
+       if (conv_handles[from][to] == (smb_iconv_t)-1) {
+               if ((from == CH_DOS || to == CH_DOS) &&
+                   strcasecmp(charset_name(CH_DOS), "ASCII") != 0) {
+                       DEBUG(0,("dos charset '%s' unavailable - using ASCII\n",
+                                charset_name(CH_DOS)));
+                       lp_set_cmdline("dos charset", "ASCII");
+
+                       n1 = charset_name(from);
+                       n2 = charset_name(to);
+                       
+                       conv_handles[from][to] = smb_iconv_open(n2,n1);
                }
        }
 
+       return conv_handles[from][to];
 }
 
 
@@ -185,7 +206,8 @@ ssize_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to,
 
        if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
                /* conversion not supported, return -1*/
-               DEBUG(3, ("convert_string_talloc: conversion not supported!\n"));
+               DEBUG(3, ("convert_string_talloc: conversion from %s to %s not supported!\n",
+                         charset_name(from), charset_name(to)));
                return -1;
        }