Change the multibyte character set support so that
authorJeremy Allison <jra@samba.org>
Tue, 3 Mar 1998 20:19:14 +0000 (20:19 +0000)
committerJeremy Allison <jra@samba.org>
Tue, 3 Mar 1998 20:19:14 +0000 (20:19 +0000)
Kanji support is one case of multibyte character
support, rather than being a specific case in
single byte character support.

This allows us to add Big5 Chinese support (code page 950)
and Korean Hangul support (code page 949) at very little
cost. Also allows us to easily add future multibyte
code pages.

Makefile: Added codepages 949, 950 as we now support more multibyte
codepages.
asyncdns.c: Fixed problem with child being re-spawned when parent killed.
charcnv.c
charset.c
client.c
clitar.c
kanji.c
kanji.h
smb.h
util.c
loadparm.c: Generic multibyte codepage support (adding Big5 Chinese
            and Korean Hangul).
nmbd.c: Fixed problem with child being re-spawned when parent killed.
mangle.c: Modified str_checksum so that first 15 characters have more
          effect on outcome. This helps with short name mangling as
          most 'long' names are still shorter than 15 chars (bug was
          foobar_mng and foobar_sum would hash to the same value, with
          the modified code they hash differently.
Jeremy.

15 files changed:
source/client/client.c
source/client/clitar.c
source/client/smbmount.c
source/include/kanji.h
source/include/proto.h
source/include/smb.h
source/lib/charcnv.c
source/lib/charset.c
source/lib/kanji.c
source/lib/util.c
source/nmbd/asyncdns.c
source/nmbd/nmbd.c
source/param/loadparm.c
source/smbd/mangle.c
source/smbd/trans2.c

index 798dfe577e728c89396c9167fd0279279a25f750..988b6685a827e2708d6ee850b6d15d4e6e1acd16 100644 (file)
@@ -130,13 +130,8 @@ extern int Client;
 
 #define USENMB
 
-static BOOL setup_term_code(char *code)
-{
-       interpret_coding_system(code);
-       return True;
-}
-#define CNV_LANG(s) dos2unix_format(s,False)
-#define CNV_INPUT(s) unix2dos_format(s,True)
+#define CNV_LANG(s) dos_to_unix(s,False)
+#define CNV_INPUT(s) unix_to_dos(s,True)
 
 /****************************************************************************
 send an SMBclose on an SMB file handle
@@ -3756,15 +3751,7 @@ static void usage(char *pname)
 
   codepage_initialise(lp_client_code_page());
 
-  if(lp_client_code_page() == KANJI_CODEPAGE)
-  {
-        if (!setup_term_code (term_code))
-    {
-            DEBUG(0, ("%s: unknown terminal code name\n", optarg));
-            usage (pname);
-            exit (1);
-        }
-  }
+  interpret_coding_system(term_code);
 
   if (*workgroup == 0)
     strcpy(workgroup,lp_workgroup());
index 6a811f41c7db012806003b048f2c48a1c82e5a3a..ccaab486d0f6f4183031729650b60d17abe57b38 100644 (file)
@@ -322,33 +322,25 @@ static void fixtarname(char *tptr, char *fp, int l)
    * to lovely unix /'s :-} */
 
   *tptr++='.';
-  if(lp_client_code_page() == KANJI_CODEPAGE)
-  {
-    while (l > 0) {
-      if (is_shift_jis (*fp)) {
+
+  while (l > 0) {
+    int skip;
+    if((skip = skip_multibyte_char( *fp)) != 0) {
+      if (skip == 2) {
         *tptr++ = *fp++;
         *tptr++ = *fp++;
         l -= 2;
-      } else if (is_kana (*fp)) {
-        *tptr++ = *fp++;
-        l--;
-      } else if (*fp == '\\') {
-        *tptr++ = '/';
-        fp++;
-        l--;
-      } else {
+      } else if (skip == 1) {
         *tptr++ = *fp++;
         l--;
       }
-    }
-  }
-  else
-  {
-    while (l--)
-    {
-      *tptr=(*fp == '\\') ? '/' : *fp;
-      tptr++;
+    } else if (*fp == '\\') {
+      *tptr++ = '/';
       fp++;
+      l--;
+    } else {
+      *tptr++ = *fp++;
+      l--;
     }
   }
 }
@@ -1227,33 +1219,24 @@ static void unfixtarname(char *tptr, char *fp, int l)
   if (*fp == '.') fp++;
   if (*fp == '\\' || *fp == '/') fp++;
 
-  if(lp_client_code_page() == KANJI_CODEPAGE)
-  {
-    while (l > 0) {
-      if (is_shift_jis (*fp)) {
+  while (l > 0) {
+    int skip;
+    if(( skip = skip_multibyte_char( *fp )) != 0) {
+      if (skip == 2) {
         *tptr++ = *fp++;
         *tptr++ = *fp++;
         l -= 2;
-      } else if (is_kana (*fp)) {
-        *tptr++ = *fp++;
-        l--;
-      } else if (*fp == '/') {
-        *tptr++ = '\\';
-        fp++;
-        l--;
-      } else {
+      } else if (skip == 1) {
         *tptr++ = *fp++;
         l--;
       }
-    }
-  }
-  else
-  {
-    while (l--)
-    {
-      *tptr=(*fp == '/') ? '\\' : *fp;
-      tptr++;
+    } else if (*fp == '/') {
+      *tptr++ = '\\';
       fp++;
+      l--;
+    } else {
+      *tptr++ = *fp++;
+      l--;
     }
   }
 }
index 847c4b1f3dde3e9cafef9af1a410c5158480db69..e5902ff0d9c1579b6f201c7f97339d72f1c98e15 100644 (file)
@@ -136,13 +136,8 @@ extern int Client;
 
 #define USENMB
 
-static BOOL setup_term_code(char *code)
-{
-       interpret_coding_system(code);
-       return True;
-}
-#define CNV_LANG(s) dos2unix_format(s,False)
-#define CNV_INPUT(s) unix2dos_format(s,True)
+#define CNV_LANG(s) dos_to_unix(s,False)
+#define CNV_INPUT(s) unix_to_dos(s,True)
 
 /****************************************************************************
 check for existance of a dir
@@ -879,15 +874,7 @@ static void usage(char *pname)
 
   codepage_initialise(lp_client_code_page());
 
-  if(lp_client_code_page() == KANJI_CODEPAGE)
-  {
-        if (!setup_term_code (term_code))
-    {
-            DEBUG(0, ("%s: unknown terminal code name\n", optarg));
-            usage (pname);
-            exit (1);
-        }
-  }
+  interpret_coding_system(term_code);
 
   if (*workgroup == 0)
     strcpy(workgroup,lp_workgroup());
index 101b98cfa344563e7ccaf4034cdbd244f434a9a6..302db13a2729457a05b61ac743341716585e4780 100644 (file)
 #define bin2hex(x)                                                   \
     ( (((int) (x)) >= 10)? (((int) (x))-10 + (int) 'a'): (((int) (x)) + (int) '0') )
 
-#else /* not _KANJI_C_ */
+/* For Hangul (Korean - code page 949). */
+#define is_hangul(c) ((0x81 <= ((unsigned char) (c)) && ((unsigned char) (c)) <= 0xfd))
 
-extern char *(*_dos_to_unix)(char *str, BOOL overwrite);
-extern char *(*_unix_to_dos)(char *str, BOOL overwrite);
+/* For traditional Chinese (known as Big5 encoding - code page 950). */
+#define is_big5_c1(c) ((0xa1 <= ((unsigned char) (c)) && ((unsigned char) (c)) <= 0xf9)) 
+
+#else /* not _KANJI_C_ */
 
 /*
  * The following is needed for AIX systems that have
@@ -130,12 +133,24 @@ extern char *(*_unix_to_dos)(char *str, BOOL overwrite);
 #undef strtok
 #endif /* strtok */
 
-/* Ensure we use our definitions. */
+/* Ensure we use our definitions in all other files than kanji.c. */
 
-#define strchr sj_strchr
-#define strrchr sj_strrchr
-#define strstr sj_strstr
-#define strtok sj_strtok
+/* Function pointers we will replace. */
+extern char *(*multibyte_strchr)(char *s, int c);
+extern char *(*multibyte_strrchr)(char *s, int c);
+extern char *(*multibyte_strstr)(char *s1, char *s2);
+extern char *(*multibyte_strtok)(char *s1, char *s2);
+extern char *(*_dos_to_unix)(char *str, BOOL overwrite);
+extern char *(*_unix_to_dos)(char *str, BOOL overwrite);
+extern BOOL (*is_multibyte_char)(char c);
+
+#define strchr(s1, c) ((*multibyte_strchr)((s1), (c)))
+#define strrchr(s1, c) ((*multibyte_strrchr)((s1), (c)))
+#define strstr(s1, s2) ((*multibyte_strstr)((s1), (s2)))
+#define strtok(s1, s2) ((*multibyte_strtok)((s1), (s2)))
+#define dos_to_unix(x,y) ((*_dos_to_unix)((x), (y)))
+#define unix_to_dos(x,y) ((*_unix_to_dos)((x), (y)))
+#define skip_multibyte_char(c) ((*is_multibyte_char)((c)))
 
 #endif /* _KANJI_C_ */
 
@@ -149,7 +164,4 @@ extern char *(*_unix_to_dos)(char *str, BOOL overwrite);
 #define CAP_CODE (6)
 #define DOSV_CODE SJIS_CODE
 
-#define unix_to_dos(x,y) unix2dos_format(x,y)
-#define dos_to_unix(x,y) dos2unix_format(x,y)
-
 #endif /* _KANJI_H_ */
index 802d9973df081bc1240ad5d728360645bb175056..47ef5812ca4b1da012c413962464bd651a3a39e6 100644 (file)
@@ -9,12 +9,14 @@ BOOL allow_access(char *deny_list,char *allow_list,char *cname,char *caddr);
 /*The following definitions come from  asyncdns.c  */
 
 int asyncdns_fd(void);
+void kill_async_dns_child();
 void start_async_dns(void);
 void run_dns_queue(void);
 BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
                     struct name_record **n);
 BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
                     struct name_record **n);
+void kill_async_dns_child();
 
 /*The following definitions come from  cgi.c  */
 
@@ -206,11 +208,8 @@ int reply_trans(char *inbuf,char *outbuf, int size, int bufsize);
 
 /*The following definitions come from  kanji.c  */
 
-char *sj_strtok(char *s1, char *s2);
-char *sj_strstr(char *s1, char *s2);
-char *sj_strchr (char *s, int c);
-char *sj_strrchr(char *s, int c);
-int interpret_coding_system(char *str);
+void interpret_coding_system(char *str);
+void initialize_multibyte_vectors( int client_codepage);
 
 /*The following definitions come from  loadparm.c  */
 
index 77f4006c4aa2a6b7fe46f93dd3db9e0f0b4005d5..f7a134d797b79cf020fbc67f350cd0cce4a71964 100644 (file)
@@ -2099,7 +2099,10 @@ enum case_handling {CASE_LOWER,CASE_UPPER};
 #endif 
 
 /* Defines needed for multi-codepage support. */
+#define MSDOS_LATIN_1_CODEPAGE 850
 #define KANJI_CODEPAGE 932
+#define HANGUL_CODEPAGE 949
+#define BIG5_CODEPAGE 950
 
 #ifdef KANJI
 /* 
@@ -2110,7 +2113,7 @@ enum case_handling {CASE_LOWER,CASE_UPPER};
 /* 
  * Default client code page - 850 - Western European 
  */
-#define DEFAULT_CLIENT_CODE_PAGE 850
+#define DEFAULT_CLIENT_CODE_PAGE MSDOS_LATIN_1_CODEPAGE
 #endif /* KANJI */
 
 /* 
index f02fcb2f927d521a70575a70ae427e4610ef295b..20db58e4abd161a41ce2e04d216f8ce748d9ad8e 100644 (file)
@@ -164,9 +164,6 @@ char *unix2dos_format(char *str,BOOL overwrite)
 
     if (!mapsinited) initmaps();
 
-    if(lp_client_code_page() == KANJI_CODEPAGE)
-      return (*_unix_to_dos)(str, overwrite);
-    else {
       if (overwrite) {
           for (p = str; *p; p++) *p = unix2dos[(unsigned char)*p];
           return str;
@@ -175,7 +172,6 @@ char *unix2dos_format(char *str,BOOL overwrite)
           *dp = 0;
           return cvtbuf;
       }
-    }
 }
 
 /*
@@ -188,9 +184,6 @@ char *dos2unix_format(char *str, BOOL overwrite)
 
     if (!mapsinited) initmaps();
 
-    if(lp_client_code_page() == KANJI_CODEPAGE)
-      return (*_dos_to_unix)(str, overwrite);
-    else {
       if (overwrite) {
           for (p = str; *p; p++) *p = dos2unix[(unsigned char)*p];
           return str;
@@ -199,7 +192,6 @@ char *dos2unix_format(char *str, BOOL overwrite)
           *dp = 0;
           return cvtbuf;
       }
-    }
 }
 
 
index 79a82f8587be3296f6546c4530477def2e106b1b..fe170bdcf5b48fd261110acab7170e318a44b1b5 100644 (file)
@@ -347,14 +347,21 @@ void codepage_initialise(int client_codepage)
 for code page %d failed. Using default client codepage 932\n", 
              CODEPAGEDIR, client_codepage, client_codepage));
     cp = cp_932;
+    client_codepage = KANJI_CODEPAGE;
 #else /* KANJI */
     DEBUG(6,("codepage_initialise: loading dynamic codepage file %s/codepage.%d \
 for code page %d failed. Using default client codepage 850\n", 
              CODEPAGEDIR, client_codepage, client_codepage));
     cp = cp_850;
+    client_codepage = MSDOS_LATIN_1_CODEPAGE;
 #endif /* KANJI */
   }
 
+  /*
+   * Setup the function pointers for the loaded codepage.
+   */
+  initialize_multibyte_vectors( client_codepage );
+
   if(cp)
   {
     for(i = 0; !((cp[i][0] == '\0') && (cp[i][1] == '\0')); i++)
index d63798914e9871445c96f345d96b7db76a3d0726..9360405547672d0f7fd89bc3c9fbc942106b8599 100644 (file)
 #define _KANJI_C_
 #include "includes.h"
 
+/*
+ * Function pointers that get overridden when multi-byte code pages
+ * are loaded.
+ */
+
+char *(*multibyte_strchr)(char *, int ) = (char *(*)(char *, int )) strchr;
+char *(*multibyte_strrchr)(char *, int ) = (char *(*)(char *, int )) strrchr;
+char *(*multibyte_strstr)(char *, char *) = (char *(*)(char *, char *)) strstr;
+char *(*multibyte_strtok)(char *, char *) = (char *(*)(char *, char *)) strtok;
+
+/*
+ * Kanji is treated differently here due to historical accident of
+ * it being the first non-English codepage added to Samba.
+ * The define 'KANJI' is being overloaded to mean 'use kanji codepage
+ * by default' and also 'this is the filename-to-disk conversion 
+ * method to use'. This really should be removed and all control
+ * over this left in the smb.conf parameters 'client codepage'
+ * and 'coding system'.
+ */
+
+#ifndef KANJI
+
+/*
+ * Set the default conversion to be the functions in
+ * charcnv.c.
+ */
+
+static int not_multibyte_char(char);
+
+char *(*_dos_to_unix)(char *, BOOL) = dos2unix_format;
+char *(*_unix_to_dos)(char *, BOOL) = unix2dos_format;
+int (*is_multibyte_char)(char) = not_multibyte_char;
+
+#else /* KANJI */
+
+/*
+ * Set the default conversion to be the function
+ * sj_to_sj in this file.
+ */
+
+static char *sj_to_sj(char *from, BOOL overwrite);
+static int kanji_multibyte_char(char);
+
+char *(*_dos_to_unix)(char *, BOOL) = sj_to_sj;
+char *(*_unix_to_dos)(char *, BOOL) = sj_to_sj;
+int (*is_multibyte_char)(char) = kanji_multibyte_char;
+
+#endif /* KANJI */
+
 /* jis si/so sequence */
 static char jis_kso = JIS_KSO;
 static char jis_ksi = JIS_KSI;
@@ -37,13 +86,10 @@ static char hex_tag = HEXTAG;
 ********************************************************************/
 /*******************************************************************
  search token from S1 separated any char of S2
- S1 contain SHIFT JIS chars.
+ S1 contains SHIFT JIS chars.
 ********************************************************************/
-char *sj_strtok(char *s1, char *s2)
+static char *sj_strtok(char *s1, char *s2)
 {
-  if (lp_client_code_page() != KANJI_CODEPAGE) {
-   return strtok(s1, s2);
-  } else {
     static char *s = NULL;
     char *q;
     if (!s1) {
@@ -75,18 +121,14 @@ char *sj_strtok(char *s1, char *s2)
        return q;
     }
     return NULL;
-  }
 }
 
 /*******************************************************************
  search string S2 from S1
- S1 contain SHIFT JIS chars.
+ S1 contains SHIFT JIS chars.
 ********************************************************************/
-char *sj_strstr(char *s1, char *s2)
+static char *sj_strstr(char *s1, char *s2)
 {
-  if (lp_client_code_page() != KANJI_CODEPAGE) {
-    return strstr(s1, s2);
-  } else {
     int len = strlen ((char *) s2);
     if (!*s2) 
        return (char *) s1;
@@ -102,18 +144,14 @@ char *sj_strstr(char *s1, char *s2)
        }
     }
     return 0;
-  }
 }
 
 /*******************************************************************
  Search char C from beginning of S.
- S contain SHIFT JIS chars.
+ S contains SHIFT JIS chars.
 ********************************************************************/
-char *sj_strchr (char *s, int c)
+static char *sj_strchr (char *s, int c)
 {
-  if (lp_client_code_page() != KANJI_CODEPAGE) {
-    return strchr(s, c);
-  } else {
     for (; *s; ) {
        if (*s == c)
            return (char *) s;
@@ -124,18 +162,14 @@ char *sj_strchr (char *s, int c)
        }
     }
     return 0;
-  }
 }
 
 /*******************************************************************
  Search char C end of S.
- S contain SHIFT JIS chars.
+ S contains SHIFT JIS chars.
 ********************************************************************/
