summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/client/client.c19
-rw-r--r--source3/client/clitar.c63
-rw-r--r--source3/client/smbmount.c19
-rw-r--r--source3/include/kanji.h34
-rw-r--r--source3/include/proto.h9
-rw-r--r--source3/include/smb.h5
-rw-r--r--source3/lib/charcnv.c8
-rw-r--r--source3/lib/charset.c7
-rw-r--r--source3/lib/kanji.c390
-rw-r--r--source3/lib/util.c72
-rw-r--r--source3/nmbd/asyncdns.c22
-rw-r--r--source3/nmbd/nmbd.c3
-rw-r--r--source3/param/loadparm.c19
-rw-r--r--source3/smbd/mangle.c136
-rw-r--r--source3/smbd/trans2.c5
15 files changed, 593 insertions, 218 deletions
diff --git a/source3/client/client.c b/source3/client/client.c
index 798dfe577e..988b6685a8 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -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());
diff --git a/source3/client/clitar.c b/source3/client/clitar.c
index 6a811f41c7..ccaab486d0 100644
--- a/source3/client/clitar.c
+++ b/source3/client/clitar.c
@@ -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--;
}
}
}
diff --git a/source3/client/smbmount.c b/source3/client/smbmount.c
index 847c4b1f3d..e5902ff0d9 100644
--- a/source3/client/smbmount.c
+++ b/source3/client/smbmount.c
@@ -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());
diff --git a/source3/include/kanji.h b/source3/include/kanji.h
index 101b98cfa3..302db13a27 100644
--- a/source3/include/kanji.h
+++ b/source3/include/kanji.h
@@ -103,10 +103,13 @@
#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_ */
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 802d9973df..47ef5812ca 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -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 */
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 77f4006c4a..f7a134d797 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -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 */
/*
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c
index f02fcb2f92..20db58e4ab 100644
--- a/source3/lib/charcnv.c
+++ b/source3/lib/charcnv.c
@@ -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;
}
- }
}
diff --git a/source3/lib/charset.c b/source3/lib/charset.c
index 79a82f8587..fe170bdcf5 100644
--- a/source3/lib/charset.c
+++ b/source3/lib/charset.c
@@ -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++)
diff --git a/source3/lib/kanji.c b/source3/lib/kanji.c
index d63798914e..9360405547 100644
--- a/source3/lib/kanji.c
+++ b/source3/lib/kanji.c
@@ -27,6 +27,55 @@
#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;
+ }
}
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 18614caeed..5af41cc06c 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -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. */
diff --git a/source3/nmbd/asyncdns.c b/source3/nmbd/asyncdns.c
index 3b71369d67..3fb16a08e9 100644
--- a/source3/nmbd/asyncdns.c
+++ b/source3/nmbd/asyncdns.c
@@ -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.
@@ -117,6 +118,17 @@ static int sig_term()
}
/***************************************************************************
+ 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
****************************************************************************/
void start_async_dns(void)
@@ -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
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index d42580bcbd..1a12e0eec0 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -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.. */
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 0bb2056745..c0f54860c1 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -50,6 +50,17 @@
#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);
}
/***************************************************************************
diff --git a/source3/smbd/mangle.c b/source3/smbd/mangle.c
index 7b6a563511..d0d5ada247 100644
--- a/source3/smbd/mangle.c
+++ b/source3/smbd/mangle.c
@@ -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 */
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 35272ae3d9..3cd6c138c8 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -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 */