-char *sj_strrchr(char *s, int c)
+static char *sj_strrchr(char *s, int c)
 {
-  if (lp_client_code_page() != KANJI_CODEPAGE) {
-    return strrchr(s, c);
-  } else {
     char *q;
 
     for (q = 0; *s; ) {
@@ -149,7 +183,249 @@ char *sj_strrchr(char *s, int c)
        }
     }
     return q;
+}
+
+/*******************************************************************
+ Kanji multibyte char function.
+*******************************************************************/
+   
+static int kanji_multibyte_char(char c)
+{
+  if(is_shift_jis(c)) {
+    return 2;
+  } else if (is_kana(c)) {
+    return 1;
+  }
+  return 0;
+}
+
+/*******************************************************************
+  Hangul (Korean - code page 949) functions
+********************************************************************/
+/*******************************************************************
+ search token from S1 separated any char of S2
+ S1 contains hangul chars.
+********************************************************************/
+static char *hangul_strtok(char *s1, char *s2)
+{
+    static char *s = NULL;
+    char *q;
+    if (!s1) {
+        if (!s) {
+            return NULL;
+        }
+        s1 = s;
+    }
+    for (q = s1; *s1; ) {
+        if (is_hangul (*s1)) {
+            s1 += 2;
+        } else {
+            char *p = strchr (s2, *s1);
+            if (p) {
+                if (s1 != q) {
+                    s = s1 + 1;
+                    *s1 = '\0';
+                    return q;
+                }
+                q = s1 + 1;
+            }
+            s1++;
+        }
+    }
+    s = NULL;
+    if (*q) {
+        return q;
+    }
+    return NULL;
+}
+
+/*******************************************************************
+ search string S2 from S1
+ S1 contains hangul chars.
+********************************************************************/
+static char *hangul_strstr(char *s1, char *s2)
+{
+    int len = strlen ((char *) s2);
+    if (!*s2)
+        return (char *) s1;
+    for (;*s1;) {
+        if (*s1 == *s2) {
+            if (strncmp (s1, s2, len) == 0)
+                return (char *) s1;
+        }
+        if (is_hangul (*s1)) {
+            s1 += 2;
+        } else {
+            s1++;
+        }
+    }
+    return 0;
+}
+
+/*******************************************************************
+ Search char C from beginning of S.
+ S contains hangul chars.
+********************************************************************/
+static char *hangul_strchr (char *s, int c)
+{
+    for (; *s; ) {
+        if (*s == c)
+            return (char *) s;
+        if (is_hangul (*s)) {
+            s += 2;
+        } else {
+            s++;
+        }
+    }
+    return 0;
+}
+
+/*******************************************************************
+ Search char C end of S.
+ S contains hangul chars.
+********************************************************************/
+static char *hangul_strrchr(char *s, int c)
+{
+    char *q;
+    for (q = 0; *s; ) {
+        if (*s == c) {
+            q = (char *) s;
+        }
+        if (is_hangul (*s)) {
+            s += 2;
+        } else {
+            s++;
+        }
+    }
+    return q;
+}
+
+/*******************************************************************
+ Hangul multibyte char function.
+*******************************************************************/
+
+static int hangul_multibyte_char(char c)
+{
+  if( is_hangul(c)) {
+    return 2;
+  }
+  return 0;
+}
+
+/*******************************************************************
+  Big5 Traditional Chinese (code page 950) functions
+********************************************************************/
+
+/*******************************************************************
+ search token from S1 separated any char of S2
+ S1 contains big5 chars.
+********************************************************************/
+static char *big5_strtok(char *s1, char *s2)
+{
+    static char *s = NULL;
+    char *q;
+    if (!s1) {
+        if (!s) {
+            return NULL;
+        }
+        s1 = s;
+    }
+    for (q = s1; *s1; ) {
+        if (is_big5_c1 (*s1)) {
+            s1 += 2;
+        } else {
+            char *p = strchr (s2, *s1);
+            if (p) {
+                if (s1 != q) {
+                    s = s1 + 1;
+                    *s1 = '\0';
+                    return q;
+                }
+                q = s1 + 1;
+            }
+            s1++;
+        }
+    }
+    s = NULL;
+    if (*q) {
+        return q;
+    }
+    return NULL;
+}
+
+/*******************************************************************
+ search string S2 from S1
+ S1 contains big5 chars.
+********************************************************************/
+static char *big5_strstr(char *s1, char *s2)
+{
+    int len = strlen ((char *) s2);
+    if (!*s2)
+        return (char *) s1;
+    for (;*s1;) {
+        if (*s1 == *s2) {
+            if (strncmp (s1, s2, len) == 0)
+                return (char *) s1;
+        }
+        if (is_big5_c1 (*s1)) {
+            s1 += 2;
+        } else {
+            s1++;
+        }
+    }
+    return 0;
+}
+
+/*******************************************************************
+ Search char C from beginning of S.
+ S contains big5 chars.
+********************************************************************/
+static char *big5_strchr (char *s, int c)
+{
+    for (; *s; ) {
+        if (*s == c)
+            return (char *) s;
+        if (is_big5_c1 (*s)) {
+            s += 2;
+        } else {
+            s++;
+        }
+    }
+    return 0;
+}
+
+/*******************************************************************
+ Search char C end of S.
+ S contains big5 chars.
+********************************************************************/
+static char *big5_strrchr(char *s, int c)
+{
+    char *q;
+    for (q = 0; *s; ) {
+        if (*s == c) {
+            q = (char *) s;
+        }
+        if (is_big5_c1 (*s)) {
+            s += 2;
+        } else {
+            s++;
+        }
+    }
+    return q;
+}
+
+/*******************************************************************
+ Big5 multibyte char function.
+*******************************************************************/
+
+static int big5_multibyte_char(char c)
+{
+  if( is_big5_c1(c)) {
+    return 2;
   }
+  return 0;
 }
 
 /*******************************************************************
@@ -770,17 +1046,17 @@ static char *sj_to_sj(char *from, BOOL overwrite)
  _dos_to_unix          _unix_to_dos
 ************************************************************************/
 
-char *(*_dos_to_unix)(char *str, BOOL overwrite) = sj_to_sj;
-char *(*_unix_to_dos)(char *str, BOOL overwrite) = sj_to_sj;
-
-static int setup_string_function(int codes)
+static void setup_string_function(int codes)
 {
     switch (codes) {
     default:
+        _dos_to_unix = dos2unix_format;
+        _unix_to_dos = unix2dos_format;
+        break;
+
     case SJIS_CODE:
        _dos_to_unix = sj_to_sj;
        _unix_to_dos = sj_to_sj;
-
        break;
        
     case EUC_CODE:
@@ -813,13 +1089,12 @@ static int setup_string_function(int codes)
        _unix_to_dos = cap_to_sj;
        break;
     }
-    return codes;
 }
 
 /*
  * Interpret coding system.
  */
-int interpret_coding_system(char *str)
+void interpret_coding_system(char *str)
 {
     int codes = UNKNOWN_CODE;
     
@@ -909,5 +1184,58 @@ int interpret_coding_system(char *str)
        jis_kso = '@';
        jis_ksi = 'H';
     }  
-    return setup_string_function (codes);
+    setup_string_function (codes);
+}
+
+/*******************************************************************
+ Non multibyte char function.
+*******************************************************************/
+   
+static int not_multibyte_char(char c)
+{
+  return 0;
+}
+
+/*******************************************************************
+ Setup the function pointers for the functions that are replaced
+ when multi-byte codepages are used.
+
+ The dos_to_unix and unix_to_dos function pointers are only
+ replaced by setup_string_function called by interpret_coding_system
+ above.
+*******************************************************************/
+
+void initialize_multibyte_vectors( int client_codepage)
+{
+  switch( client_codepage )
+  {
+  case KANJI_CODEPAGE:
+    multibyte_strchr = (char *(*)(char *, int )) sj_strchr;
+    multibyte_strrchr = (char *(*)(char *, int )) sj_strrchr;
+    multibyte_strstr = (char *(*)(char *, char *)) sj_strstr;
+    multibyte_strtok = (char *(*)(char *, char *)) sj_strtok;
+    is_multibyte_char = kanji_multibyte_char;
+    break;
+  case HANGUL_CODEPAGE:
+    multibyte_strchr = (char *(*)(char *, int )) hangul_strchr;
+    multibyte_strrchr = (char *(*)(char *, int )) hangul_strrchr;
+    multibyte_strstr = (char *(*)(char *, char *)) hangul_strstr;
+    multibyte_strtok = (char *(*)(char *, char *)) hangul_strtok;
+    is_multibyte_char = hangul_multibyte_char;
+    break;
+  case BIG5_CODEPAGE:
+    multibyte_strchr = (char *(*)(char *, int )) big5_strchr;
+    multibyte_strrchr = (char *(*)(char *, int )) big5_strrchr;
+    multibyte_strstr = (char *(*)(char *, char *)) big5_strstr;
+    multibyte_strtok = (char *(*)(char *, char *)) big5_strtok;
+    is_multibyte_char = big5_multibyte_char;
+    break;
+  default:
+    multibyte_strchr = (char *(*)(char *, int )) strchr;
+    multibyte_strrchr = (char *(*)(char *, int )) strrchr;
+    multibyte_strstr = (char *(*)(char *, char *)) strstr;
+    multibyte_strtok = (char *(*)(char *, char *)) strtok;
+    is_multibyte_char = not_multibyte_char;
+    break; 
+  }
 }
index 18614caeed8f6e5b9080f8015496939e1446b024..5af41cc06cd625fc7d666bddedb057cee257afd9 100644 (file)
@@ -887,6 +887,15 @@ int StrCaseCmp(char *s, char *t)
      asynchronous upper to lower mapping.
    */
 #if !defined(KANJI_WIN95_COMPATIBILITY)
+  /*
+   * For completeness we should put in equivalent code for code pages
+   * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+   * doubt anyone wants Samba to behave differently from Win95 and WinNT
+   * here. They both treat full width ascii characters as case senstive
+   * filenames (ie. they don't do the work we do here).
+   * JRA.
+   */
+
   if(lp_client_code_page() == KANJI_CODEPAGE)
   {
     /* Win95 treats full width ascii characters as case sensitive. */
@@ -951,6 +960,15 @@ int StrnCaseCmp(char *s, char *t, int n)
      asynchronous upper to lower mapping.
    */
 #if !defined(KANJI_WIN95_COMPATIBILITY)
+  /*
+   * For completeness we should put in equivalent code for code pages
+   * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+   * doubt anyone wants Samba to behave differently from Win95 and WinNT
+   * here. They both treat full width ascii characters as case senstive
+   * filenames (ie. they don't do the work we do here).
+   * JRA. 
+   */
+
   if(lp_client_code_page() == KANJI_CODEPAGE)
   {
     /* Win95 treats full width ascii characters as case sensitive. */
@@ -1058,6 +1076,15 @@ void strlower(char *s)
   while (*s)
   {
 #if !defined(KANJI_WIN95_COMPATIBILITY)
+  /*
+   * For completeness we should put in equivalent code for code pages
+   * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+   * doubt anyone wants Samba to behave differently from Win95 and WinNT
+   * here. They both treat full width ascii characters as case senstive
+   * filenames (ie. they don't do the work we do here).
+   * JRA. 
+   */
+
     if(lp_client_code_page() == KANJI_CODEPAGE)
     {
       /* Win95 treats full width ascii characters as case sensitive. */
@@ -1096,6 +1123,15 @@ void strupper(char *s)
   while (*s)
   {
 #if !defined(KANJI_WIN95_COMPATIBILITY)
+  /*
+   * For completeness we should put in equivalent code for code pages
+   * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+   * doubt anyone wants Samba to behave differently from Win95 and WinNT
+   * here. They both treat full width ascii characters as case senstive
+   * filenames (ie. they don't do the work we do here).
+   * JRA. 
+   */
+
     if(lp_client_code_page() == KANJI_CODEPAGE)
     {
       /* Win95 treats full width ascii characters as case sensitive. */
@@ -1157,6 +1193,15 @@ void string_replace(char *s,char oldc,char newc)
   while (*s)
   {
 #if !defined(KANJI_WIN95_COMPATIBILITY)
+  /*
+   * For completeness we should put in equivalent code for code pages
+   * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+   * doubt anyone wants Samba to behave differently from Win95 and WinNT
+   * here. They both treat full width ascii characters as case senstive
+   * filenames (ie. they don't do the work we do here).
+   * JRA. 
+   */
+
     if(lp_client_code_page() == KANJI_CODEPAGE)
     {
       /* Win95 treats full width ascii characters as case sensitive. */
@@ -1783,6 +1828,15 @@ BOOL strhasupper(char *s)
   while (*s) 
   {
 #if !defined(KANJI_WIN95_COMPATIBILITY)
+  /*
+   * For completeness we should put in equivalent code for code pages
+   * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+   * doubt anyone wants Samba to behave differently from Win95 and WinNT
+   * here. They both treat full width ascii characters as case senstive
+   * filenames (ie. they don't do the work we do here).
+   * JRA. 
+   */
+
     if(lp_client_code_page() == KANJI_CODEPAGE)
     {
       /* Win95 treats full width ascii characters as case sensitive. */
@@ -1816,6 +1870,15 @@ BOOL strhaslower(char *s)
   while (*s) 
   {
 #if !defined(KANJI_WIN95_COMPATIBILITY)
+  /*
+   * For completeness we should put in equivalent code for code pages
+   * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+   * doubt anyone wants Samba to behave differently from Win95 and WinNT
+   * here. They both treat full width ascii characters as case senstive
+   * filenames (ie. they don't do the work we do here).
+   * JRA. 
+   */
+
     if(lp_client_code_page() == KANJI_CODEPAGE)
     {
       /* Win95 treats full width ascii characters as case sensitive. */
@@ -1857,6 +1920,15 @@ int count_chars(char *s,char c)
   int count=0;
 
 #if !defined(KANJI_WIN95_COMPATIBILITY)
+  /*
+   * For completeness we should put in equivalent code for code pages
+   * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+   * doubt anyone wants Samba to behave differently from Win95 and WinNT
+   * here. They both treat full width ascii characters as case senstive
+   * filenames (ie. they don't do the work we do here).
+   * JRA. 
+   */
+
   if(lp_client_code_page() == KANJI_CODEPAGE)
   {
     /* Win95 treats full width ascii characters as case sensitive. */
index 3b71369d67058d57e41ffc6c6514017b20e94012..3fb16a08e94497993f4742e1a08d4bd14e205816 100644 (file)
@@ -103,7 +103,8 @@ static void asyncdns_process(void)
 }
 
 /**************************************************************************** **
-  catch a sigterm
+  catch a sigterm (in the child process - the parent has a different handler
+  see nmbd.c for details).
   We need a separate term handler here so we don't release any 
   names that our parent is going to release, or overwrite a 
   WINS db that our parent is going to write.
@@ -116,6 +117,17 @@ static int sig_term()
   return 0;
 }
 
+/***************************************************************************
+ Called by the parent process when it receives a SIGTERM - also kills the
+ child so we don't get child async dns processes lying around, causing trouble.
+  ****************************************************************************/
+
+void kill_async_dns_child()
+{
+  if(child_pid != 0 && child_pid != -1)
+    kill(child_pid, SIGTERM);
+}
+
 /***************************************************************************
   create a child process to handle DNS lookups
   ****************************************************************************/
@@ -326,4 +338,12 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
           send_wins_name_query_response(0, p, *n);
        return False;
 }
+
+/***************************************************************************
+ With sync dns there is no child to kill on SIGTERM.
+  ****************************************************************************/
+void kill_async_dns_child()
+{
+  return;
+}
 #endif
index d42580bcbd7fca9ce61cc5d112098a191ac671db..1a12e0eec08437fa49117707f10b76bf6b4de8a8 100644 (file)
@@ -74,6 +74,9 @@ static int sig_term()
   /* Announce all server entries as 0 time-to-live, 0 type. */
   announce_my_servers_removed();
 
+  /* If there was an async dns child - kill it. */
+  kill_async_dns_child();
+
   exit(0);
 
   /* Keep compiler happy.. */
index 0bb20567458978fc2161df1ae9862236e1433ed5..c0f54860c1b78ad60084ca85744cb49c928f66b5 100644 (file)
 #include "includes.h"
 
 /* Set default coding system for KANJI if none specified in Makefile. */
+/* 
+ * We treat KANJI specially due to historical precedent (it was the
+ * first non-english codepage added to Samba). With the new dynamic
+ * codepage support this is not needed anymore.
+ *
+ * The define 'KANJI' is being overloaded to mean 'use kanji codepage
+ * by default' and also 'this is the filename-to-disk conversion 
+ * method to use'. This really should be removed and all control
+ * over this left in the smb.conf parameters 'client codepage'
+ * and 'coding system'.
+ */
 #ifndef KANJI
 #define KANJI "sjis"
 #endif /* KANJI */
@@ -721,7 +732,6 @@ static void init_globals(void)
   Globals.bNISHomeMap = False;
   string_set(&Globals.szNISHomeMapName, "auto.home");
 #endif
-  interpret_coding_system(KANJI);
   Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
   Globals.bTimeServer = False;
   Globals.bBindInterfacesOnly = False;
@@ -748,6 +758,13 @@ static void init_globals(void)
   Globals.bWINSproxy = False;
 
   Globals.bDNSproxy = True;
+
+  /*
+   * This must be done last as it checks the value in 
+   * client_code_page.
+   */
+
+  interpret_coding_system(KANJI);
 }
 
 /***************************************************************************
index 7b6a5635110d56b8e2889e21686ea6a60c1d843e..d0d5ada24799990c3be68e888413827da248668c 100644 (file)
@@ -42,7 +42,7 @@ int str_checksum(char *s)
   while( *s )
     {
     c = *s;
-    res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
+    res ^= (c << (15-(i%15))) ^ (c >> (i % 15));
     s++; i++;
     }
   return(res);
@@ -130,38 +130,25 @@ BOOL is_8_3(char *fname, BOOL check_case)
 
   dot_pos = strchr(fname,'.');
 
-    {
+  {
     char *p = fname;
+    int skip;
 
-    if(lp_client_code_page() == KANJI_CODEPAGE)
-      {
-      dot_pos = 0;
-      while (*p)
-        {
-        if (is_shift_jis (*p)) 
-          p += 2;
-        else if (is_kana (*p)) 
-          p ++;
-        else 
-          {
-          if (*p == '.' && !dot_pos)
-            dot_pos = (char *) p;
-          if (!isdoschar(*p))
-            return(False);
-          p++;
-          }
-        }
-      }      
-    else
+    dot_pos = 0;
+    while (*p)
+    {
+      if((skip = skip_multibyte_char( *p )) != 0)
+        p += skip;
+      else 
       {
-      while (*p)
-        {
+        if (*p == '.' && !dot_pos)
+          dot_pos = (char *) p;
         if (!isdoschar(*p))
           return(False);
         p++;
-        }      
       }
     }
+  }      
 
   /* no dot and less than 9 means OK */
   if (!dot_pos)
@@ -542,6 +529,7 @@ void mangle_name_83(char *s)
   char base[9];
   int baselen = 0;
   int extlen = 0;
+  int skip;
 
   extension[0]=0;
   base[0]=0;
@@ -572,40 +560,29 @@ void mangle_name_83(char *s)
       *p++ = 0;
       while (*p && extlen < 3)
         {
-        if(lp_client_code_page() == KANJI_CODEPAGE)
+        skip = skip_multibyte_char(*p);
+        if (skip == 2)
           {
-          if (is_shift_jis (*p))
+          if (extlen < 2)
             {
-            if (extlen < 2)
-              {
-              extension[extlen++] = p[0];
-              extension[extlen++] = p[1];
-              }
-            else 
-              {
-              extension[extlen++] = base36 (((unsigned char) *p) % 36);
-              }
-            p += 2;
+            extension[extlen++] = p[0];
+            extension[extlen++] = p[1];
             }
-          else
+          else 
             {
-            if( is_kana (*p) )
-              {
-              extension[extlen++] = p[0];
-              p++;
-              }
-            else 
-              {
-              if (isdoschar (*p) && *p != '.')
-                extension[extlen++] = p[0];
-              p++;
-              }
+            extension[extlen++] = base36 (((unsigned char) *p) % 36);
             }
+          p += 2;
           }
-        else
+        else if( skip == 1 )
           {
-          if (isdoschar(*p) && *p != '.')
-            extension[extlen++] = *p;
+          extension[extlen++] = p[0];
+          p++;
+          }
+        else 
+          {
+          if (isdoschar (*p) && *p != '.')
+            extension[extlen++] = p[0];
           p++;
           }
         }
@@ -617,9 +594,8 @@ void mangle_name_83(char *s)
 
   while (*p && baselen < 5)
     {
-    if(lp_client_code_page() == KANJI_CODEPAGE)
-      {
-      if (is_shift_jis (*p))
+      skip = skip_multibyte_char(*p);
+      if (skip == 2)
         {
         if (baselen < 4)
           {
@@ -632,27 +608,17 @@ void mangle_name_83(char *s)
           }
         p += 2;
         }
-      else
+      else if( skip == 1)
         {
-        if( is_kana (*p) )
-          {
+        base[baselen++] = p[0];
+        p++;
+        }
+      else 
+        {
+        if (isdoschar (*p) && *p != '.')
           base[baselen++] = p[0];
-          p++;
-          }
-        else 
-          {
-          if (isdoschar (*p) && *p != '.')
-            base[baselen++] = p[0];
-          p++;
-          }
+        p++;
         }
-      }
-    else
-      {
-      if (isdoschar(*p) && *p != '.')
-        base[baselen++] = *p;
-      p++;
-      }
     }
   base[baselen] = 0;
 
@@ -679,6 +645,7 @@ static BOOL illegal_name(char *name)
   static unsigned char illegal[256];
   static BOOL initialised=False;
   unsigned char *s;
+  int skip;
 
   if( !initialised )
     {
@@ -690,26 +657,19 @@ static BOOL illegal_name(char *name)
       illegal[*s] = True;
     }
 
-  if(lp_client_code_page() == KANJI_CODEPAGE)
+  for (s = (unsigned char *)name; *s;)
     {
-    for (s = (unsigned char *)name; *s;)
+    skip = skip_multibyte_char( *s );
+    if (skip != 0)
+      s += skip;
+    else
       {
-      if (is_shift_jis (*s))
-        s += 2;
+      if (illegal[*s])
+        return(True);
       else
-        {
-        if (illegal[*s])
-          return(True);
-        else
-          s++;
-        }
+        s++;
       }
     }
-  else
-    {
-    for (s = (unsigned char *)name;*s;s++)
-      if (illegal[*s]) return(True);
-    }
 
   return(False);
   } /* illegal_name */
index 35272ae3d96a6aa45e1b9675ab63705480be0b29..3cd6c138c87ceab1f83fa2257a3bc199f84811d4 100644 (file)
@@ -908,11 +908,14 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
     start_pos = TellDir(dirptr);
     for(current_pos = start_pos; current_pos >= 0; current_pos--)
     {
+      DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
+
       SeekDir(dirptr, current_pos);
       dname = ReadDirName(dirptr);
       if(dname && strcsequal( resume_name, dname))
       {
         SeekDir(dirptr, current_pos+1);
+        DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
         break;
       }
     }
@@ -923,12 +926,14 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
 
     if(current_pos < 0)
     {
+      DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
       SeekDir(dirptr, start_pos);
       for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
       {
         if(strcsequal( resume_name, dname))
         {
           SeekDir(dirptr, current_pos+1);
+          DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
           break;
         }
       } /* end for */