summaryrefslogtreecommitdiff
path: root/source3/lib
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/charcnv.c584
-rw-r--r--source3/lib/charset.c287
-rw-r--r--source3/lib/cmd_interp.c4
-rw-r--r--source3/lib/doscalls.c345
-rw-r--r--source3/lib/iconv.c346
-rw-r--r--source3/lib/kanji.c1691
-rw-r--r--source3/lib/ms_fnmatch.c145
-rw-r--r--source3/lib/sysacls.c2
-rw-r--r--source3/lib/system.c170
-rw-r--r--source3/lib/util.c19
-rw-r--r--source3/lib/util_file.c25
-rw-r--r--source3/lib/util_str.c808
-rw-r--r--source3/lib/util_unistr.c1644
13 files changed, 947 insertions, 5123 deletions
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c
index 4a3d7090e3..388c05f816 100644
--- a/source3/lib/charcnv.c
+++ b/source3/lib/charcnv.c
@@ -1,8 +1,9 @@
/*
Unix SMB/Netbios implementation.
- Version 1.9.
+ Version 3.0
Character set conversion Extensions
- Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Igor Vergeichik <iverg@mail.ru> 2001
+ Copyright (C) Andrew Tridgell 2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,351 +21,336 @@
*/
#include "includes.h"
-#define CTRLZ 26
+
extern int DEBUGLEVEL;
-static char cvtbuf[sizeof(pstring)];
+static pstring cvtbuf;
-static BOOL mapsinited = 0;
+static smb_iconv_t
+ ucs2_to_unix=(smb_iconv_t)-1, /*ucs2 (MS) <-> unix format */
+ unix_to_ucs2=(smb_iconv_t)-1,
+ dos_to_unix=(smb_iconv_t)-1, /*unix format <-> dos codepage*/
+ unix_to_dos=(smb_iconv_t)-1; /*for those clients who does not support unicode*/
-static char unix2dos[256];
-static char dos2unix[256];
+
+/****************************************************************************
+ Initialize iconv conversion descriptors
+****************************************************************************/
+void init_iconv(char *unix_charset, char *dos_charset)
+{
+#define ICONV(descr, from_name, to_name)\
+ if(descr!=(smb_iconv_t)-1) smb_iconv_close(descr);\
+ descr = smb_iconv_open(to_name, from_name);\
+ if(descr==(smb_iconv_t)-1)\
+ DEBUG(0,("Conversion from %s to %s is not supported\n",from_name,to_name));
+
+ if (!unix_charset || !*unix_charset) unix_charset = "ASCII";
+ if (!dos_charset || !*dos_charset) dos_charset = "ASCII";
+
+ ICONV(ucs2_to_unix, "UCS2", unix_charset)
+ ICONV(unix_to_ucs2, unix_charset, "UCS2")
+ ICONV(dos_to_unix, dos_charset, unix_charset)
+ ICONV(unix_to_dos, unix_charset, dos_charset)
+
+#undef ICONV
+}
-static void initmaps(void) {
- int k;
+/****************************************************************************
+ Convert string from one encoding to another, makeing error checking etc
+ Parameters:
+ descriptor - conversion descriptor, created in init_iconv
+ src - pointer to source string (multibute or singlebyte)
+ srclen - length of the source string in bytes
+ dest - pointer to destination string (multibyte or singlebyte)
+ destlen - maximal length allowed for string
+return the number of bytes occupied in the destination
+****************************************************************************/
+static size_t convert_string(smb_iconv_t descriptor,
+ void const *src, size_t srclen,
+ void *dest, size_t destlen)
+{
+ size_t i_len, o_len;
+ size_t retval;
+ char* inbuf = (char*)src;
+ char* outbuf = (char*)dest;
+
+ if (descriptor == (smb_iconv_t)-1) {
+ /* conversion not supported, use as is */
+ int len = MIN(srclen,destlen);
+ memcpy(dest,src,len);
+ return len;
+ }
+
+ i_len=srclen;
+ o_len=destlen;
+ retval=smb_iconv(descriptor,&inbuf, &i_len, &outbuf, &o_len);
+ if(retval==-1)
+ { char *reason;
+ switch(errno)
+ { case EINVAL: reason="Incomplete multybyte sequence"; break;
+ case E2BIG: reason="No more room";
+ DEBUG(0, ("Required %d, available %d\n",
+ srclen, destlen));
+ break;
+ case EILSEQ: reason="Illegal myltybyte sequence"; break;
+ }
+ DEBUG(0,("Conversion error:%s(%s)\n",reason,inbuf));
+ /* smb_panic(reason); */
+ }
+ return destlen-o_len;
+}
- for (k = 0; k < 256; k++) unix2dos[k] = k;
- for (k = 0; k < 256; k++) dos2unix[k] = k;
+int unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
+{
+ int size,len;
+ smb_ucs2_t *buffer=(smb_ucs2_t*)cvtbuf;
+ size=convert_string(unix_to_ucs2, src, srclen, buffer, sizeof(cvtbuf));
+ len=size/2;
+ strupper_w(buffer);
+ return convert_string(ucs2_to_unix, buffer, size, dest, destlen);
+}
- mapsinited = True;
+int unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
+{
+ int size,len;
+ smb_ucs2_t *buffer=(smb_ucs2_t*)cvtbuf;
+ size=convert_string(unix_to_ucs2, src, srclen, buffer, sizeof(cvtbuf));
+ len=size/2;
+ strlower_w(buffer);
+ return convert_string(ucs2_to_unix, buffer, size, dest, destlen);
}
-static void update_map(char *str) {
- char *p;
- for (p = str; *p; p++) {
- if (p[1]) {
- unix2dos[(unsigned char)*p] = p[1];
- dos2unix[(unsigned char)p[1]] = *p;
- p++;
- }
- }
+int ucs2_align(const void *base_ptr, const void *p, int flags)
+{
+ if (flags & (STR_NOALIGN|STR_ASCII)) return 0;
+ return PTR_DIFF(p, base_ptr) & 1;
}
-static void setupmaps(void)
+
+/****************************************************************************
+copy a string from a char* unix src to a dos codepage string destination
+return the number of bytes occupied by the string in the destination
+flags can have:
+ STR_TERMINATE means include the null termination
+ STR_UPPER means uppercase in the destination
+dest_len is the maximum length allowed in the destination. If dest_len
+is -1 then no maxiumum is used
+****************************************************************************/
+int push_ascii(void *dest, const char *src, int dest_len, int flags)
{
- int i;
- if (!mapsinited) initmaps();
-
- /* Do not map undefined characters to some accidental code */
- for (i = 128; i < 256; i++)
- {
- unix2dos[i] = CTRLZ;
- dos2unix[i] = CTRLZ;
- }
-}
+ int src_len = strlen(src);
+ pstring tmpbuf;
-static void init_iso8859_1(int codepage) {
-
- setupmaps();
-
- if (codepage == 437) {
- /* MSDOS Code Page 437 -> ISO-8859-1 */
- update_map("\xA1\xAD\xA2\x98\xA3\x9C\xA4\xED\xA5\x9D\xA6\xB3\xA7\xEE");
- update_map("\xAA\xA6\xAB\xAE\xAC\xAA\xAE\xE9\xAF\xC4");
- update_map("\xB0\xF8\xB1\xF1\xB2\xFD\xB5\xE6\xB7\xFA\xBA\xA7\xBC\xAC\xBD\xAB\xBF\xA8");
- update_map("\xC0\x85\xC1\xA0\xC2\x83\xC4\x8E\xC5\x8F\xC6\x92\xC7\x80\xC8\x8A");
- update_map("\xC9\x90\xCA\x88\xCB\x89\xCC\x8D\xCD\xA1\xCE\x8C\xCF\x8B");
- update_map("\xD1\xA5\xD2\x96\xD3\xA2\xD4\x93\xD6\x99\xD9\x97\xDA\xA3\xDB\x96\xDC\x9A\xDF\xE1");
- update_map("\xE0\x85\xE1\xA0\xE2\x83\xE4\x84\xE5\x86\xE6\x91\xE7\x87\xE8\x8A\xE9\x82\xEA\x88\xEB\x89\xEC\x8D\xED\xA1\xEE\x8C\xEF\x8B");
- update_map("\xF0\xEB\xF1\xA4\xF2\x95\xF3\xA2\xF4\x93\xF6\x94\xF7\xF6\xF8\xED\xF9\x97\xFA\xA3\xFB\x96\xFC\x81\xFF\x98");
- } else {
- /* MSDOS Code Page 850 -> ISO-8859-1 */
- update_map("\240\377\241\255\242\275\243\234\244\317\245\276\246\335\247\365");
- update_map("\250\371\251\270\252\246\253\256\254\252\255\360\256\251\257\356");
- update_map("\260\370\261\361\262\375\263\374\264\357\265\346\266\364\267\372");
- update_map("\270\367\271\373\272\247\273\257\274\254\275\253\276\363\277\250");
- update_map("\300\267\301\265\302\266\303\307\304\216\305\217\306\222\307\200");
- update_map("\310\324\311\220\312\322\313\323\314\336\315\326\316\327\317\330");
- update_map("\320\321\321\245\322\343\323\340\324\342\325\345\326\231\327\236");
- update_map("\330\235\331\353\332\351\333\352\334\232\335\355\336\350\337\341");
- update_map("\340\205\341\240\342\203\343\306\344\204\345\206\346\221\347\207");
- update_map("\350\212\351\202\352\210\353\211\354\215\355\241\356\214\357\213");
- update_map("\360\320\361\244\362\225\363\242\364\223\365\344\366\224\367\366");
- update_map("\370\233\371\227\372\243\373\226\374\201\375\354\376\347\377\230");
- }
-}
+ /* treat a pstring as "unlimited" length */
+ if (dest_len == -1) {
+ dest_len = sizeof(pstring);
+ }
-static void init_iso8859_15(int codepage) {
-
- setupmaps();
-
-
- if (codepage == 775) {
- /* MSDOS Code Page 775 -> ISO-8859-15 this is for estonian */
-update_map("\240\377\242\226\243\234\246\276\247\365");
-update_map("\250\325\251\250\253\256\254\252\255\360\256\251");
-update_map("\260\370\261\361\262\375\263\374\264\317\265\346\266\364\267\372");
-update_map("\270\330\271\373\273\257");
-update_map("\304\216\305\217\306\222");
-update_map("\311\220");
-update_map("\323\340\325\345\326\231\327\236");
-update_map("\330\235\334\232\337\341");
-update_map("\344\204\345\206\346\221");
-update_map("\351\202");
-update_map("\363\242\365\344\366\224\367\366");
-update_map("\370\233\374\201");
- } else {
- /* MSDOS Code Page 850 -> ISO-8859-15 */
-update_map("\240\377\241\255\242\275\243\234\244\317\245\276\246\321\247\365");
-update_map("\250\320\251\270\252\246\253\256\254\252\255\360\256\251\257\356");
-update_map("\260\370\261\361\262\375\263\374\264\350\265\346\266\364\267\372");
-update_map("\270\347\271\373\272\247\273\257\274\254\275\253\276\363\277\250");
-update_map("\300\267\301\265\302\266\303\307\304\216\305\217\306\222\307\200");
-update_map("\310\324\311\220\312\322\313\323\314\336\315\326\316\327\317\330");
-update_map("\320\321\321\245\322\343\323\340\324\342\325\345\326\231\327\236");
-update_map("\330\235\331\353\332\351\333\352\334\232\335\355\336\350\337\341");
-update_map("\340\205\341\240\342\203\343\306\344\204\345\206\346\221\347\207");
-update_map("\350\212\351\202\352\210\353\211\354\215\355\241\356\214\357\213");
-update_map("\360\320\361\244\362\225\363\242\364\223\365\344\366\224\367\366");
-update_map("\370\233\371\227\372\243\373\226\374\201\375\354\376\347\377\230");
-}
-}
+ if (flags & STR_UPPER) {
+ pstrcpy(tmpbuf, src);
+ strupper(tmpbuf);
+ src = tmpbuf;
+ }
-/* Init for eastern european languages. */
-
-static void init_iso8859_2(void) {
-
- setupmaps();
-
-/*
- * Tranlation table created by Petr Hubeny <psh@capitol.cz>
- * Requires client code page = 852
- * and character set = ISO8859-2 in smb.conf
- */
-
-/* MSDOS Code Page 852 -> ISO-8859-2 */
-update_map("\240\377"); /* Fix for non-breaking space */
-update_map("\241\244\242\364\243\235\244\317\245\225\246\227\247\365");
-update_map("\250\371\251\346\252\270\253\233\254\215\256\246\257\275");
-update_map("\261\245\262\362\263\210\264\357\265\226\266\230\267\363");
-update_map("\270\367\271\347\272\255\273\234\274\253\275\361\276\247\277\276");
-update_map("\300\350\301\265\302\266\303\306\304\216\305\221\306\217\307\200");
-update_map("\310\254\311\220\312\250\313\323\314\267\315\326\316\327\317\322");
-update_map("\320\321\321\343\322\325\323\340\324\342\325\212\326\231\327\236");
-update_map("\330\374\331\336\332\351\333\353\334\232\335\355\336\335\337\341");
-update_map("\340\352\341\240\342\203\343\307\344\204\345\222\346\206\347\207");
-update_map("\350\237\351\202\352\251\353\211\354\330\355\241\356\214\357\324");
-update_map("\360\320\361\344\362\345\363\242\364\223\365\213\366\224\367\366");
-update_map("\370\375\371\205\372\243\373\373\374\201\375\354\376\356\377\372");
+ if (flags & STR_TERMINATE) {
+ src_len++;
+ }
+
+ return convert_string(unix_to_dos, src, src_len, dest, dest_len);
}
-/* Init for russian language (iso8859-5) */
+int push_ascii_fstring(void *dest, const char *src)
+{
+ return push_ascii(dest, src, sizeof(fstring), STR_TERMINATE);
+}
-/* Added by Max Khon <max@iclub.nsu.ru> */
+int push_ascii_pstring(void *dest, const char *src)
+{
+ return push_ascii(dest, src, sizeof(pstring), STR_TERMINATE);
+}
-static void init_iso8859_5(void)
+int push_pstring(void *dest, const char *src)
{
- setupmaps();
-
-/* MSDOS Code Page 866 -> ISO8859-5 */
-update_map("\260\200\261\201\262\202\263\203\264\204\265\205\266\206\267\207");
-update_map("\270\210\271\211\272\212\273\213\274\214\275\215\276\216\277\217");
-update_map("\300\220\301\221\302\222\303\223\304\224\305\225\306\226\307\227");
-update_map("\310\230\311\231\312\232\313\233\314\234\315\235\316\236\317\237");
-update_map("\320\240\321\241\322\242\323\243\324\244\325\245\326\246\327\247");
-update_map("\330\250\331\251\332\252\333\253\334\254\335\255\336\256\337\257");
-update_map("\340\340\341\341\342\342\343\343\344\344\345\345\346\346\347\347");
-update_map("\350\350\351\351\352\352\353\353\354\354\355\355\356\356\357\357");
-update_map("\241\360\361\361\244\362\364\363\247\364\367\365\256\366\376\367");
-update_map("\360\374\240\377");
+ return push_ascii(dest, src, sizeof(pstring), STR_TERMINATE);
}
-/* Added by Antonios Kavarnos (Antonios.Kavarnos@softlab.ece.ntua.gr */
-static void init_iso8859_7(void)
+/****************************************************************************
+copy a string from a dos codepage source to a unix char* destination
+flags can have:
+ STR_TERMINATE means the string in src is null terminated
+if STR_TERMINATE is set then src_len is ignored
+src_len is the length of the source area in bytes
+return the number of bytes occupied by the string in src
+the resulting string in "dest" is always null terminated
+****************************************************************************/
+int pull_ascii(char *dest, const void *src, int dest_len, int src_len, int flags)
{
- setupmaps();
-
-/* MSDOS Code Page 737 -> ISO-8859-7 (Greek-Hellenic) */
-
-update_map("\301\200\302\201\303\202\304\203\305\204\306\205\307\206");
-update_map("\310\207\311\210\312\211\313\212\314\213\315\214\316\215\317\216");
-update_map("\320\217\321\220\323\221\324\222\325\223\326\224\327\225");
-update_map("\330\226\331\227");
-update_map("\341\230\342\231\343\232\344\233\345\234\346\235\347\236");
-update_map("\350\237\351\240\352\241\353\242\354\243\355\244\356\245\357\246");
-update_map("\360\247\361\250\362\252\363\251\364\253\365\254\366\255\367\256");
-update_map("\370\257\371\340");
-update_map("\332\364\333\365\334\341\335\342\336\343\337\345");
-update_map("\372\344\373\350\374\346\375\347\376\351");
-update_map("\266\352");
-update_map("\270\353\271\354\272\355\274\356\276\357\277\360");
+ int ret;
+
+ if (dest_len == -1) {
+ dest_len = sizeof(pstring);
+ }
+
+ if (flags & STR_TERMINATE) src_len = strlen(src)+1;
+
+ ret = convert_string(dos_to_unix, src, src_len, dest, dest_len);
+
+ if (dest_len) dest[MIN(ret, dest_len-1)] = 0;
+
+ return src_len;
}
-/* Added by Deniz Akkus (akkus@alum.mit.edu) */
+int pull_ascii_pstring(char *dest, const void *src)
+{
+ return pull_ascii(dest, src, sizeof(pstring), -1, STR_TERMINATE);
+}
-static void init_iso8859_9(void)
+int pull_ascii_fstring(char *dest, const void *src)
{
- setupmaps();
-
- /* MSDOS Code Page 857 -> ISO-8859-9 (Turkish) */
-
- update_map("\xa0\xff\xa1\xad\xa2\xbd\xa3\x9c\xa4\xcf\xA5\xbe\xa6\xdd\xa7\xf5");
- update_map("\xa8\xf9\xa9\xb8\xaa\xd1\xab\xae\xac\xaa\xad\xf0\xae\xa9\xaf\xee");
- update_map("\xb0\xf8\xb1\xf1\xb2\xfd\xb3\xfc\xb4\xef\xb5\xe6\xb6\xf4\xb7\xfa");
- update_map("\xb8\xf7\xb9\xfb\xba\xd0\xbb\xaf\xbc\xac\xbd\xab\xbe\xf3\xbf\xa8");
- update_map("\xc0\xb7\xc1\xb5\xc2\xb6\xc3\xc7\xc4\x8e\xc5\x8f\xc6\x92\xc7\x80");
- update_map("\xc8\xd4\xc9\x90\xca\xd2\xcb\xd3\xcc\xde\xcd\xd6\xce\xd7\xcf\xd8");
- update_map("\xd0\xa6\xd1\xa5\xd2\xe3\xd3\xe0\xd4\xe2\xd5\xe5\xd6\x99\xd7\xe8");
- update_map("\xd8\x9d\xd9\xeb\xda\xe9\xdb\xea\xdc\x9a\xdd\x98\xde\x9e\xdf\xe1");
- update_map("\xe0\x85\xe1\xa0\xe2\x83\xe3\xc6\xe4\x84\xe5\x86\xe6\x91\xe7\x87");
- update_map("\xe8\x8a\xe9\x82\xea\x88\xeb\x89\xec\xec\xed\xa1\xee\x8c\xef\x8b");
- update_map("\xf0\xa7\xf1\xa4\xf2\x95\xf3\xa2\xf4\x93\xf5\xe4\xf6\x94\xf7\xf6");
- update_map("\xf8\x9b\xf9\x97\xfa\xa3\xfb\x96\xfc\x81\xfd\x8d\xfe\x9f\xff\xed");
+ return pull_ascii(dest, src, sizeof(fstring), -1, STR_TERMINATE);
}
-/* init for Baltic Rim */
-
-static void init_iso8859_13(void) {
-
- setupmaps();
-
- /* MSDOS Code Page 775 -> ISO-8859-13 */
-update_map("\240\377\241\246\242\226\243\234\244\237\245\367\246\247\247\365");
-update_map("\250\235\251\250\252\212\253\256\254\252\255\360\256\251\257\222");
-update_map("\260\370\261\361\262\375\263\374\264\362\265\346\266\364\267\372");
-update_map("\270\233\271\373\272\213\273\257\274\254\275\253\276\363\277\221");
-update_map("\300\265\301\275\302\240\303\200\304\216\305\217\306\267\307\355");
-update_map("\310\266\311\220\312\215\313\270\314\225\315\350\316\241\317\352");
-update_map("\320\276\321\343\322\356\323\340\324\342\325\345\326\231\327\236");
-update_map("\330\306\331\255\332\227\333\307\334\232\335\243\336\317\337\341");
-update_map("\340\320\341\324\342\203\343\207\344\204\345\206\346\322\347\211");
-update_map("\350\321\351\202\352\245\353\323\354\205\355\351\356\214\357\353");
-update_map("\360\325\361\347\362\354\363\242\364\223\365\344\366\224\367\366");
-update_map("\370\326\371\210\372\230\373\327\374\201\375\244\376\330\377\357");
+/****************************************************************************
+copy a string from a char* src to a unicode destination
+return the number of bytes occupied by the string in the destination
+flags can have:
+ STR_TERMINATE means include the null termination
+ STR_UPPER means uppercase in the destination
+ STR_NOALIGN means don't do alignment
+dest_len is the maximum length allowed in the destination. If dest_len
+is -1 then no maxiumum is used
+****************************************************************************/
+int push_ucs2(const void *base_ptr, void *dest, const char *src, int dest_len, int flags)
+{
+ int len=0;
+ int src_len = strlen(src);
+ pstring tmpbuf;
+
+ /* treat a pstring as "unlimited" length */
+ if (dest_len == -1) {
+ dest_len = sizeof(pstring);
+ }
+
+ if (flags & STR_UPPER) {
+ pstrcpy(tmpbuf, src);
+ strupper(tmpbuf);
+ src = tmpbuf;
+ }
+
+ if (flags & STR_TERMINATE) {
+ src_len++;
+ }
+
+ if (ucs2_align(base_ptr, dest, flags)) {
+ *(char *)dest = 0;
+ dest = (void *)((char *)dest + 1);
+ if (dest_len) dest_len--;
+ len++;
+ }
+
+ len += convert_string(unix_to_ucs2, src, src_len, dest, dest_len);
+ return len;
}
-/* Init for russian language (koi8) */
-static void init_koi8_r(void)
+/****************************************************************************
+copy a string from a ucs2 source to a unix char* destination
+flags can have:
+ STR_TERMINATE means the string in src is null terminated
+ STR_NOALIGN means don't try to align
+if STR_TERMINATE is set then src_len is ignored
+src_len is the length of the source area in bytes
+return the number of bytes occupied by the string in src
+the resulting string in "dest" is always null terminated
+****************************************************************************/
+int pull_ucs2(const void *base_ptr, char *dest, const void *src, int dest_len, int src_len, int flags)
{
- setupmaps();
-
-/* MSDOS Code Page 866 -> KOI8-R */
-update_map("\200\304\201\263\202\332\203\277\204\300\205\331\206\303\207\264");
-update_map("\210\302\211\301\212\305\213\337\214\334\215\333\216\335\217\336");
-update_map("\220\260\221\261\222\262\223\364\224\376\225\371\226\373\227\367");
-update_map("\230\363\231\362\232\377\233\365\234\370\235\375\236\372\237\366");
-update_map("\240\315\241\272\242\325\243\361\244\326\245\311\246\270\247\267");
-update_map("\250\273\251\324\252\323\253\310\254\276\255\275\256\274\257\306");
-update_map("\260\307\261\314\262\265\263\360\264\266\265\271\266\321\267\322");
-update_map("\270\313\271\317\272\320\273\312\274\330\275\327\276\316\277\374");
-update_map("\300\356\301\240\302\241\303\346\304\244\305\245\306\344\307\243");
-update_map("\310\345\311\250\312\251\313\252\314\253\315\254\316\255\317\256");
-update_map("\320\257\321\357\322\340\323\341\324\342\325\343\326\246\327\242");
-update_map("\330\354\331\353\332\247\333\350\334\355\335\351\336\347\337\352");
-update_map("\340\236\341\200\342\201\343\226\344\204\345\205\346\224\347\203");
-update_map("\350\225\351\210\352\211\353\212\354\213\355\214\356\215\357\216");
-update_map("\360\217\361\237\362\220\363\221\364\222\365\223\366\206\367\202");
-update_map("\370\234\371\233\372\207\373\230\374\235\375\231\376\227\377\232");
-}
+ int ret;
+
+ if (dest_len == -1) {
+ dest_len = sizeof(pstring);
+ }
+ if (ucs2_align(base_ptr, src, flags)) {
+ src = (const void *)((const char *)src + 1);
+ if (src_len > 0) src_len--;
+ }
-/* Init for ROMAN-8 (HP-UX) */
+ if (flags & STR_TERMINATE) src_len = strlen_w(src)*2+2;
-static void init_roman8(void) {
+ ret = convert_string(ucs2_to_unix, src, src_len, dest, dest_len);
+ if (dest_len) dest[MIN(ret, dest_len-1)] = 0;
- setupmaps();
+ return src_len;
+}
-/* MSDOS Code Page 850 -> ROMAN8 */
-update_map("\240\377\241\267\242\266\243\324\244\322\245\323\246\327\247\330");
-update_map("\250\357\253\371\255\353\256\352\257\234");
-update_map("\260\356\261\355\262\354\263\370\264\200\265\207\266\245\267\244");
-update_map("\270\255\271\250\272\317\273\234\274\276\275\365\276\237\277\275");
-update_map("\300\203\301\210\302\223\303\226\304\240\305\202\306\242\307\243");
-update_map("\310\205\311\212\312\225\313\227\314\204\315\211\316\224\317\201");
-update_map("\320\217\321\214\322\235\323\222\324\206\325\241\326\233\327\221");
-update_map("\330\216\331\215\332\231\333\232\334\220\335\213\336\341\337\342");
-update_map("\340\265\341\307\342\306\343\321\344\320\345\326\346\336\347\340");
-update_map("\350\343\351\345\352\344\355\351\357\230");
-update_map("\360\350\361\347\362\372\363\346\364\364\365\363\366\360\367\254");
-update_map("\370\253\371\246\372\247\373\256\374\376\375\257\376\361");
+int pull_ucs2_pstring(char *dest, const void *src)
+{
+ return pull_ucs2(NULL, dest, src, sizeof(pstring), -1, STR_TERMINATE);
}
-/*
- * Convert unix to dos
- */
-char *unix2dos_format(char *str,BOOL overwrite)
+int pull_ucs2_fstring(char *dest, const void *src)
{
- char *p;
- char *dp;
-
- if (!mapsinited)
- initmaps();
-
- if (overwrite) {
- for (p = str; *p; p++)
- *p = unix2dos[(unsigned char)*p];
- return str;
- } else {
- for (p = str, dp = cvtbuf;*p && (dp - cvtbuf < sizeof(cvtbuf) - 1); p++,dp++)
- *dp = unix2dos[(unsigned char)*p];
- *dp = 0;
- return cvtbuf;
- }
+ return pull_ucs2(NULL, dest, src, sizeof(fstring), -1, STR_TERMINATE);
}
-/*
- * Convert dos to unix
- */
-char *dos2unix_format(char *str, BOOL overwrite)
+
+/****************************************************************************
+copy a string from a char* src to a unicode or ascii
+dos code page destination choosing unicode or ascii based on the
+flags in the SMB buffer starting at base_ptr
+return the number of bytes occupied by the string in the destination
+flags can have:
+ STR_TERMINATE means include the null termination
+ STR_UPPER means uppercase in the destination
+ STR_ASCII use ascii even with unicode packet
+ STR_NOALIGN means don't do alignment
+dest_len is the maximum length allowed in the destination. If dest_len
+is -1 then no maxiumum is used
+****************************************************************************/
+int push_string(const void *base_ptr, void *dest, const char *src, int dest_len, int flags)
{
- char *p;
- char *dp;
-
- if (!mapsinited)
- initmaps();
-
- if (overwrite) {
- for (p = str; *p; p++)
- *p = dos2unix[(unsigned char)*p];
- return str;
- } else {
- for (p = str, dp = cvtbuf;*p && (dp - cvtbuf < sizeof(cvtbuf) - 1); p++,dp++)
- *dp = dos2unix[(unsigned char)*p];
- *dp = 0;
- return cvtbuf;
- }
+ if (!(flags & STR_ASCII) && \
+ ((flags & STR_UNICODE || \
+ (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
+ return push_ucs2(base_ptr, dest, src, dest_len, flags);
+ }
+ return push_ascii(dest, src, dest_len, flags);
}
-/*
- * Interpret character set.
- */
-void interpret_character_set(char *str, int codepage)
+/****************************************************************************
+copy a string from a unicode or ascii source (depending on
+the packet flags) to a char* destination
+flags can have:
+ STR_TERMINATE means the string in src is null terminated
+ STR_UNICODE means to force as unicode
+ STR_ASCII use ascii even with unicode packet
+ STR_NOALIGN means don't do alignment
+if STR_TERMINATE is set then src_len is ignored
+src_len is the length of the source area in bytes
+return the number of bytes occupied by the string in src
+the resulting string in "dest" is always null terminated
+****************************************************************************/
+int pull_string(const void *base_ptr, char *dest, const void *src, int dest_len, int src_len,
+ int flags)
+{
+ if (!(flags & STR_ASCII) && \
+ ((flags & STR_UNICODE || \
+ (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
+ return pull_ucs2(base_ptr, dest, src, dest_len, src_len, flags);
+ }
+ return pull_ascii(dest, src, dest_len, src_len, flags);
+}
+
+int align_string(const void *base_ptr, const char *p, int flags)
{
- if (strequal (str, "iso8859-1")) {
- init_iso8859_1(codepage);
- } else if (strequal (str, "iso8859-2")) {
- init_iso8859_2();
- } else if (strequal (str, "iso8859-5")) {
- init_iso8859_5();
- } else if (strequal (str, "iso8859-7")) {
- init_iso8859_7();
- } else if (strequal (str, "iso8859-9")) {
- init_iso8859_9();
- } else if (strequal (str, "iso8859-13")) {
- init_iso8859_13();
- } else if (strequal (str, "iso8859-15")) {
- init_iso8859_15(codepage);
- } else if (strequal (str, "koi8-r")) {
- init_koi8_r();
- } else if (strequal (str, "roman8")) {
- init_roman8();
- } else {
- DEBUG(0,("unrecognized character set %s\n", str));
- }
-
- load_unix_unicode_map(str);
+ if (!(flags & STR_ASCII) && \
+ ((flags & STR_UNICODE || \
+ (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) {
+ return ucs2_align(base_ptr, p, flags);
+ }
+ return 0;
}
diff --git a/source3/lib/charset.c b/source3/lib/charset.c
index d699df3e2b..cca5fdd326 100644
--- a/source3/lib/charset.c
+++ b/source3/lib/charset.c
@@ -111,290 +111,3 @@ char *dos_char_map = xx_dos_char_map;
char *upper_char_map = xx_upper_char_map;
char *lower_char_map = xx_lower_char_map;
-/*
- * This code has been extended to deal with ascynchronous mappings
- * like MS-DOS Latin US (Code page 437) where things like :
- * a acute are capitalized to 'A', but the reverse mapping
- * must not hold true. This allows the filename case insensitive
- * matching in do_match() to work, as the DOS/Win95/NT client
- * uses 'A' as a mask to match against characters like a acute.
- * This is the meaning behind the parameters that allow a
- * mapping from lower to upper, but not upper to lower.
- */
-
-static void add_dos_char(int lower, BOOL map_lower_to_upper,
- int upper, BOOL map_upper_to_lower)
-{
- lower &= 0xff;
- upper &= 0xff;
- DEBUGADD( 6, ( "Adding chars 0x%x 0x%x (l->u = %s) (u->l = %s)\n",
- lower, upper,
- map_lower_to_upper ? "True" : "False",
- map_upper_to_lower ? "True" : "False" ) );
- if (lower) dos_char_map[lower] = 1;
- if (upper) dos_char_map[upper] = 1;
- lower_char_map[lower] = (char)lower; /* Define tolower(lower) */
- upper_char_map[upper] = (char)upper; /* Define toupper(upper) */
- if (lower && upper) {
- if(map_upper_to_lower)
- lower_char_map[upper] = (char)lower;
- if(map_lower_to_upper)
- upper_char_map[lower] = (char)upper;
- }
-}
-
-/****************************************************************************
-initialise the charset arrays
-****************************************************************************/
-void charset_initialise(void)
-{
- int i;
-
-#ifdef LC_ALL
- /* include <locale.h> in includes.h if available for OS */
- /* we take only standard 7-bit ASCII definitions from ctype */
- setlocale(LC_ALL,"C");
-#endif
-
- for (i= 0;i<=255;i++) {
- dos_char_map[i] = 0;
- }
-
- for (i=0;i<=127;i++) {
- if (isalnum(i) || strchr("._^$~!#%&-{}()@'`",(char)i))
- add_dos_char(i,False,0,False);
- }
-
- for (i=0; i<=255; i++) {
- char c = (char)i;
- upper_char_map[i] = lower_char_map[i] = c;
-
- /* Some systems have buggy isupper/islower for characters
- above 127. Best not to rely on them. */
- if(i < 128) {
- if (isupper((int)c)) lower_char_map[i] = tolower(c);
- if (islower((int)c)) upper_char_map[i] = toupper(c);
- }
- }
-}
-
-/****************************************************************************
-load the client codepage.
-****************************************************************************/
-
-typedef unsigned char (*codepage_p)[4];
-
-static codepage_p load_client_codepage( int client_codepage )
-{
- pstring codepage_file_name;
- unsigned char buf[8];
- int fd = -1;
- SMB_OFF_T size;
- codepage_p cp_p = NULL;
- SMB_STRUCT_STAT st;
-
- DEBUG(5, ("load_client_codepage: loading codepage %d.\n", client_codepage));
-
- if(strlen(lp_codepagedir()) + 14 > sizeof(codepage_file_name))
- {
- DEBUG(0,("load_client_codepage: filename too long to load\n"));
- return NULL;
- }
-
- pstrcpy(codepage_file_name, lp_codepagedir());
- pstrcat(codepage_file_name, "/");
- pstrcat(codepage_file_name, "codepage.");
- slprintf(&codepage_file_name[strlen(codepage_file_name)],
- sizeof(pstring)-(strlen(codepage_file_name)+1)-1,
- "%03d",
- client_codepage);
-
- if(sys_stat(codepage_file_name,&st)!=0)
- {
- DEBUG(0,("load_client_codepage: filename %s does not exist.\n",
- codepage_file_name));
- return NULL;
- }
-
- /* Check if it is at least big enough to hold the required
- data. Should be 2 byte version, 2 byte codepage, 4 byte length,
- plus zero or more bytes of data. Note that the data cannot be more
- than 4 * MAXCODEPAGELINES bytes.
- */
- size = st.st_size;
-
- if( size < CODEPAGE_HEADER_SIZE || size > (CODEPAGE_HEADER_SIZE + 4 * MAXCODEPAGELINES))
- {
- DEBUG(0,("load_client_codepage: file %s is an incorrect size for a \
-code page file (size=%d).\n", codepage_file_name, (int)size));
- return NULL;
- }
-
- /* Read the first 8 bytes of the codepage file - check
- the version number and code page number. All the data
- is held in little endian format.
- */
-
- if((fd = open(codepage_file_name, O_RDONLY)) == -1)
- {
- DEBUG(0,("load_client_codepage: cannot open file %s. Error was %s\n",
- codepage_file_name, strerror(errno)));
- return NULL;
- }
-
- if (read(fd, buf, CODEPAGE_HEADER_SIZE)!=CODEPAGE_HEADER_SIZE)
- {
- DEBUG(0,("load_client_codepage: cannot read header from file %s. Error was %s\n",
- codepage_file_name, strerror(errno)));
- goto clean_and_exit;
- }
-
- /* Check the version value */
- if(SVAL(buf,CODEPAGE_VERSION_OFFSET) != CODEPAGE_FILE_VERSION_ID)
- {
- DEBUG(0,("load_client_codepage: filename %s has incorrect version id. \
-Needed %hu, got %hu.\n",
- codepage_file_name, (uint16)CODEPAGE_FILE_VERSION_ID,
- SVAL(buf,CODEPAGE_VERSION_OFFSET)));
- goto clean_and_exit;
- }
-
- /* Check the codepage matches */
- if(SVAL(buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET) != (uint16)client_codepage)
- {
- DEBUG(0,("load_client_codepage: filename %s has incorrect codepage. \
-Needed %hu, got %hu.\n",
- codepage_file_name, (uint16)client_codepage,
- SVAL(buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET)));
- goto clean_and_exit;
- }
-
- /* Check the length is correct. */
- if(IVAL(buf,CODEPAGE_LENGTH_OFFSET) != (size - CODEPAGE_HEADER_SIZE))
- {
- DEBUG(0,("load_client_codepage: filename %s has incorrect size headers. \
-Needed %u, got %u.\n", codepage_file_name, (uint32)(size - CODEPAGE_HEADER_SIZE),
- IVAL(buf,CODEPAGE_LENGTH_OFFSET)));
- goto clean_and_exit;
- }
-
- size -= CODEPAGE_HEADER_SIZE; /* Remove header */
-
- /* Make sure the size is a multiple of 4. */
- if((size % 4 ) != 0)
- {
- DEBUG(0,("load_client_codepage: filename %s has a codepage size not a \
-multiple of 4.\n", codepage_file_name));
- goto clean_and_exit;
- }
-
- /* Allocate space for the code page file and read it all in. */
- if((cp_p = (codepage_p)malloc( size + 4 )) == NULL)
- {
- DEBUG(0,("load_client_codepage: malloc fail.\n"));
- goto clean_and_exit;
- }
-
- if(read(fd, (char *)cp_p, size)!=size)
- {
- DEBUG(0,("load_client_codepage: read fail on file %s. Error was %s.\n",
- codepage_file_name, strerror(errno)));
- goto clean_and_exit;
- }
-
- /* Ensure array is correctly terminated. */
- memset(((char *)cp_p) + size, '\0', 4);
-
- close(fd);
- return cp_p;
-
-clean_and_exit:
-
- /* pseudo destructor :-) */
-
- if(fd != -1)
- close(fd);
- if(cp_p)
- free((char *)cp_p);
- return NULL;
-}
-
-/****************************************************************************
- Initialise the client codepage.
-****************************************************************************/
-
-void codepage_initialise(int client_codepage)
-{
- int i;
- static codepage_p cp = NULL;
-
- if(cp != NULL)
- {
- DEBUG(6,
- ("codepage_initialise: called twice - ignoring second client code page = %d\n",
- client_codepage));
- return;
- }
-
- DEBUG(6,("codepage_initialise: client code page = %d\n", client_codepage));
-
- /*
- * Known client codepages - these can be added to.
- */
- cp = load_client_codepage( client_codepage );
-
- if(cp == NULL)
- {
-#ifdef KANJI
- DEBUG(6,("codepage_initialise: loading dynamic codepage file %s/codepage.%d \
-for code page %d failed. Using default client codepage 932\n",
- lp_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",
- lp_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++)
- add_dos_char(cp[i][0], (BOOL)cp[i][2], cp[i][1], (BOOL)cp[i][3]);
- }
-
- /* Try and load the unicode map. */
- load_dos_unicode_map(client_codepage);
-}
-
-/*******************************************************************
-add characters depending on a string passed by the user
-********************************************************************/
-void add_char_string(char *s)
-{
- char *extra_chars = (char *)strdup(s);
- char *t;
- if (!extra_chars) return;
-
- for (t=strtok(extra_chars," \t\r\n"); t; t=strtok(NULL," \t\r\n")) {
- char c1=0,c2=0;
- int i1=0,i2=0;
- if (isdigit((unsigned char)*t) || (*t)=='-') {
- sscanf(t,"%i:%i",&i1,&i2);
- add_dos_char(i1,True,i2,True);
- } else {
- sscanf(t,"%c:%c",&c1,&c2);
- add_dos_char((unsigned char)c1,True,(unsigned char)c2, True);
- }
- }
-
- free(extra_chars);
-}
diff --git a/source3/lib/cmd_interp.c b/source3/lib/cmd_interp.c
index 20812d3f9a..ef6f94bd49 100644
--- a/source3/lib/cmd_interp.c
+++ b/source3/lib/cmd_interp.c
@@ -1293,8 +1293,6 @@ int command_main(int argc, char *argv[])
DEBUGLEVEL = 2;
- charset_initialise();
-
/* add in the internal command set and the various
client RPC groups--spoolss, lsa, etc... */
add_command_set(general_commands);
@@ -1357,8 +1355,6 @@ int command_main(int argc, char *argv[])
cmd_set_options &= ~CMD_USER;
cmd_set_options &= ~CMD_PASS;
- codepage_initialise(lp_client_code_page());
-
/* parse the command line args
init the first connection if possible
process a command if passed in on the command line */
diff --git a/source3/lib/doscalls.c b/source3/lib/doscalls.c
deleted file mode 100644
index 8d0071dde6..0000000000
--- a/source3/lib/doscalls.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Samba system utilities
- Copyright (C) Jeremy Allison 1992-1998
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-/*
- * Wrappers for calls that need to translate to
- * DOS/Windows semantics. Note that the pathnames
- * in all these functions referred to as 'DOS' names
- * are actually in UNIX path format (ie. '/' instead of
- * '\' directory separators etc.), but the codepage they
- * are in is still the client codepage, hence the 'DOS'
- * name.
- */
-
-extern int DEBUGLEVEL;
-
-#if 0 /* Use vfs_unlink. */
-/*******************************************************************
- Unlink wrapper that calls dos_to_unix.
-********************************************************************/
-
-int dos_unlink(char *fname)
-{
- return(unlink(dos_to_unix(fname,False)));
-}
-#endif
-
-/*******************************************************************
- Open() wrapper that calls dos_to_unix.
-********************************************************************/
-
-int dos_open(char *fname,int flags,mode_t mode)
-{
- return(sys_open(dos_to_unix(fname,False),flags,mode));
-}
-
-/*******************************************************************
- Opendir() wrapper that calls dos_to_unix. Should use the
- vfs_ops->opendir() function instead.
-********************************************************************/
-
-#if 0
-DIR *dos_opendir(char *dname)
-{
- return(opendir(dos_to_unix(dname,False)));
-}
-#endif
-
-/*******************************************************************
- Readdirname() wrapper that calls unix_to_dos. Should use the
- vfs_readdirname() function instead.
-********************************************************************/
-
-#if 0
-char *dos_readdirname(DIR *p)
-{
- char *dname = readdirname(p);
-
- if (!dname)
- return(NULL);
-
- unix_to_dos(dname, True);
- return(dname);
-}
-#endif
-
-/*******************************************************************
- A chown() wrapper that calls dos_to_unix.
-********************************************************************/
-
-#if 0 /* Use vfs_chown. */
-int dos_chown(char *fname, uid_t uid, gid_t gid)
-{
- return(sys_chown(dos_to_unix(fname,False),uid,gid));
-}
-#endif
-
-/*******************************************************************
- A stat() wrapper that calls dos_to_unix.
-********************************************************************/
-
-int dos_stat(char *fname,SMB_STRUCT_STAT *sbuf)
-{
- return(sys_stat(dos_to_unix(fname,False),sbuf));
-}
-
-/*******************************************************************
- An lstat() that calls dos_to_unix.
-********************************************************************/
-
-int dos_lstat(char *fname,SMB_STRUCT_STAT *sbuf)
-{
- return(sys_lstat(dos_to_unix(fname,False),sbuf));
-}
-
-#if 0 /* VFS */
-/*******************************************************************
- Mkdir() that calls dos_to_unix.
- Cope with UNIXes that don't allow high order mode bits on mkdir.
- Patch from gcarter@lanier.com.
- Don't use this call unless you really want to access a file on
- disk. Use the vfs_ops.mkdir() function instead.
-********************************************************************/
-
-int dos_mkdir(char *dname,mode_t mode)
-{
- int ret = mkdir(dos_to_unix(dname,False),mode);
- if(!ret)
- return(dos_chmod(dname,mode));
- else
- return ret;
-}
-#endif
-
-/*******************************************************************
- Rmdir() - call dos_to_unix.
-********************************************************************/
-
-int dos_rmdir(char *dname)
-{
- return(rmdir(dos_to_unix(dname,False)));
-}
-
-#if 0 /* VFS */
-/*******************************************************************
- chdir() - call dos_to_unix.
-********************************************************************/
-
-int dos_chdir(char *dname)
-{
- return(chdir(dos_to_unix(dname,False)));
-}
-#endif
-
-/*******************************************************************
- Utime() - call dos_to_unix.
-********************************************************************/
-
-int dos_utime(char *fname,struct utimbuf *times)
-{
- /* if the modtime is 0 or -1 then ignore the call and
- return success */
- if (times->modtime == (time_t)0 || times->modtime == (time_t)-1)
- return 0;
-
- /* if the access time is 0 or -1 then set it to the modtime */
- if (times->actime == (time_t)0 || times->actime == (time_t)-1)
- times->actime = times->modtime;
-
- return(utime(dos_to_unix(fname,False),times));
-}
-
-/*********************************************************
- For rename across filesystems Patch from Warren Birnbaum
- <warrenb@hpcvscdp.cv.hp.com>
-**********************************************************/
-
-int copy_reg(char *source, const char *dest)
-{
- SMB_STRUCT_STAT source_stats;
- int ifd;
- int ofd;
- char *buf;
- int len; /* Number of bytes read into `buf'. */
-
- sys_lstat (source, &source_stats);
- if (!S_ISREG (source_stats.st_mode))
- return 1;
-
- if (unlink (dest) && errno != ENOENT)
- return 1;
-
- if((ifd = sys_open (source, O_RDONLY, 0)) < 0)
- return 1;
-
- if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0 )
- {
- close (ifd);
- return 1;
- }
-
- if((buf = malloc( COPYBUF_SIZE )) == NULL)
- {
- close (ifd);
- close (ofd);
- unlink (dest);
- return 1;
- }
-
- while ((len = read(ifd, buf, COPYBUF_SIZE)) > 0)
- {
- if (write_data(ofd, buf, len) < 0)
- {
- close (ifd);
- close (ofd);
- unlink (dest);
- free(buf);
- return 1;
- }
- }
- free(buf);
- if (len < 0)
- {
- close (ifd);
- close (ofd);
- unlink (dest);
- return 1;
- }
-
- if (close (ifd) < 0)
- {
- close (ofd);
- return 1;
- }
- if (close (ofd) < 0)
- return 1;
-
- /* chown turns off set[ug]id bits for non-root,
- so do the chmod last. */
-
- /* Try to copy the old file's modtime and access time. */
- {
- struct utimbuf tv;
-
- tv.actime = source_stats.st_atime;
- tv.modtime = source_stats.st_mtime;
- if (utime (dest, &tv))
- return 1;
- }
-
- /* Try to preserve ownership. For non-root it might fail, but that's ok.
- But root probably wants to know, e.g. if NFS disallows it. */
- if (chown (dest, source_stats.st_uid, source_stats.st_gid)
- && (errno != EPERM))
- return 1;
-
- if (chmod (dest, source_stats.st_mode & 07777))
- return 1;
-
- unlink (source);
- return 0;
-}
-
-/*******************************************************************
- Rename() - call dos_to_unix.
-********************************************************************/
-
-int dos_rename(char *from, char *to)
-{
- int rcode;
- pstring zfrom, zto;
-
- pstrcpy (zfrom, dos_to_unix (from, False));
- pstrcpy (zto, dos_to_unix (to, False));
- rcode = rename (zfrom, zto);
-
- if (errno == EXDEV)
- {
- /* Rename across filesystems needed. */
- rcode = copy_reg (zfrom, zto);
- }
- return rcode;
-}
-
-/*******************************************************************
- Chmod - call dos_to_unix.
-********************************************************************/
-
-int dos_chmod(char *fname,mode_t mode)
-{
- return(chmod(dos_to_unix(fname,False),mode));
-}
-
-#if 0 /* VFS */
-/*******************************************************************
- Getwd - takes a UNIX directory name and returns the name
- in dos format.
-********************************************************************/
-
-char *dos_getwd(char *unix_path)
-{
- char *wd;
- wd = sys_getwd(unix_path);
- if (wd)
- unix_to_dos(wd, True);
- return wd;
-}
-#endif /* VFS */
-
-/*******************************************************************
- Check if a DOS file exists. Use vfs_file_exist function instead.
-********************************************************************/
-
-#if 0
-BOOL dos_file_exist(char *fname,SMB_STRUCT_STAT *sbuf)
-{
- return file_exist(dos_to_unix(fname, False), sbuf);
-}
-#endif
-
-/*******************************************************************
- Check if a DOS directory exists.
-********************************************************************/
-
-BOOL dos_directory_exist(char *dname,SMB_STRUCT_STAT *st)
-{
- return directory_exist(dos_to_unix(dname, False), st);
-}
-
-/*******************************************************************
- Return the modtime of a DOS pathname.
-********************************************************************/
-
-time_t dos_file_modtime(char *fname)
-{
- return file_modtime(dos_to_unix(fname, False));
-}
-
-/*******************************************************************
- Return the file size of a DOS pathname.
-********************************************************************/
-
-SMB_OFF_T dos_file_size(char *file_name)
-{
- return get_file_size(dos_to_unix(file_name, False));
-}
diff --git a/source3/lib/iconv.c b/source3/lib/iconv.c
new file mode 100644
index 0000000000..a22c84997d
--- /dev/null
+++ b/source3/lib/iconv.c
@@ -0,0 +1,346 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 3.0
+ minimal iconv implementation
+ Copyright (C) Andrew Tridgell 2001
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+static size_t ascii_pull(char **, size_t *, char **, size_t *);
+static size_t ascii_push(char **, size_t *, char **, size_t *);
+static size_t weird_pull(char **, size_t *, char **, size_t *);
+static size_t weird_push(char **, size_t *, char **, size_t *);
+static size_t iconv_copy(char **, size_t *, char **, size_t *);
+
+/*
+ for each charset we have a function that pulls from that charset to
+ a ucs2 buffer, and a function that pushes to a ucs2 buffer
+*/
+static struct {
+ char *name;
+ size_t (*pull)(char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft);
+ size_t (*push)(char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft);
+} charsets[] = {
+ {"UCS2", iconv_copy, iconv_copy},
+ {"ASCII", ascii_pull, ascii_push},
+ {"WEIRD", weird_pull, weird_push},
+ {NULL, NULL, NULL}
+};
+
+/*
+ this is a simple portable iconv() implementaion. It only knows about
+ a very small number of character sets - just enough that Samba works
+ on systems that don't have iconv
+ */
+size_t smb_iconv(smb_iconv_t cd,
+ char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ char cvtbuf[2048];
+ char *bufp = cvtbuf;
+ size_t bufsize;
+
+#ifdef HAVE_NATIVE_ICONV
+ if (cd->cd) {
+ return iconv(cd->cd, inbuf, inbytesleft, outbuf, outbytesleft);
+ }
+#endif
+
+ if (!inbuf || ! *inbuf || !outbuf || ! *outbuf) return 0;
+
+ /* in most cases we can go direct */
+ if (cd->direct) {
+ return cd->direct(inbuf, inbytesleft, outbuf, outbytesleft);
+ }
+
+ /* otherwise we have to do it chunks at a time */
+ while (*inbytesleft > 0) {
+ bufp = cvtbuf;
+ bufsize = sizeof(cvtbuf);
+ if (cd->pull(inbuf, inbytesleft, &bufp, &bufsize) == -1 &&
+ errno != E2BIG) return -1;
+
+ bufp = cvtbuf;
+ bufsize = sizeof(cvtbuf) - bufsize;
+ if (cd->push(&bufp, &bufsize, outbuf, outbytesleft) == -1) return -1;
+ }
+
+ return 0;
+}
+
+/*
+ simple iconv_open() wrapper
+ */
+smb_iconv_t smb_iconv_open(const char *tocode, const char *fromcode)
+{
+ smb_iconv_t ret;
+ int from, to;
+#ifdef HAVE_NATIVE_ICONV
+ iconv_t cd = NULL;
+#endif
+
+ for (from=0; charsets[from].name; from++) {
+ if (strcasecmp(charsets[from].name, fromcode) == 0) break;
+ }
+ for (to=0; charsets[to].name; to++) {
+ if (strcasecmp(charsets[to].name, tocode) == 0) break;
+ }
+
+ if (!charsets[from].name || !charsets[to].name) {
+#ifdef HAVE_NATIVE_ICONV
+ cd = iconv_open(tocode, fromcode);
+ if (!cd)
+#endif
+ {
+ errno = EINVAL;
+ return (smb_iconv_t)-1;
+ }
+ }
+
+ ret = (smb_iconv_t)malloc(sizeof(*ret));
+ if (!ret) {
+ errno = ENOMEM;
+ return (smb_iconv_t)-1;
+ }
+ memset(ret, 0, sizeof(*ret));
+
+#ifdef HAVE_NATIVE_ICONV
+ /* see if we wil be using the native iconv */
+ if (cd) {
+ ret->cd = cd;
+ return ret;
+ }
+#endif
+
+ /* check for the simplest null conversion */
+ if (from == to) {
+ ret->direct = iconv_copy;
+ return ret;
+ }
+
+ /* check for conversion to/from ucs2 */
+ if (from == 0) {
+ ret->direct = charsets[to].push;
+ return ret;
+ }
+ if (to == 0) {
+ ret->direct = charsets[from].pull;
+ return ret;
+ }
+
+ /* the general case has to go via a buffer */
+ ret->pull = charsets[from].pull;
+ ret->push = charsets[to].push;
+ return ret;
+}
+
+/*
+ simple iconv_close() wrapper
+*/
+int smb_iconv_close (smb_iconv_t cd)
+{
+#ifdef HAVE_NATIVE_ICONV
+ if (cd->cd) {
+ iconv_close(cd->cd);
+ }
+#endif
+ memset(cd, 0, sizeof(*cd));
+ free(cd);
+ return 0;
+}
+
+
+/**********************************************************************
+ the following functions implement the builtin character sets in Samba
+ and also the "test" character sets that are designed to test
+ multi-byte character set support for english users
+***********************************************************************/
+
+static size_t ascii_pull(char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ while (*inbytesleft >= 1 && *outbytesleft >= 2) {
+ (*outbuf)[0] = (*inbuf)[0];
+ (*outbuf)[1] = 0;
+ (*inbytesleft) -= 1;
+ (*outbytesleft) -= 2;
+ (*inbuf) += 1;
+ (*outbuf) += 2;
+ }
+
+ if (*inbytesleft > 0) {
+ errno = E2BIG;
+ return -1;
+ }
+
+ return 0;
+}
+
+static size_t ascii_push(char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ int ir_count=0;
+
+ while (*inbytesleft >= 2 && *outbytesleft >= 1) {
+ (*outbuf)[0] = (*inbuf)[0];
+ if ((*inbuf)[1]) ir_count++;
+ (*inbytesleft) -= 2;
+ (*outbytesleft) -= 1;
+ (*inbuf) += 2;
+ (*outbuf) += 1;
+ }
+
+ if (*inbytesleft == 1) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (*inbytesleft > 1) {
+ errno = E2BIG;
+ return -1;
+ }
+
+ return ir_count;
+}
+
+
+/* the "weird" character set is very useful for testing multi-byte
+ support and finding bugs. Don't use on a production system!
+*/
+static struct {
+ char from;
+ char *to;
+ int len;
+} weird_table[] = {
+ {'q', "^q^", 3},
+ {'Q', "^Q^", 3},
+ {'x', "\\.q\\.", 5},
+ {'X', "\\.Z\\.", 5},
+ {0, NULL}
+};
+
+static size_t weird_pull(char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ while (*inbytesleft >= 1 && *outbytesleft >= 2) {
+ int i;
+ for (i=0;weird_table[i].from;i++) {
+ if (strncmp((*inbuf),
+ weird_table[i].to,
+ weird_table[i].len) == 0) {
+ if (*inbytesleft < weird_table[i].len) {
+ DEBUG(0,("ERROR: truncated weird string\n"));
+ smb_panic(__FUNCTION__);
+
+ } else {
+ (*outbuf)[0] = weird_table[i].from;
+ (*outbuf)[1] = 0;
+ (*inbytesleft) -= weird_table[i].len;
+ (*outbytesleft) -= 2;
+ (*inbuf) += weird_table[i].len;
+ (*outbuf) += 2;
+ goto next;
+ }
+ }
+ }
+ (*outbuf)[0] = (*inbuf)[0];
+ (*outbuf)[1] = 0;
+ (*inbytesleft) -= 1;
+ (*outbytesleft) -= 2;
+ (*inbuf) += 1;
+ (*outbuf) += 2;
+ next:
+ }
+
+ if (*inbytesleft > 0) {
+ errno = E2BIG;
+ return -1;
+ }
+
+ return 0;
+}
+
+static size_t weird_push(char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ int ir_count=0;
+
+ while (*inbytesleft >= 2 && *outbytesleft >= 1) {
+ int i;
+ for (i=0;weird_table[i].from;i++) {
+ if ((*inbuf)[0] == weird_table[i].from &&
+ (*inbuf)[1] == 0) {
+ if (*outbytesleft < weird_table[i].len) {
+ DEBUG(0,("No room for weird character\n"));
+ smb_panic(__FUNCTION__);
+ } else {
+ memcpy(*outbuf, weird_table[i].to,
+ weird_table[i].len);
+ (*inbytesleft) -= 2;
+ (*outbytesleft) -= weird_table[i].len;
+ (*inbuf) += 2;
+ (*outbuf) += weird_table[i].len;
+ goto next;
+ }
+ }
+ }
+ (*outbuf)[0] = (*inbuf)[0];
+ if ((*inbuf)[1]) ir_count++;
+ (*inbytesleft) -= 2;
+ (*outbytesleft) -= 1;
+ (*inbuf) += 2;
+ (*outbuf) += 1;
+ next:
+ }
+
+ if (*inbytesleft == 1) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (*inbytesleft > 1) {
+ errno = E2BIG;
+ return -1;
+ }
+
+ return ir_count;
+}
+
+static size_t iconv_copy(char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ int n;
+
+ n = MIN(*inbytesleft, *outbytesleft);
+
+ memmove(*outbuf, *inbuf, n);
+
+ (*inbytesleft) -= n;
+ (*outbytesleft) -= n;
+ (*inbuf) += n;
+ (*outbuf) += n;
+
+ if (*inbytesleft > 0) {
+ errno = E2BIG;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/source3/lib/kanji.c b/source3/lib/kanji.c
deleted file mode 100644
index 39e9933842..0000000000
--- a/source3/lib/kanji.c
+++ /dev/null
@@ -1,1691 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Kanji Extensions
- Copyright (C) Andrew Tridgell 1992-1998
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Adding for Japanese language by <fujita@ainix.isac.co.jp> 1994.9.5
- and extend coding system to EUC/SJIS/JIS/HEX at 1994.10.11
- and add all jis codes sequence type at 1995.8.16
- Notes: Hexadecimal code by <ohki@gssm.otuka.tsukuba.ac.jp>
- Adding features about Machine dependent codes and User Defined Codes
- by Hiroshi MIURA <miura@samba.gr.jp> 2000.3.19
-*/
-
-#define _KANJI_C_
-#include "includes.h"
-
-/*
- * Function pointers that get overridden when multi-byte code pages
- * are loaded.
- */
-
-const char *(*multibyte_strchr)(const char *, int ) = (const char *(*)(const char *, int )) strchr;
-const char *(*multibyte_strrchr)(const char *, int ) = (const char *(*)(const char *, int )) strrchr;
-const char *(*multibyte_strstr)(const char *, const char *) = (const char *(*)(const char *, const char *)) strstr;
-char *(*multibyte_strtok)(char *, const char *) = (char *(*)(char *, const 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 size_t skip_non_multibyte_char(char);
-static BOOL not_multibyte_char_1(char);
-
-char *(*_dos_to_unix)(char *, BOOL) = dos2unix_format;
-char *(*_unix_to_dos)(char *, BOOL) = unix2dos_format;
-size_t (*_skip_multibyte_char)(char) = skip_non_multibyte_char;
-BOOL (*is_multibyte_char_1)(char) = not_multibyte_char_1;
-
-#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 size_t skip_kanji_multibyte_char(char);
-static BOOL is_kanji_multibyte_char_1(char);
-
-char *(*_dos_to_unix)(char *, BOOL) = sj_to_sj;
-char *(*_unix_to_dos)(char *, BOOL) = sj_to_sj;
-size_t (*_skip_multibyte_char)(char) = skip_kanji_multibyte_char;
-int (*is_multibyte_char_1)(char) = is_kanji_multibyte_char_1;
-
-#endif /* KANJI */
-
-BOOL global_is_multibyte_codepage = False;
-
-/* jis si/so sequence */
-static char jis_kso = JIS_KSO;
-static char jis_ksi = JIS_KSI;
-static char hex_tag = HEXTAG;
-
-/*******************************************************************
- SHIFT JIS functions
-********************************************************************/
-
-/*******************************************************************
- search token from S1 separated any char of S2
- S1 contains SHIFT JIS chars.
-********************************************************************/
-
-static char *sj_strtok(char *s1, const char *s2)
-{
- static char *s = NULL;
- char *q;
- if (!s1) {
- if (!s) {
- return NULL;
- }
- s1 = s;
- }
- for (q = s1; *s1; ) {
- if (is_shift_jis (*s1)) {
- s1 += 2;
- } else if (is_kana (*s1)) {
- s1++;
- } 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 SHIFT JIS chars.
-********************************************************************/
-
-static const char *sj_strstr(const char *s1, const char *s2)
-{
- size_t len = strlen (s2);
- if (!*s2)
- return (const char *) s1;
- for (;*s1;) {
- if (*s1 == *s2) {
- if (strncmp (s1, s2, len) == 0)
- return (const char *) s1;
- }
- if (is_shift_jis (*s1)) {
- s1 += 2;
- } else {
- s1++;
- }
- }
- return NULL;
-}
-
-/*******************************************************************
- Search char C from beginning of S.
- S contains SHIFT JIS chars.
-********************************************************************/
-
-static const char *sj_strchr (const char *s, int c)
-{
- for (; *s; ) {
- if (*s == c)
- return (const char *) s;
- if (is_shift_jis (*s)) {
- s += 2;
- } else {
- s++;
- }
- }
- return NULL;
-}
-
-/*******************************************************************
- Search char C end of S.
- S contains SHIFT JIS chars.
-********************************************************************/
-
-static const char *sj_strrchr(const char *s, int c)
-{
- const char *q;
-
- for (q = 0; *s; ) {
- if (*s == c) {
- q = (const char *) s;
- }
- if (is_shift_jis (*s)) {
- s += 2;
- } else {
- s++;
- }
- }
- return q;
-}
-
-/*******************************************************************
- Kanji multibyte char skip function.
-*******************************************************************/
-
-static size_t skip_kanji_multibyte_char(char c)
-{
- if(is_shift_jis(c)) {
- return 2;
- } else if (is_kana(c)) {
- return 1;
- }
- return 0;
-}
-
-/*******************************************************************
- Kanji multibyte char identification.
-*******************************************************************/
-
-static BOOL is_kanji_multibyte_char_1(char c)
-{
- return is_shift_jis(c);
-}
-
-/*******************************************************************
- The following functions are the only ones needed to do multibyte
- support for Hangul, Big5 and Simplified Chinese. Most of the
- real work for these codepages is done in the generic multibyte
- functions. The only reason these functions are needed at all
- is that the is_xxx(c) calls are really preprocessor macros.
-********************************************************************/
-
-/*******************************************************************
- Hangul (Korean - code page 949) function.
-********************************************************************/
-
-static BOOL hangul_is_multibyte_char_1(char c)
-{
- return is_hangul(c);
-}
-
-/*******************************************************************
- Big5 Traditional Chinese (code page 950) function.
-********************************************************************/
-
-static BOOL big5_is_multibyte_char_1(char c)
-{
- return is_big5_c1(c);
-}
-
-/*******************************************************************
- Simplified Chinese (code page 936) function.
-********************************************************************/
-
-static BOOL simpch_is_multibyte_char_1(char c)
-{
- return is_simpch_c1(c);
-}
-
-/*******************************************************************
- Generic multibyte functions - used by Hangul, Big5 and Simplified
- Chinese codepages.
-********************************************************************/
-
-/*******************************************************************
- search token from S1 separated any char of S2
- S1 contains generic multibyte chars.
-********************************************************************/
-
-static char *generic_multibyte_strtok(char *s1, const char *s2)
-{
- static char *s = NULL;
- char *q;
- if (!s1) {
- if (!s) {
- return NULL;
- }
- s1 = s;
- }
- for (q = s1; *s1; ) {
- if ((*is_multibyte_char_1)(*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 generic multibyte chars.
-********************************************************************/
-
-static const char *generic_multibyte_strstr(const char *s1, const char *s2)
-{
- size_t len = strlen (s2);
- if (!*s2)
- return (const char *) s1;
- for (;*s1;) {
- if (*s1 == *s2) {
- if (strncmp (s1, s2, len) == 0)
- return (const char *) s1;
- }
- if ((*is_multibyte_char_1)(*s1)) {
- s1 += 2;
- } else {
- s1++;
- }
- }
- return NULL;
-}
-
-/*******************************************************************
- Search char C from beginning of S.
- S contains generic multibyte chars.
-********************************************************************/
-
-static const char *generic_multibyte_strchr(const char *s, int c)
-{
- for (; *s; ) {
- if (*s == c)
- return (const char *) s;
- if ((*is_multibyte_char_1)(*s)) {
- s += 2;
- } else {
- s++;
- }
- }
- return NULL;
-}
-
-/*******************************************************************
- Search char C end of S.
- S contains generic multibyte chars.
-********************************************************************/
-
-static const char *generic_multibyte_strrchr(const char *s, int c)
-{
- const char *q;
-
- for (q = 0; *s; ) {
- if (*s == c) {
- q = (const char *) s;
- }
- if ((*is_multibyte_char_1)(*s)) {
- s += 2;
- } else {
- s++;
- }
- }
- return q;
-}
-
-/*******************************************************************
- Generic multibyte char skip function.
-*******************************************************************/
-
-static size_t skip_generic_multibyte_char(char c)
-{
- if( (*is_multibyte_char_1)(c)) {
- return 2;
- }
- return 0;
-}
-
-/*******************************************************************
- Code conversion
-********************************************************************/
-
-/* convesion buffer */
-static char cvtbuf[2*sizeof(pstring)];
-
-/*******************************************************************
- EUC <-> SJIS
-********************************************************************/
-
-static int euc2sjis (int hi, int lo)
-{
- int w;
- int maxidx = SJISREVTBLSIZ;
- int minidx = 0;
- int i = 2;
-
- if (hi & 1) {
- hi = hi / 2 + (hi < 0xdf ? 0x31 : 0x71);
- w = (hi << 8) | (lo - (lo >= 0xe0 ? 0x60 : 0x61));
- } else {
- hi = hi / 2 + (hi < 0xdf ? 0x30 : 0x70);
- w = (hi << 8) | (lo - 2);
- }
- if ( (0x87 < hi ) && (hi < 0xed ) ) {
- return w;
- }
- while ( maxidx >= minidx ) {
- if ( sjisrev[i].start > w ) {
- maxidx = i-1;
- } else if ( w > sjisrev[i].end ) {
- minidx = i+1;
- } else {
- w -= sjisrev[i].start;
- w += sjisrev[i].rstart;
- break;
- }
- i = (int)( minidx + (maxidx - minidx) % 2 );
- }
- return w;
-}
-
-static int sjis2euc (int hi, int lo)
-{
- int minidx = 0;
- int maxidx = SJISCONVTBLSIZ -1; /* max index 1 less than number of entries */
- int i = ( 0 + SJISCONVTBLSIZ ) % 2;
- int w = (int)((hi << 8) | lo);
-
- if ( (sjisconv[0].start < w) && (w < sjisconv[SJISCONVTBLSIZ-1].end) ) {
- while (maxidx >= minidx) {
- if ( sjisconv[i].start > w ) {
- maxidx = i-1;
- } else if (w > sjisconv[i].end) {
- minidx = i+1;
- } else {
- w -= sjisconv[i].start;
- w += sjisconv[i].rstart;
- break;
- }
- i = (int)( minidx + (maxidx-minidx)%2 );
- }
- hi = (int) ((w >> 8) & 0xff);
- lo = (int) (w & 0xff);
- }
- if (hi >= 0xf0) {
- hi = GETAHI;
- lo = GETALO;
- }
- if (lo >= 0x9f)
- return ((hi * 2 - (hi >= 0xe0 ? 0xe0 : 0x60)) << 8) | (lo + 2);
- else
- return ((hi * 2 - (hi >= 0xe0 ? 0xe1 : 0x61)) << 8) |
- (lo + (lo >= 0x7f ? 0x60 : 0x61));
-}
-
-/*******************************************************************
- Convert FROM contain SHIFT JIS codes to EUC codes
- return converted buffer
-********************************************************************/
-
-static char *sj_to_euc(char *from, BOOL overwrite)
-{
- char *out;
- char *save;
-
- save = (char *) from;
- for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
- if (is_shift_jis (*from)) {
- int code = sjis2euc ((int) from[0] & 0xff, (int) from[1] & 0xff);
- *out++ = (code >> 8) & 0xff;
- *out++ = code & 0xff;
- from += 2;
- } else if (is_kana (*from)) {
- *out++ = (char)euc_kana;
- *out++ = *from++;
- } else {
- *out++ = *from++;
- }
- }
- *out = 0;
- if (overwrite) {
- pstrcpy((char *) save, (char *) cvtbuf);
- return (char *) save;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- Convert FROM contain EUC codes to SHIFT JIS codes
- return converted buffer
-********************************************************************/
-
-static char *euc_to_sj(char *from, BOOL overwrite)
-{
- char *out;
- char *save;
-
- save = (char *) from;
- for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3); ) {
- if (is_euc (*from)) {
- int code = euc2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
- *out++ = (code >> 8) & 0xff;
- *out++ = code & 0xff;
- from += 2;
- } else if (is_euc_kana (*from)) {
- *out++ = from[1];
- from += 2;
- } else {
- *out++ = *from++;
- }
- }
- *out = 0;
-
- if (overwrite) {
- pstrcpy(save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- EUC3 <-> SJIS
-********************************************************************/
-static int sjis3euc (int hi, int lo, int *len)
-{
- int i,w;
- int minidx;
- int maxidx;
-
- w = (int)((hi << 8) | lo);
-
- /* no sjis */
- if ( ( 0x40 >= lo ) && (lo >= 0xfc) && (lo == 0x7f )) {
- w = (GETAHI << 8) | GETALO;
-
- /* IBM Extended Kanji */
- } else if (( w == 0xfa54 )||( w == 0x81ca )) {
- *len = 2;
- return (0xa2cc);
-
- } else if (( w == 0xfa5b )||( w == 0x81e6)) {
- *len = 2;
- return (0xa2e8);
-
- } else if (( 0xfa <= hi ) && ( hi <= 0xfc ) ) {
- i = w - 0xfa40 - ( hi - 0xfa )*( 0xfb40 - 0xfafc) - ((lo < 0x7f)? 0 : 1 );
- if ( i <= EUC3CONVTBLSIZ ){
- *len = 3;
- return euc3conv[i];
- }
-
-/* NEC selected IBM Extend Kanji */
- /* there are 3 code that is not good for conv */
- } else if (( 0x8754 <= w ) && ( w <= 0x878a)) {
- minidx = 0;
- maxidx = EUC3CONV2TBLSIZ;
- i = minidx + (maxidx - minidx) % 2;
- while ( maxidx >= minidx ) {
- if ( euc3conv2[i].sjis > w ) {
- maxidx = i-1;
- } else if ( w > euc3conv2[i].sjis ) {
- minidx = i+1;
- } else {
- *len = 3;
- return (euc3conv2[i].euc);
- }
- i = (int)( minidx + (maxidx - minidx) % 2 );
- }
- /* else normal EUC */
-
- } else if (( w == 0xeef9 ) || ( w == 0x81ca )) {
- *len = 2;
- return (0xa2cc);
-
- } else if (( 0xed <= hi ) && ( hi <= 0xef )) {
- minidx = 0;
- maxidx = SJISREVTBLSIZ;
- i = 10;
- while ( maxidx >= minidx ) {
- if ( sjisrev[i].start > w ) {
- maxidx = i-1;
- } else if ( w > sjisrev[i].end ) {
- minidx = i+1;
- } else {
- w -= sjisrev[i].start;
- w += sjisrev[i].rstart;
- break;
- }
- i = (int)( minidx + (maxidx - minidx) % 2 );
- }
- if ( w >= 0xfa40 ) {
- i = w - 0xfa40 - ( hi - 0xfa )*( 0xfb40 - 0xfafc) - ((lo < 0x7f)? 0 : 1 );
- if ( i <= EUC3CONVTBLSIZ ){
- *len = 3;
- return euc3conv[i];
- } else {
- w = (GETAHI << 8) | GETALO;
- }
- }
- /* else normal EUC */
-
-/* UDC half low*/
-/* this area maps to the G2 UDC area: 0xf5a1 -- 0xfefe */
- } else if ((0xf0 <= hi) && (hi <= 0xf4)) {
- *len = 2;
- if (lo >= 0x9f) {
- return (((hi * 2 - 0xea) << 8) | (lo + 2));
- } else {
- return (((hi * 2 - 0xeb) << 8) | (lo + (lo >=0x7f ? 0x60: 0x61 )));
- }
-
-/* UDC half high*/
-/* this area maps to the G3 UDC area: 0xf8f5a1 -- 0xf8fefe */
- } else if ((0xf5 <= hi) && (hi <= 0xf9)) {
- *len = 3;
- if (lo >= 0x9f) {
- return (((hi*2 - 0xf4) << 8) | (lo + 2));
- } else {
- return (((hi*2 - 0xf5) << 8) | (lo + (lo >= 0x7f ? 0x60: 0x61 )));
- }
- /* ....checked all special case */
- }
-
- /* These Normal 2 byte EUC */
- *len = 2;
- hi = (int) ((w >> 8) & 0xff);
- lo = (int) (w & 0xff);
-
- if (hi >= 0xf0) { /* Check range */
- hi = GETAHI;
- lo = GETALO;
- }
-
- if (lo >= 0x9f)
- return ((hi * 2 - (hi >= 0xe0 ? 0xe0 : 0x60)) << 8) | (lo + 2);
- else
- return ((hi * 2 - (hi >= 0xe0 ? 0xe1 : 0x61)) << 8) |
- (lo + (lo >= 0x7f ? 0x60 : 0x61));
-}
-
-static int euc3sjis (int hi, int lo, BOOL is_3byte)
-{
- int w;
-
- w = (int)((hi << 8) | lo);
- if (is_3byte) {
- if (( 0xf5 <= hi) && ( hi <= 0xfe)) {
- /* UDC half high*/
- /* this area maps to the G3 UDC area */
- /* 0xf8f5a1 -- 0xf8fefe --> 0xf540 -- 0xf9fc */
- if (hi & 1) {
- return (((hi / 2 + 0x7b) << 8) | (lo - (lo >= 0xe0 ? 0x60 : 0x61)));
- } else {
- return (((hi / 2 + 0x7a) << 8) | (lo - 2));
- }
- } else {
- /* Using map table */
- int minidx = 0;
- int maxidx = EUC3REVTBLSIZ;
- int i = minidx + (maxidx - minidx) % 2;
-
- while ( maxidx >= minidx ) {
- if (euc3rev[i].euc > w) {
- maxidx = i-1;
- } else if (euc3rev[i].euc < w) {
- minidx = i+1;
- } else {
- return (euc3rev[i].sjis);
- }
- i = (int)( minidx + ( maxidx - minidx ) % 2);
- }
- return ((GETAHI << 8 ) | GETALO);
- }
- } else { /* is_2byte */
- if ((0xf5 <= hi) && (hi <= 0xfe)) {
- /* UDC half low*/
- /* this area maps to the G2 UDC area */
- /* 0xf5a1 -- 0xfefe --> 0xf040 -- 0xf4fc */
- if (hi & 1) {
- return (((hi / 2 + 0x76) << 8) | (lo - (lo >= 0xe0 ? 0x60 : 0x61)));
- } else {
- return (((hi / 2 + 0x75) << 8) | (lo - 2));
- }
- } else { /* Normal EUC */
- if (hi & 1) {
- hi = hi / 2 + (hi < 0xdf ? 0x31 : 0x71);
- return ((hi << 8) | (lo - (lo >= 0xe0 ? 0x60 : 0x61)));
- } else {
- hi = hi / 2 + (hi < 0xdf ? 0x30 : 0x70);
- return ((hi << 8) | (lo - 2));
- }
- }
- }
-}
-
-/*******************************************************************
- Convert FROM contain SHIFT JIS codes to EUC codes (with SS2)
- return converted buffer
-********************************************************************/
-
-static char *sj_to_euc3(char *from, BOOL overwrite)
-{
- char *out;
- char *save;
- int len;
-
- save = (char *) from;
- for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4);) {
- if (is_shift_jis (*from)) {
- int code = sjis3euc ((int) from[0] & 0xff, (int) from[1] & 0xff, &len);
- if (len == 3) {
- *out++ = (char)euc_sup;
- }
- *out++ = (code >> 8) & 0xff;
- *out++ = code & 0xff;
- from += 2;
- } else if (is_kana (*from)) {
- *out++ = (char)euc_kana;
- *out++ = *from++;
- } else {
- *out++ = *from++;
- }
- }
- *out = 0;
- if (overwrite) {
- pstrcpy((char *) save, (char *) cvtbuf);
- return (char *) save;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- Convert FROM contain EUC codes (with Sup-Kanji) to SHIFT JIS codes
- return converted buffer
-********************************************************************/
-static char *euc3_to_sj(char *from, BOOL overwrite)
-{
- char *out;
- char *save;
-
- save = (char *) from;
- for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3); ) {
- if (is_euc_sup (*from)) {
- int code = euc3sjis((int) from[1] & 0xff, (int) from[2] & 0xff, True);
- *out++ = (code >> 8) & 0xff;
- *out++ = code & 0xff;
- from += 3;
- } else if (is_euc (*from)) {
- int code = euc3sjis ((int) from[0] & 0xff, (int) from[1] & 0xff,False);
- *out++ = (code >> 8) & 0xff;
- *out++ = code & 0xff;
- from += 2;
- } else if (is_euc_kana (*from)) {
- *out++ = from[1];
- from += 2;
- } else {
- *out++ = *from++;
- }
- }
- *out = 0;
-
- if (overwrite) {
- pstrcpy(save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- JIS7,JIS8,JUNET <-> SJIS
-********************************************************************/
-
-static int sjis2jis(int hi, int lo)
-{
- int minidx = 0;
- int maxidx = SJISCONVTBLSIZ -1; /* max index 1 less than number of entries */
- int i = (0 + SJISCONVTBLSIZ) % 2;
- int w = (int)((hi << 8) | lo);
-
- if ((sjisconv[0].start < w) && (w < sjisconv[SJISCONVTBLSIZ-1].end)) {
- while (maxidx >= minidx) {
- if (sjisconv[i].start > w) {
- maxidx = i-1;
- } else if (w > sjisconv[i].end) {
- minidx = i+1;
- } else {
- w -= sjisconv[i].start;
- w += sjisconv[i].rstart;
- break;
- }
- i = (int)( minidx + (maxidx-minidx) %2 );
- }
- hi = (int) ((w >> 8) & 0xff);
- lo = (int) (w & 0xff);
- }
- if (hi >= 0xf0) {
- hi = GETAHI;
- lo = GETALO;
- }
- if (lo >= 0x9f)
- return ((hi * 2 - (hi >= 0xe0 ? 0x160 : 0xe0)) << 8) | (lo - 0x7e);
- else
- return ((hi * 2 - (hi >= 0xe0 ? 0x161 : 0xe1)) << 8) |
- (lo - (lo >= 0x7f ? 0x20 : 0x1f));
-}
-
-static int jis2sjis(int hi, int lo)
-{
- int w;
- int minidx = 0;
- int maxidx = SJISREVTBLSIZ;
- int i = 2;
-
- if (hi & 1) {
- hi = hi / 2 + (hi < 0x5f ? 0x71 : 0xb1);
- w = (hi << 8) | (lo + (lo >= 0x60 ? 0x20 : 0x1f));
- } else {
- hi = hi / 2 + (hi < 0x5f ? 0x70 : 0xb0);
- w = (hi << 8) | (lo + 0x7e);
- }
-
- if (( 0x87 < hi ) && ( hi < 0xed )) {
- return w;
- }
- while (maxidx >= minidx) {
- if (sjisrev[i].start > w) {
- maxidx = i-1;
- } else if (w > sjisrev[i].end) {
- minidx = i+1;
- } else {
- w -= sjisrev[i].start;
- w += sjisrev[i].rstart;
- break;
- }
- i = (int)( minidx + (maxidx-minidx) %2 );
- }
- return w;
-}
-
-/*******************************************************************
- Convert FROM contain JIS codes to SHIFT JIS codes
- return converted buffer
-********************************************************************/
-
-static char *jis8_to_sj(char *from, BOOL overwrite)
-{
- char *out;
- int shifted;
- char *save;
-
- shifted = _KJ_ROMAN;
- save = (char *) from;
- for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
- if (is_esc (*from)) {
- if (is_so1 (from[1]) && is_so2 (from[2])) {
- shifted = _KJ_KANJI;
- from += 3;
- } else if (is_si1 (from[1]) && is_si2 (from[2])) {
- shifted = _KJ_ROMAN;
- from += 3;
- } else { /* sequence error */
- goto normal;
- }
- } else {
-
-normal:
-
- switch (shifted) {
- default:
- case _KJ_ROMAN:
- *out++ = *from++;
- break;
- case _KJ_KANJI:
- {
- int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
- *out++ = (code >> 8) & 0xff;
- *out++ = code;
- from += 2;
- break;
- }
- }
- }
- }
-
- *out = 0;
- if (overwrite) {
- pstrcpy (save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- Convert FROM contain SHIFT JIS codes to JIS codes
- return converted buffer
-********************************************************************/
-
-static char *sj_to_jis8(char *from, BOOL overwrite)
-{
- char *out;
- int shifted;
- char *save;
-
- shifted = _KJ_ROMAN;
- save = (char *) from;
- for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
- if (is_shift_jis (*from)) {
- int code;
- switch (shifted) {
- case _KJ_ROMAN: /* to KANJI */
- *out++ = jis_esc;
- *out++ = jis_so1;
- *out++ = jis_kso;
- shifted = _KJ_KANJI;
- break;
- }
- code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
- *out++ = (code >> 8) & 0xff;
- *out++ = code;
- from += 2;
- } else {
- switch (shifted) {
- case _KJ_KANJI: /* to ROMAN/KANA */
- *out++ = jis_esc;
- *out++ = jis_si1;
- *out++ = jis_ksi;
- shifted = _KJ_ROMAN;
- break;
- }
- *out++ = *from++;
- }
- }
-
- switch (shifted) {
- case _KJ_KANJI: /* to ROMAN/KANA */
- *out++ = jis_esc;
- *out++ = jis_si1;
- *out++ = jis_ksi;
- shifted = _KJ_ROMAN;
- break;
- }
- *out = 0;
- if (overwrite) {
- pstrcpy (save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- Convert FROM contain 7 bits JIS codes to SHIFT JIS codes
- return converted buffer
-********************************************************************/
-static char *jis7_to_sj(char *from, BOOL overwrite)
-{
- char *out;
- int shifted;
- char *save;
-
- shifted = _KJ_ROMAN;
- save = (char *) from;
- for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
- if (is_esc (*from)) {
- if (is_so1 (from[1]) && is_so2 (from[2])) {
- shifted = _KJ_KANJI;
- from += 3;
- } else if (is_si1 (from[1]) && is_si2 (from[2])) {
- shifted = _KJ_ROMAN;
- from += 3;
- } else { /* sequence error */
- goto normal;
- }
- } else if (is_so (*from)) {
- shifted = _KJ_KANA; /* to KANA */
- from++;
- } else if (is_si (*from)) {
- shifted = _KJ_ROMAN; /* to ROMAN */
- from++;
- } else {
- normal:
- switch (shifted) {
- default:
- case _KJ_ROMAN:
- *out++ = *from++;
- break;
- case _KJ_KANJI:
- {
- int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
- *out++ = (code >> 8) & 0xff;
- *out++ = code;
- from += 2;
- }
- break;
- case _KJ_KANA:
- *out++ = ((int) from[0]) + 0x80;
- break;
- }
- }
- }
- *out = 0;
- if (overwrite) {
- pstrcpy (save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- Convert FROM contain SHIFT JIS codes to 7 bits JIS codes
- return converted buffer
-********************************************************************/
-static char *sj_to_jis7(char *from, BOOL overwrite)
-{
- char *out;
- int shifted;
- char *save;
-
- shifted = _KJ_ROMAN;
- save = (char *) from;
- for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
- if (is_shift_jis (*from)) {
- int code;
- switch (shifted) {
- case _KJ_KANA:
- *out++ = jis_si; /* to ROMAN and through down */
- case _KJ_ROMAN: /* to KANJI */
- *out++ = jis_esc;
- *out++ = jis_so1;
- *out++ = jis_kso;
- shifted = _KJ_KANJI;
- break;
- }
- code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
- *out++ = (code >> 8) & 0xff;
- *out++ = code;
- from += 2;
- } else if (is_kana (from[0])) {
- switch (shifted) {
- case _KJ_KANJI: /* to ROMAN */
- *out++ = jis_esc;
- *out++ = jis_si1;
- *out++ = jis_ksi;
- case _KJ_ROMAN: /* to KANA */
- *out++ = jis_so;
- shifted = _KJ_KANA;
- break;
- }
- *out++ = ((int) *from++) - 0x80;
- } else {
- switch (shifted) {
- case _KJ_KANA:
- *out++ = jis_si; /* to ROMAN */
- shifted = _KJ_ROMAN;
- break;
- case _KJ_KANJI: /* to ROMAN */
- *out++ = jis_esc;
- *out++ = jis_si1;
- *out++ = jis_ksi;
- shifted = _KJ_ROMAN;
- break;
- }
- *out++ = *from++;
- }
- }
- switch (shifted) {
- case _KJ_KANA:
- *out++ = jis_si; /* to ROMAN */
- break;
- case _KJ_KANJI: /* to ROMAN */
- *out++ = jis_esc;
- *out++ = jis_si1;
- *out++ = jis_ksi;
- break;
- }
- *out = 0;
- if (overwrite) {
- pstrcpy (save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- Convert FROM contain 7 bits JIS(junet) codes to SHIFT JIS codes
- return converted buffer
-********************************************************************/
-
-static char *junet_to_sj(char *from, BOOL overwrite)
-{
- char *out;
- int shifted;
- char *save;
-
- shifted = _KJ_ROMAN;
- save = (char *) from;
- for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
- if (is_esc (*from)) {
- if (is_so1 (from[1]) && is_so2 (from[2])) {
- shifted = _KJ_KANJI;
- from += 3;
- } else if (is_si1 (from[1]) && is_si2 (from[2])) {
- shifted = _KJ_ROMAN;
- from += 3;
- } else if (is_juk1(from[1]) && is_juk2 (from[2])) {
- shifted = _KJ_KANA;
- from += 3;
- } else { /* sequence error */
- goto normal;
- }
- } else {
- normal:
- switch (shifted) {
- default:
- case _KJ_ROMAN:
- *out++ = *from++;
- break;
- case _KJ_KANJI:
- {
- int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
- *out++ = (code >> 8) & 0xff;
- *out++ = code;
- from += 2;
- }
- break;
- case _KJ_KANA:
- *out++ = ((int) from[0]) + 0x80;
- break;
- }
- }
- }
- *out = 0;
- if (overwrite) {
- pstrcpy (save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- Convert FROM contain SHIFT JIS codes to 7 bits JIS(junet) codes
- return converted buffer
-********************************************************************/
-static char *sj_to_junet(char *from, BOOL overwrite)
-{
- char *out;
- int shifted;
- char *save;
-
- shifted = _KJ_ROMAN;
- save = (char *) from;
- for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
- if (is_shift_jis (*from)) {
- int code;
- switch (shifted) {
- case _KJ_KANA:
- case _KJ_ROMAN: /* to KANJI */
- *out++ = jis_esc;
- *out++ = jis_so1;
- *out++ = jis_so2;
- shifted = _KJ_KANJI;
- break;
- }
- code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
- *out++ = (code >> 8) & 0xff;
- *out++ = code;
- from += 2;
- } else if (is_kana (from[0])) {
- switch (shifted) {
- case _KJ_KANJI: /* to ROMAN */
- case _KJ_ROMAN: /* to KANA */
- *out++ = jis_esc;
- *out++ = junet_kana1;
- *out++ = junet_kana2;
- shifted = _KJ_KANA;
- break;
- }
- *out++ = ((int) *from++) - 0x80;
- } else {
- switch (shifted) {
- case _KJ_KANA:
- case _KJ_KANJI: /* to ROMAN */
- *out++ = jis_esc;
- *out++ = jis_si1;
- *out++ = jis_si2;
- shifted = _KJ_ROMAN;
- break;
- }
- *out++ = *from++;
- }
- }
- switch (shifted) {
- case _KJ_KANA:
- case _KJ_KANJI: /* to ROMAN */
- *out++ = jis_esc;
- *out++ = jis_si1;
- *out++ = jis_si2;
- break;
- }
- *out = 0;
- if (overwrite) {
- pstrcpy (save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- HEX <-> SJIS
-********************************************************************/
-/* ":xx" -> a byte */
-static char *hex_to_sj(char *from, BOOL overwrite)
-{
- char *sp, *dp;
-
- sp = (char *) from;
- dp = cvtbuf;
- while (*sp && (dp - cvtbuf < sizeof(cvtbuf)-3)) {
- if (*sp == hex_tag && isxdigit((int)sp[1]) && isxdigit((int)sp[2])) {
- *dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2]));
- sp += 3;
- } else
- *dp++ = *sp++;
- }
- *dp = '\0';
- if (overwrite) {
- pstrcpy ((char *) from, (char *) cvtbuf);
- return (char *) from;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- kanji/kana -> ":xx"
-********************************************************************/
-static char *sj_to_hex(char *from, BOOL overwrite)
-{
- unsigned char *sp, *dp;
-
- sp = (unsigned char*) from;
- dp = (unsigned char*) cvtbuf;
- while (*sp && (((char *)dp)- cvtbuf < sizeof(cvtbuf)-7)) {
- if (is_kana(*sp)) {
- *dp++ = hex_tag;
- *dp++ = bin2hex (((*sp)>>4)&0x0f);
- *dp++ = bin2hex ((*sp)&0x0f);
- sp++;
- } else if (is_shift_jis (*sp) && is_shift_jis2 (sp[1])) {
- *dp++ = hex_tag;
- *dp++ = bin2hex (((*sp)>>4)&0x0f);
- *dp++ = bin2hex ((*sp)&0x0f);
- sp++;
- *dp++ = hex_tag;
- *dp++ = bin2hex (((*sp)>>4)&0x0f);
- *dp++ = bin2hex ((*sp)&0x0f);
- sp++;
- } else
- *dp++ = *sp++;
- }
- *dp = '\0';
- if (overwrite) {
- pstrcpy ((char *) from, (char *) cvtbuf);
- return (char *) from;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- CAP <-> SJIS
-********************************************************************/
-/* ":xx" CAP -> a byte */
-static char *cap_to_sj(char *from, BOOL overwrite)
-{
- char *sp, *dp;
-
- sp = (char *) from;
- dp = cvtbuf;
- while (*sp && (dp- cvtbuf < sizeof(cvtbuf)-2)) {
- /*
- * The only change between this and hex_to_sj is here. sj_to_cap only
- * translates characters greater or equal to 0x80 - make sure that here
- * we only do the reverse (that's why the strchr is used rather than
- * isxdigit. Based on fix from ado@elsie.nci.nih.gov (Arthur David Olson).
- */
- if (*sp == hex_tag && (strchr ("89abcdefABCDEF", sp[1]) != NULL) && isxdigit((int)sp[2])) {
- *dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2]));
- sp += 3;
- } else
- *dp++ = *sp++;
- }
- *dp = '\0';
- if (overwrite) {
- pstrcpy ((char *) from, (char *) cvtbuf);
- return (char *) from;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- kanji/kana -> ":xx" - CAP format.
-********************************************************************/
-static char *sj_to_cap(char *from, BOOL overwrite)
-{
- unsigned char *sp, *dp;
-
- sp = (unsigned char*) from;
- dp = (unsigned char*) cvtbuf;
- while (*sp && (((char *)dp) - cvtbuf < sizeof(cvtbuf)-4)) {
- if (*sp >= 0x80) {
- *dp++ = hex_tag;
- *dp++ = bin2hex (((*sp)>>4)&0x0f);
- *dp++ = bin2hex ((*sp)&0x0f);
- sp++;
- } else {
- *dp++ = *sp++;
- }
- }
- *dp = '\0';
- if (overwrite) {
- pstrcpy ((char *) from, (char *) cvtbuf);
- return (char *) from;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- sj to sj
-********************************************************************/
-static char *sj_to_sj(char *from, BOOL overwrite)
-{
- if (!overwrite) {
- pstrcpy (cvtbuf, (char *) from);
- return cvtbuf;
- } else {
- return (char *) from;
- }
-}
-
-/*******************************************************************
- cp to utf8
-********************************************************************/
-static char *cp_to_utf8(char *from, BOOL overwrite)
-{
- unsigned char *dst;
- unsigned char *src;
- smb_ucs2_t val;
- int w;
- size_t len;
-
- src = (unsigned char *)from;
- dst = (unsigned char *)cvtbuf;
- while (*src && (((char *)dst - cvtbuf) < sizeof(cvtbuf)-4)) {
- len = _skip_multibyte_char(*src);
- if ( len == 2 ) {
- w = (int)(*src++ & 0xff);
- w = (int)((w << 8)|(*src++ & 0xff));
- } else {
- w = (int)(*src++ & 0xff);
- }
- val = doscp2ucs2(w);
-
- if ( val <= 0x7f ) {
- *dst++ = (char)(val & 0xff);
- } else if ( val <= 0x7ff ){
- *dst++ = (char)( 0xc0 | ((val >> 6) & 0xff));
- *dst++ = (char)( 0x80 | ( val & 0x3f ));
- } else {
- *dst++ = (char)( 0xe0 | ((val >> 12) & 0x0f));
- *dst++ = (char)( 0x80 | ((val >> 6) & 0x3f));
- *dst++ = (char)( 0x80 | (val & 0x3f));
- }
-
- }
- *dst++='\0';
- if (overwrite) {
- pstrcpy ((char *) from, (char *) cvtbuf);
- return (char *) from;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- utf8 to cp
-********************************************************************/
-static char *utf8_to_cp(char *from, BOOL overwrite)
-{
- unsigned char *src;
- unsigned char *dst;
- smb_ucs2_t val;
- int w;
-
- src = (unsigned char *)from;
- dst = (unsigned char *)cvtbuf;
-
- while (*src && ((char *)dst - cvtbuf < sizeof(cvtbuf)-4)) {
- val = (*src++ & 0xff);
- if (val < 0x80) {
- *dst++ = (char)(val & 0x7f);
- } else if ((0xc0 <= val) && (val <= 0xdf)
- && (0x80 <= *src) && (*src <= 0xbf)) {
- w = ucs2doscp( ((val & 31) << 6) | ((*src++) & 63 ));
- *dst++ = (char)((w >> 8) & 0xff);
- *dst++ = (char)(w & 0xff);
- } else {
- val = (val & 0x0f) << 12;
- val |= ((*src++ & 0x3f) << 6);
- val |= (*src++ & 0x3f);
- w = ucs2doscp(val);
- *dst++ = (char)((w >> 8) & 0xff);
- *dst++ = (char)(w & 0xff);
- }
- }
- *dst++='\0';
- if (overwrite) {
- pstrcpy ((char *) from, (char *) cvtbuf);
- return (char *) from;
- } else {
- return cvtbuf;
- }
-}
-
-/************************************************************************
- conversion:
- _dos_to_unix _unix_to_dos
-************************************************************************/
-
-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:
- _dos_to_unix = sj_to_euc;
- _unix_to_dos = euc_to_sj;
- break;
-
- case JIS7_CODE:
- _dos_to_unix = sj_to_jis7;
- _unix_to_dos = jis7_to_sj;
- break;
-
- case JIS8_CODE:
- _dos_to_unix = sj_to_jis8;
- _unix_to_dos = jis8_to_sj;
- break;
-
- case JUNET_CODE:
- _dos_to_unix = sj_to_junet;
- _unix_to_dos = junet_to_sj;
- break;
-
- case HEX_CODE:
- _dos_to_unix = sj_to_hex;
- _unix_to_dos = hex_to_sj;
- break;
-
- case CAP_CODE:
- _dos_to_unix = sj_to_cap;
- _unix_to_dos = cap_to_sj;
- break;
- case UTF8_CODE:
- _dos_to_unix = cp_to_utf8;
- _unix_to_dos = utf8_to_cp;
- break;
- case EUC3_CODE:
- _dos_to_unix = sj_to_euc3;
- _unix_to_dos = euc3_to_sj;
- break;
- }
-}
-
-/************************************************************************
- Interpret coding system.
-************************************************************************/
-
-void interpret_coding_system(char *str)
-{
- int codes = UNKNOWN_CODE;
-
- if (strequal (str, "sjis")) {
- codes = SJIS_CODE;
- } else if (strequal (str, "euc")) {
- codes = EUC_CODE;
- } else if (strequal (str, "cap")) {
- codes = CAP_CODE;
- hex_tag = HEXTAG;
- } else if (strequal (str, "hex")) {
- codes = HEX_CODE;
- hex_tag = HEXTAG;
- } else if (!strncasecmp (str, "hex", 3)) {
- codes = HEX_CODE;
- hex_tag = (str[3] ? str[3] : HEXTAG);
- } else if (strequal (str, "j8bb")) {
- codes = JIS8_CODE;
- jis_kso = 'B';
- jis_ksi = 'B';
- } else if (strequal (str, "j8bj") || strequal (str, "jis8")) {
- codes = JIS8_CODE;
- jis_kso = 'B';
- jis_ksi = 'J';
- } else if (strequal (str, "j8bh")) {
- codes = JIS8_CODE;
- jis_kso = 'B';
- jis_ksi = 'H';
- } else if (strequal (str, "j8@b")) {
- codes = JIS8_CODE;
- jis_kso = '@';
- jis_ksi = 'B';
- } else if (strequal (str, "j8@j")) {
- codes = JIS8_CODE;
- jis_kso = '@';
- jis_ksi = 'J';
- } else if (strequal (str, "j8@h")) {
- codes = JIS8_CODE;
- jis_kso = '@';
- jis_ksi = 'H';
- } else if (strequal (str, "j7bb")) {
- codes = JIS7_CODE;
- jis_kso = 'B';
- jis_ksi = 'B';
- } else if (strequal (str, "j7bj") || strequal (str, "jis7")) {
- codes = JIS7_CODE;
- jis_kso = 'B';
- jis_ksi = 'J';
- } else if (strequal (str, "j7bh")) {
- codes = JIS7_CODE;
- jis_kso = 'B';
- jis_ksi = 'H';
- } else if (strequal (str, "j7@b")) {
- codes = JIS7_CODE;
- jis_kso = '@';
- jis_ksi = 'B';
- } else if (strequal (str, "j7@j")) {
- codes = JIS7_CODE;
- jis_kso = '@';
- jis_ksi = 'J';
- } else if (strequal (str, "j7@h")) {
- codes = JIS7_CODE;
- jis_kso = '@';
- jis_ksi = 'H';
- } else if (strequal (str, "jubb")) {
- codes = JUNET_CODE;
- jis_kso = 'B';
- jis_ksi = 'B';
- } else if (strequal (str, "jubj") || strequal (str, "junet")) {
- codes = JUNET_CODE;
- jis_kso = 'B';
- jis_ksi = 'J';
- } else if (strequal (str, "jubh")) {
- codes = JUNET_CODE;
- jis_kso = 'B';
- jis_ksi = 'H';
- } else if (strequal (str, "ju@b")) {
- codes = JUNET_CODE;
- jis_kso = '@';
- jis_ksi = 'B';
- } else if (strequal (str, "ju@j")) {
- codes = JUNET_CODE;
- jis_kso = '@';
- jis_ksi = 'J';
- } else if (strequal (str, "ju@h")) {
- codes = JUNET_CODE;
- jis_kso = '@';
- jis_ksi = 'H';
- } else if (strequal (str, "utf8")) {
- codes = UTF8_CODE;
- } else if (strequal (str, "euc3")) {
- codes = EUC3_CODE;
- }
- setup_string_function (codes);
-}
-
-/*******************************************************************
- Non multibyte char function.
-*******************************************************************/
-
-static size_t skip_non_multibyte_char(char c)
-{
- return 0;
-}
-
-/*******************************************************************
- Function that always says a character isn't multibyte.
-*******************************************************************/
-
-static BOOL not_multibyte_char_1(char c)
-{
- return False;
-}
-
-/*******************************************************************
- 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 = sj_strchr;
- multibyte_strrchr = sj_strrchr;
- multibyte_strstr = sj_strstr;
- multibyte_strtok = sj_strtok;
- _skip_multibyte_char = skip_kanji_multibyte_char;
- is_multibyte_char_1 = is_kanji_multibyte_char_1;
- global_is_multibyte_codepage = True;
- break;
- case HANGUL_CODEPAGE:
- multibyte_strchr = generic_multibyte_strchr;
- multibyte_strrchr = generic_multibyte_strrchr;
- multibyte_strstr = generic_multibyte_strstr;
- multibyte_strtok = generic_multibyte_strtok;
- _skip_multibyte_char = skip_generic_multibyte_char;
- is_multibyte_char_1 = hangul_is_multibyte_char_1;
- global_is_multibyte_codepage = True;
- break;
- case BIG5_CODEPAGE:
- multibyte_strchr = generic_multibyte_strchr;
- multibyte_strrchr = generic_multibyte_strrchr;
- multibyte_strstr = generic_multibyte_strstr;
- multibyte_strtok = generic_multibyte_strtok;
- _skip_multibyte_char = skip_generic_multibyte_char;
- is_multibyte_char_1 = big5_is_multibyte_char_1;
- global_is_multibyte_codepage = True;
- break;
- case SIMPLIFIED_CHINESE_CODEPAGE:
- multibyte_strchr = generic_multibyte_strchr;
- multibyte_strrchr = generic_multibyte_strrchr;
- multibyte_strstr = generic_multibyte_strstr;
- multibyte_strtok = generic_multibyte_strtok;
- _skip_multibyte_char = skip_generic_multibyte_char;
- is_multibyte_char_1 = simpch_is_multibyte_char_1;
- global_is_multibyte_codepage = True;
- break;
- /*
- * Single char size code page.
- */
- default:
- multibyte_strchr = (const char *(*)(const char *, int )) strchr;
- multibyte_strrchr = (const char *(*)(const char *, int )) strrchr;
- multibyte_strstr = (const char *(*)(const char *, const char *)) strstr;
- multibyte_strtok = (char *(*)(char *, const char *)) strtok;
- _skip_multibyte_char = skip_non_multibyte_char;
- is_multibyte_char_1 = not_multibyte_char_1;
- global_is_multibyte_codepage = False;
- break;
- }
-}
-/* *******************************************************
- function(s) for "dynamic" encoding of SWAT output.
- in this version, only dos_to_dos, dos_to_unix, unix_to_dos
- are used for bug fix. conversion to web encoding
- (to catalog file encoding) is not needed because
- they are using same character codes.
- **************************************************** */
-static char *no_conversion(char *str, BOOL bOverwrite)
-{
- static pstring temp;
- if(bOverwrite)
- return str;
- pstrcpy(temp, str);
- return temp;
-}
-char *(*_dos_to_dos)(char *, BOOL) = no_conversion;
diff --git a/source3/lib/ms_fnmatch.c b/source3/lib/ms_fnmatch.c
index 72f61c021c..39b3e0013c 100644
--- a/source3/lib/ms_fnmatch.c
+++ b/source3/lib/ms_fnmatch.c
@@ -31,37 +31,37 @@
#include "includes.h"
#endif
-
-
/*
bugger. we need a separate wildcard routine for older versions
of the protocol. This is not yet perfect, but its a lot
- better thaan what we had */
-static int ms_fnmatch_lanman_core(const char *pattern, const char *string)
+ better than what we had */
+static int ms_fnmatch_lanman_core(const smb_ucs2_t *pattern,
+ const smb_ucs2_t *string)
{
- const char *p = pattern, *n = string;
- char c;
+ const smb_ucs2_t *p = pattern, *n = string;
+ smb_ucs2_t c;
- if (strcmp(p,"?")==0 && strcmp(n,".")==0) goto match;
+ if (strcmp_wa(p, "?")==0 && strcmp_wa(n, ".")) goto match;
while ((c = *p++)) {
switch (c) {
- case '.':
+ case UCS2_CHAR('.'):
if (! *n) goto next;
- /* if (! *n && ! *p) goto match; */
- if (*n != '.') goto nomatch;
+ if (*n != UCS2_CHAR('.')) goto nomatch;
n++;
break;
- case '?':
+ case UCS2_CHAR('?'):
if (! *n) goto next;
- if ((*n == '.' && n[1] != '.') || ! *n) goto next;
+ if ((*n == UCS2_CHAR('.') &&
+ n[1] != UCS2_CHAR('.')) || ! *n)
+ goto next;
n++;
break;
- case '>':
+ case UCS2_CHAR('>'):
if (! *n) goto next;
- if (n[0] == '.') {
+ if (n[0] == UCS2_CHAR('.')) {
if (! n[1] && ms_fnmatch_lanman_core(p, n+1) == 0) goto match;
if (ms_fnmatch_lanman_core(p, n) == 0) goto match;
goto nomatch;
@@ -69,7 +69,7 @@ static int ms_fnmatch_lanman_core(const char *pattern, const char *string)
n++;
break;
- case '*':
+ case UCS2_CHAR('*'):
if (! *n) goto next;
if (! *p) goto match;
for (; *n; n++) {
@@ -77,19 +77,20 @@ static int ms_fnmatch_lanman_core(const char *pattern, const char *string)
}
break;
- case '<':
+ case UCS2_CHAR('<'):
for (; *n; n++) {
if (ms_fnmatch_lanman_core(p, n) == 0) goto match;
- if (*n == '.' && !strchr(n+1,'.')) {
+ if (*n == UCS2_CHAR('.') &&
+ !strchr_w(n+1,UCS2_CHAR('.'))) {
n++;
break;
}
}
break;
- case '"':
+ case UCS2_CHAR('"'):
if (*n == 0 && ms_fnmatch_lanman_core(p, n) == 0) goto match;
- if (*n != '.') goto nomatch;
+ if (*n != UCS2_CHAR('.')) goto nomatch;
n++;
break;
@@ -118,16 +119,19 @@ next:
return 0;
}
-static int ms_fnmatch_lanman1(const char *pattern, const char *string)
+static int ms_fnmatch_lanman1(const smb_ucs2_t *pattern, const smb_ucs2_t *string)
{
- if (!strpbrk(pattern, "?*<>\"")) {
- if (strcmp(string,"..") == 0) string = ".";
- return strcasecmp(pattern, string);
+ if (!strpbrk_wa(pattern, "?*<>\"")) {
+ smb_ucs2_t s[] = {UCS2_CHAR('.'), 0};
+ if (strcmp_wa(string,"..") == 0) string = s;
+ return strcasecmp_w(pattern, string);
}
- if (strcmp(string,"..") == 0 || strcmp(string,".") == 0) {
- return ms_fnmatch_lanman_core(pattern, "..") &&
- ms_fnmatch_lanman_core(pattern, ".");
+ if (strcmp_wa(string,"..") == 0 || strcmp_wa(string,".") == 0) {
+ smb_ucs2_t dot[] = {UCS2_CHAR('.'), 0};
+ smb_ucs2_t dotdot[] = {UCS2_CHAR('.'), UCS2_CHAR('.'), 0};
+ return ms_fnmatch_lanman_core(pattern, dotdot) &&
+ ms_fnmatch_lanman_core(pattern, dot);
}
return ms_fnmatch_lanman_core(pattern, string);
@@ -142,10 +146,10 @@ static int ms_fnmatch_lanman1(const char *pattern, const char *string)
Returns 0 on match, -1 on fail.
*/
-int ms_fnmatch(const char *pattern, const char *string)
+static int ms_fnmatch_w(const smb_ucs2_t *pattern, const smb_ucs2_t *string)
{
- const char *p = pattern, *n = string;
- char c;
+ const smb_ucs2_t *p = pattern, *n = string;
+ smb_ucs2_t c;
extern int Protocol;
if (Protocol <= PROTOCOL_LANMAN2) {
@@ -154,40 +158,40 @@ int ms_fnmatch(const char *pattern, const char *string)
while ((c = *p++)) {
switch (c) {
- case '?':
+ case UCS2_CHAR('?'):
if (! *n) return -1;
n++;
break;
- case '>':
- if (n[0] == '.') {
- if (! n[1] && ms_fnmatch(p, n+1) == 0) return 0;
- if (ms_fnmatch(p, n) == 0) return 0;
+ case UCS2_CHAR('>'):
+ if (n[0] == UCS2_CHAR('.')) {
+ if (! n[1] && ms_fnmatch_w(p, n+1) == 0) return 0;
+ if (ms_fnmatch_w(p, n) == 0) return 0;
return -1;
}
- if (! *n) return ms_fnmatch(p, n);
+ if (! *n) return ms_fnmatch_w(p, n);
n++;
break;
- case '*':
+ case UCS2_CHAR('*'):
for (; *n; n++) {
- if (ms_fnmatch(p, n) == 0) return 0;
+ if (ms_fnmatch_w(p, n) == 0) return 0;
}
break;
- case '<':
+ case UCS2_CHAR('<'):
for (; *n; n++) {
- if (ms_fnmatch(p, n) == 0) return 0;
- if (*n == '.' && !strchr(n+1,'.')) {
+ if (ms_fnmatch_w(p, n) == 0) return 0;
+ if (*n == UCS2_CHAR('.') && !strchr_wa(n+1,'.')) {
n++;
break;
}
}
break;
- case '"':
- if (*n == 0 && ms_fnmatch(p, n) == 0) return 0;
- if (*n != '.') return -1;
+ case UCS2_CHAR('"'):
+ if (*n == 0 && ms_fnmatch_w(p, n) == 0) return 0;
+ if (*n != UCS2_CHAR('.')) return -1;
n++;
break;
@@ -203,57 +207,12 @@ int ms_fnmatch(const char *pattern, const char *string)
}
-#if FNMATCH_TEST
-
-static int match_one(char *pattern, char *file)
+int ms_fnmatch(const char *pattern, const char *string)
{
- if (strcmp(file,"..") == 0) file = ".";
- if (strcmp(pattern,".") == 0) return -1;
-
- return ms_fnmatch(pattern, file);
-}
+ wpstring p, s;
-static char *match_test(char *pattern, char *file, char *short_name)
-{
- static char ret[4];
- strncpy(ret, "---", 3);
-
- if (match_one(pattern, ".") == 0) ret[0] = '+';
- if (match_one(pattern, "..") == 0) ret[1] = '+';
- if (match_one(pattern, file) == 0 ||
- (*short_name && match_one(pattern, short_name)==0)) ret[2] = '+';
- return ret;
-}
+ pstrcpy_wa(p, pattern);
+ pstrcpy_wa(s, string);
- int main(int argc, char *argv[])
-{
- int ret;
- char ans[4], mask[100], file[100], mfile[100];
- char *ans2;
- int n, i=0;
- char line[200];
-
- if (argc == 3) {
- ret = ms_fnmatch(argv[1], argv[2]);
- if (ret == 0)
- printf("YES\n");
- else printf("NO\n");
- return ret;
- }
- mfile[0] = 0;
-
- while (fgets(line, sizeof(line)-1, stdin)) {
- n = sscanf(line, "%3s %s %s %s\n", ans, mask, file, mfile);
- if (n < 3) continue;
- ans2 = match_test(mask, file, mfile);
- if (strcmp(ans2, ans)) {
- printf("%s %s %d mask=[%s] file=[%s] mfile=[%s]\n",
- ans, ans2, i, mask, file, mfile);
- }
- i++;
- mfile[0] = 0;
- }
- return 0;
+ return ms_fnmatch_w(p, s);
}
-#endif /* FNMATCH_TEST */
-
diff --git a/source3/lib/sysacls.c b/source3/lib/sysacls.c
index 0770a8856a..bdf18b52fc 100644
--- a/source3/lib/sysacls.c
+++ b/source3/lib/sysacls.c
@@ -161,7 +161,7 @@ int sys_acl_valid( SMB_ACL_T theacl )
return acl_valid(theacl);
}
-int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
+int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
{
return acl_set_file(name, acltype, theacl);
}
diff --git a/source3/lib/system.c b/source3/lib/system.c
index a402af77c9..8d4a872f14 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -727,176 +727,6 @@ struct passwd *sys_getpwuid(uid_t uid)
}
/**************************************************************************
- The following are the UNICODE versions of *all* system interface functions
- called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
- which currently are left as ascii as they are not used other than in name
- resolution.
-****************************************************************************/
-
-/**************************************************************************
- Wide stat. Just narrow and call sys_xxx.
-****************************************************************************/
-
-int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
-{
- pstring fname;
- return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
-}
-
-/**************************************************************************
- Wide lstat. Just narrow and call sys_xxx.
-****************************************************************************/
-
-int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
-{
- pstring fname;
- return sys_lstat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
-}
-
-/**************************************************************************
- Wide creat. Just narrow and call sys_xxx.
-****************************************************************************/
-
-int wsys_creat(const smb_ucs2_t *wfname, mode_t mode)
-{
- pstring fname;
- return sys_creat(unicode_to_unix(fname,wfname,sizeof(fname)), mode);
-}
-
-/**************************************************************************
- Wide open. Just narrow and call sys_xxx.
-****************************************************************************/
-
-int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode)
-{
- pstring fname;
- return sys_open(unicode_to_unix(fname,wfname,sizeof(fname)), oflag, mode);
-}
-
-/**************************************************************************
- Wide fopen. Just narrow and call sys_xxx.
-****************************************************************************/
-
-FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type)
-{
- pstring fname;
- return sys_fopen(unicode_to_unix(fname,wfname,sizeof(fname)), type);
-}
-
-/**************************************************************************
- Wide opendir. Just narrow and call sys_xxx.
-****************************************************************************/
-
-DIR *wsys_opendir(const smb_ucs2_t *wfname)
-{
- pstring fname;
- return opendir(unicode_to_unix(fname,wfname,sizeof(fname)));
-}
-
-/**************************************************************************
- Wide readdir. Return a structure pointer containing a wide filename.
-****************************************************************************/
-
-SMB_STRUCT_WDIRENT *wsys_readdir(DIR *dirp)
-{
- static SMB_STRUCT_WDIRENT retval;
- SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp);
-
- if(!dirval)
- return NULL;
-
- /*
- * The only POSIX defined member of this struct is d_name.
- */
-
- unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name));
-
- return &retval;
-}
-
-/**************************************************************************
- Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
-****************************************************************************/
-
-smb_ucs2_t *wsys_getwd(smb_ucs2_t *s)
-{
- pstring fname;
- char *p = sys_getwd(fname);
-
- if(!p)
- return NULL;
-
- return unix_to_unicode(s, p, sizeof(wpstring));
-}
-
-/**************************************************************************
- Wide chown. Just narrow and call sys_xxx.
-****************************************************************************/
-
-int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid)
-{
- pstring fname;
- return chown(unicode_to_unix(fname,wfname,sizeof(fname)), uid, gid);
-}
-
-/**************************************************************************
- Wide chroot. Just narrow and call sys_xxx.
-****************************************************************************/
-
-int wsys_chroot(const smb_ucs2_t *wfname)
-{
- pstring fname;
- return chroot(unicode_to_unix(fname,wfname,sizeof(fname)));
-}
-
-/**************************************************************************
- Wide getpwnam. Return a structure pointer containing wide names.
-****************************************************************************/
-
-SMB_STRUCT_WPASSWD *wsys_getpwnam(const smb_ucs2_t *wname)
-{
- static SMB_STRUCT_WPASSWD retval;
- fstring name;
- struct passwd *pwret = sys_getpwnam(unicode_to_unix(name,wname,sizeof(name)));
-
- if(!pwret)
- return NULL;
-
- unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
- retval.pw_passwd = pwret->pw_passwd;
- retval.pw_uid = pwret->pw_uid;
- retval.pw_gid = pwret->pw_gid;
- unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
- unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
- unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
-
- return &retval;
-}
-
-/**************************************************************************
- Wide getpwuid. Return a structure pointer containing wide names.
-****************************************************************************/
-
-SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid)
-{
- static SMB_STRUCT_WPASSWD retval;
- struct passwd *pwret = sys_getpwuid(uid);
-
- if(!pwret)
- return NULL;
-
- unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
- retval.pw_passwd = pwret->pw_passwd;
- retval.pw_uid = pwret->pw_uid;
- retval.pw_gid = pwret->pw_gid;
- unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
- unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
- unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
-
- return &retval;
-}
-
-/**************************************************************************
Extract a command into an arg list. Uses a static pstring for storage.
Caller frees returned arg list (which contains pointers into the static pstring).
****************************************************************************/
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 2e2c887b93..a8ef69e559 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -195,21 +195,6 @@ BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf)
}
/*******************************************************************
- rename a unix file
-********************************************************************/
-int file_rename(char *from, char *to)
-{
- int rcode = rename (from, to);
-
- if (errno == EXDEV)
- {
- /* Rename across filesystems needed. */
- rcode = copy_reg (from, to);
- }
- return rcode;
-}
-
-/*******************************************************************
check a files mod time
********************************************************************/
time_t file_modtime(char *fname)
@@ -790,7 +775,7 @@ BOOL is_ipaddress(const char *str)
interpret an internet address or name into an IP address in 4 byte form
****************************************************************************/
-uint32 interpret_addr(char *str)
+uint32 interpret_addr(const char *str)
{
struct hostent *hp;
uint32 res;
@@ -823,7 +808,7 @@ uint32 interpret_addr(char *str)
/*******************************************************************
a convenient addition to interpret_addr()
******************************************************************/
-struct in_addr *interpret_addr2(char *str)
+struct in_addr *interpret_addr2(const char *str)
{
static struct in_addr ret;
uint32 a = interpret_addr(str);
diff --git a/source3/lib/util_file.c b/source3/lib/util_file.c
index 4e2adc97bc..7dc25a8dae 100644
--- a/source3/lib/util_file.c
+++ b/source3/lib/util_file.c
@@ -417,7 +417,7 @@ char *file_load(char *fname, size_t *size)
/****************************************************************************
parse a buffer into lines
****************************************************************************/
-static char **file_lines_parse(char *p, size_t size, int *numlines, BOOL convert)
+static char **file_lines_parse(char *p, size_t size, int *numlines)
{
int i;
char *s, **ret;
@@ -446,21 +446,15 @@ static char **file_lines_parse(char *p, size_t size, int *numlines, BOOL convert
if (s[0] == '\r') s[0] = 0;
}
- if (convert) {
- for (i = 0; ret[i]; i++)
- unix_to_dos(ret[i], True);
- }
-
return ret;
}
/****************************************************************************
load a file into memory and return an array of pointers to lines in the file
-must be freed with file_lines_free(). If convert is true calls unix_to_dos on
-the list.
+must be freed with file_lines_free().
****************************************************************************/
-char **file_lines_load(char *fname, int *numlines, BOOL convert)
+char **file_lines_load(char *fname, int *numlines)
{
char *p;
size_t size;
@@ -468,7 +462,7 @@ char **file_lines_load(char *fname, int *numlines, BOOL convert)
p = file_load(fname, &size);
if (!p) return NULL;
- return file_lines_parse(p, size, numlines, convert);
+ return file_lines_parse(p, size, numlines);
}
/****************************************************************************
@@ -476,7 +470,7 @@ load a fd into memory and return an array of pointers to lines in the file
must be freed with file_lines_free(). If convert is true calls unix_to_dos on
the list.
****************************************************************************/
-char **fd_lines_load(int fd, int *numlines, BOOL convert)
+char **fd_lines_load(int fd, int *numlines)
{
char *p;
size_t size;
@@ -484,16 +478,15 @@ char **fd_lines_load(int fd, int *numlines, BOOL convert)
p = fd_load(fd, &size);
if (!p) return NULL;
- return file_lines_parse(p, size, numlines, convert);
+ return file_lines_parse(p, size, numlines);
}
/****************************************************************************
load a pipe into memory and return an array of pointers to lines in the data
-must be freed with file_lines_free(). If convert is true calls unix_to_dos on
-the list.
+must be freed with file_lines_free().
****************************************************************************/
-char **file_lines_pload(char *syscmd, int *numlines, BOOL convert)
+char **file_lines_pload(char *syscmd, int *numlines)
{
char *p;
size_t size;
@@ -501,7 +494,7 @@ char **file_lines_pload(char *syscmd, int *numlines, BOOL convert)
p = file_pload(syscmd, &size);
if (!p) return NULL;
- return file_lines_parse(p, size, numlines, convert);
+ return file_lines_parse(p, size, numlines);
}
/****************************************************************************
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c
index d52ff82b10..8ff3e23443 100644
--- a/source3/lib/util_str.c
+++ b/source3/lib/util_str.c
@@ -1,8 +1,8 @@
/*
Unix SMB/Netbios implementation.
- Version 1.9.
+ Version 3.0
Samba utility functions
- Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Andrew Tridgell 1992-2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -83,6 +83,8 @@ BOOL next_token_nr(char **ptr,char *buff,char *sep, size_t bufsize)
return ret;
}
+static uint16 tmpbuf[sizeof(pstring)];
+
void set_first_token(char *ptr)
{
last_ptr = ptr;
@@ -126,78 +128,15 @@ char **toktocliplist(int *ctok, char *sep)
return ret;
}
-
/*******************************************************************
case insensitive string compararison
********************************************************************/
int StrCaseCmp(const char *s, const char *t)
{
- /* compare until we run out of string, either t or s, or find a difference */
- /* We *must* use toupper rather than tolower here due to the
- 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. */
- int diff;
- for (;;)
- {
- if (!*s || !*t)
- return toupper (*s) - toupper (*t);
- else if (is_sj_alph (*s) && is_sj_alph (*t))
- {
- diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
- if (diff)
- return diff;
- s += 2;
- t += 2;
- }
- else if (is_shift_jis (*s) && is_shift_jis (*t))
- {
- diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
- if (diff)
- return diff;
- diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
- if (diff)
- return diff;
- s += 2;
- t += 2;
- }
- else if (is_shift_jis (*s))
- return 1;
- else if (is_shift_jis (*t))
- return -1;
- else
- {
- diff = toupper (*s) - toupper (*t);
- if (diff)
- return diff;
- s++;
- t++;
- }
- }
- }
- else
-#endif /* KANJI_WIN95_COMPATIBILITY */
- {
- while (*s && *t && toupper(*s) == toupper(*t))
- {
- s++;
- t++;
- }
-
- return(toupper(*s) - toupper(*t));
- }
+ pstring buf1, buf2;
+ unix_strlower(s, strlen(s)+1, buf1, sizeof(buf1));
+ unix_strlower(t, strlen(t)+1, buf2, sizeof(buf2));
+ return strcmp(buf1,buf2);
}
/*******************************************************************
@@ -205,83 +144,10 @@ int StrCaseCmp(const char *s, const char *t)
********************************************************************/
int StrnCaseCmp(const char *s, const char *t, size_t n)
{
- /* compare until we run out of string, either t or s, or chars */
- /* We *must* use toupper rather than tolower here due to the
- 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. */
- int diff;
- for (;n > 0;)
- {
- if (!*s || !*t)
- return toupper (*s) - toupper (*t);
- else if (is_sj_alph (*s) && is_sj_alph (*t))
- {
- diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
- if (diff)
- return diff;
- s += 2;
- t += 2;
- n -= 2;
- }
- else if (is_shift_jis (*s) && is_shift_jis (*t))
- {
- diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
- if (diff)
- return diff;
- diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
- if (diff)
- return diff;
- s += 2;
- t += 2;
- n -= 2;
- }
- else if (is_shift_jis (*s))
- return 1;
- else if (is_shift_jis (*t))
- return -1;
- else
- {
- diff = toupper (*s) - toupper (*t);
- if (diff)
- return diff;
- s++;
- t++;
- n--;
- }
- }
- return 0;
- }
- else
-#endif /* KANJI_WIN95_COMPATIBILITY */
- {
- while (n && *s && *t && toupper(*s) == toupper(*t))
- {
- s++;
- t++;
- n--;
- }
-
- /* not run out of chars - strings are different lengths */
- if (n)
- return(toupper(*s) - toupper(*t));
-
- /* identical up to where we run out of chars,
- and strings are same length */
- return(0);
- }
+ pstring buf1, buf2;
+ unix_strlower(s, strlen(s)+1, buf1, sizeof(buf1));
+ unix_strlower(t, strlen(t)+1, buf2, sizeof(buf2));
+ return strncmp(buf1,buf2,n);
}
/*******************************************************************
@@ -349,112 +215,6 @@ int strwicmp(char *psz1, char *psz2)
/*******************************************************************
- convert a string to lower case
-********************************************************************/
-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. */
- if (is_shift_jis (*s))
- {
- if (is_sj_upper (s[0], s[1]))
- s[1] = sj_tolower2 (s[1]);
- s += 2;
- }
- else if (is_kana (*s))
- {
- s++;
- }
- else
- {
- if (isupper(*s))
- *s = tolower(*s);
- s++;
- }
- }
- else
-#endif /* KANJI_WIN95_COMPATIBILITY */
- {
- size_t skip = get_character_len( *s );
- if( skip != 0 )
- s += skip;
- else
- {
- if (isupper(*s))
- *s = tolower(*s);
- s++;
- }
- }
- }
-}
-
-/*******************************************************************
- convert a string to upper case
-********************************************************************/
-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. */
- if (is_shift_jis (*s))
- {
- if (is_sj_lower (s[0], s[1]))
- s[1] = sj_toupper2 (s[1]);
- s += 2;
- }
- else if (is_kana (*s))
- {
- s++;
- }
- else
- {
- if (islower(*s))
- *s = toupper(*s);
- s++;
- }
- }
- else
-#endif /* KANJI_WIN95_COMPATIBILITY */
- {
- size_t skip = get_character_len( *s );
- if( skip != 0 )
- s += skip;
- else
- {
- if (islower(*s))
- *s = toupper(*s);
- s++;
- }
- }
- }
-}
-
-/*******************************************************************
convert a string to "normal" form
********************************************************************/
void strnorm(char *s)
@@ -471,44 +231,26 @@ check if a string is in "normal" case
********************************************************************/
BOOL strisnormal(char *s)
{
- extern int case_default;
- if (case_default == CASE_UPPER)
- return(!strhaslower(s));
-
- return(!strhasupper(s));
+ extern int case_default;
+ if (case_default == CASE_UPPER)
+ return(!strhaslower(s));
+
+ return(!strhasupper(s));
}
/****************************************************************************
string replace
+ NOTE: oldc and newc must be 7 bit characters
****************************************************************************/
void string_replace(char *s,char oldc,char newc)
{
- size_t skip;
-
- /*
- * sbcs optimization.
- */
- if(!global_is_multibyte_codepage) {
- while (*s) {
- if (oldc == *s)
- *s = newc;
- s++;
- }
- } else {
- while (*s)
- {
- skip = get_character_len( *s );
- if( skip != 0 )
- s += skip;
- else
- {
- if (oldc == *s)
- *s = newc;
- s++;
- }
- }
- }
+ smb_ucs2_t *ptr;
+ push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
+ for(ptr=tmpbuf;*ptr;ptr++) {
+ if(*ptr==UCS2_CHAR(oldc)) *ptr = UCS2_CHAR(newc);
+ }
+ pull_ucs2(NULL, s, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
}
@@ -517,35 +259,20 @@ skip past some strings in a buffer
********************************************************************/
char *skip_string(char *buf,size_t n)
{
- while (n--)
- buf += strlen(buf) + 1;
- return(buf);
+ while (n--)
+ buf += strlen(buf) + 1;
+ return(buf);
}
/*******************************************************************
Count the number of characters in a string. Normally this will
be the same as the number of bytes in a string for single byte strings,
but will be different for multibyte.
- 16.oct.98, jdblair@cobaltnet.com.
********************************************************************/
-
size_t str_charnum(const char *s)
{
- size_t len = 0;
-
- /*
- * sbcs optimization.
- */
- if(!global_is_multibyte_codepage) {
- return strlen(s);
- } else {
- while (*s != '\0') {
- int skip = get_character_len(*s);
- s += (skip ? skip : 1);
- len++;
- }
- }
- return len;
+ push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
+ return strlen_w(tmpbuf);
}
/*******************************************************************
@@ -554,110 +281,36 @@ trim the specified elements off the front and back of a string
BOOL trim_string(char *s,const char *front,const char *back)
{
- BOOL ret = False;
- size_t s_len;
- size_t front_len;
- size_t back_len;
- char *sP;
+ BOOL ret = False;
+ size_t front_len;
+ size_t back_len;
+ size_t len;
/* Ignore null or empty strings. */
+ if (!s || (s[0] == '\0'))
+ return False;
- if ( !s || (s[0] == '\0'))
- return False;
-
- sP = s;
- s_len = strlen( s ) + 1;
- front_len = (front) ? strlen( front ) + 1 : 0;
- back_len = (back) ? strlen( back ) + 1 : 0;
-
- /*
- * remove "front" string from given "s", if it matches front part,
- * repeatedly.
- */
- if ( front && front_len > 1 ) {
- while (( s_len >= front_len )&&
- ( memcmp( sP, front, front_len - 1 )) == 0 ) {
- ret = True;
- sP += ( front_len - 1 );
- s_len -= ( front_len - 1 );
- }
- }
+ front_len = front? strlen(front) : 0;
+ back_len = back? strlen(back) : 0;
- /*
- * we'll memmove sP to s later, after we're done with
- * back part removal, for minimizing copy.
- */
-
-
- /*
- * We split out the multibyte code page
- * case here for speed purposes. Under a
- * multibyte code page we need to walk the
- * string forwards only and multiple times.
- * Thanks to John Blair for finding this
- * one. JRA.
- */
- /*
- * This JRA's comment is partly correct, but partly wrong.
- * You can always check from "end" part, and if it did not match,
- * it means there is no possibility of finding one.
- * If you found matching point, mark them, then look from front
- * if marking point suits multi-byte string rule.
- * Kenichi Okuyama.
- */
-
- if ( back && back_len > 1 && s_len >= back_len) {
- char *bP = sP + s_len - back_len;
- long b_len = s_len;
-
- while (( b_len >= back_len )&&
- ( memcmp( bP, back, back_len - 1 ) == 0 )) {
- bP -= ( back_len - 1 );
- b_len -= ( back_len - 1 );
- }
+ len = strlen(s);
- /*
- * You're here, means you ether have found match multiple times,
- * or you found none. If you've found match, then bP should be
- * moving.
- */
- if ( bP != sP + s_len - back_len ) {
- bP += ( back_len - 1 ); /* slide bP to first matching point. */
-
- if( !global_is_multibyte_codepage ) {
- /* simply terminate */
- (*bP) = '\0';
- s_len = b_len;
- ret = True;
- } else {
- /* trace string from start. */
- char *cP = sP;
- while ( cP < sP + s_len - back_len ) {
- size_t skip;
- skip = skip_multibyte_char( *cP );
- cP += ( skip ? skip : 1 );
- if ( cP == bP ) {
- /* you found the match */
- (*bP) = '\0';
- ret = True;
- s_len = b_len;
- break;
- }
- while (( cP > bP )&&( bP < sP + s_len - back_len )) {
- bP += ( back_len - 1 );
- b_len += ( back_len - 1 );
- }
- }
- }
- }
- }
-
- /* if front found matching point */
- if ( sP != s ) {
- /* slide string to buffer top */
- memmove( s, sP, s_len );
- }
- return ret;
+ if (front_len) {
+ while (len && strncmp(s, front, front_len)==0) {
+ memcpy(s, s+front_len, (len-front_len)+1);
+ len -= front_len;
+ ret=True;
+ }
+ }
+
+ if (back_len) {
+ while (strncmp(s+len-back_len,back,back_len)==0) {
+ s[len-back_len]='\0';
+ len -= back_len;
+ ret=True;
+ }
+ }
+ return ret;
}
@@ -666,46 +319,11 @@ does a string have any uppercase chars in it?
****************************************************************************/
BOOL strhasupper(const 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. */
- if (is_shift_jis (*s))
- s += 2;
- else if (is_kana (*s))
- s++;
- else
- {
- if (isupper(*s))
- return(True);
- s++;
- }
- }
- else
-#endif /* KANJI_WIN95_COMPATIBILITY */
- {
- size_t skip = get_character_len( *s );
- if( skip != 0 )
- s += skip;
- else {
- if (isupper(*s))
- return(True);
- s++;
- }
- }
- }
- return(False);
+ smb_ucs2_t *ptr;
+ push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
+ for(ptr=tmpbuf;*ptr;ptr++)
+ if(isupper_w(*ptr)) return True;
+ return(False);
}
/****************************************************************************
@@ -713,104 +331,23 @@ does a string have any lowercase chars in it?
****************************************************************************/
BOOL strhaslower(const 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. */
- if (is_shift_jis (*s))
- {
- if (is_sj_upper (s[0], s[1]))
- return(True);
- if (is_sj_lower (s[0], s[1]))
- return (True);
- s += 2;
- }
- else if (is_kana (*s))
- {
- s++;
- }
- else
- {
- if (islower(*s))
- return(True);
- s++;
- }
- }
- else
-#endif /* KANJI_WIN95_COMPATIBILITY */
- {
- size_t skip = get_character_len( *s );
- if( skip != 0 )
- s += skip;
- else {
- if (islower(*s))
- return(True);
- s++;
- }
- }
- }
- return(False);
+ smb_ucs2_t *ptr;
+ push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
+ for(ptr=tmpbuf;*ptr;ptr++)
+ if(islower_w(*ptr)) return True;
+ return(False);
}
/****************************************************************************
-find the number of chars in a string
+find the number of 'c' chars in a string
****************************************************************************/
size_t count_chars(const char *s,char c)
{
- size_t 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. */
- while (*s)
- {
- if (is_shift_jis (*s))
- s += 2;
- else
- {
- if (*s == c)
- count++;
- s++;
- }
- }
- }
- else
-#endif /* KANJI_WIN95_COMPATIBILITY */
- {
- while (*s)
- {
- size_t skip = get_character_len( *s );
- if( skip != 0 )
- s += skip;
- else {
- if (*s == c)
- count++;
- s++;
- }
- }
- }
- return(count);
+ smb_ucs2_t *ptr;
+ int count;
+ push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
+ for(count=0,ptr=tmpbuf;*ptr;ptr++) if(*ptr==UCS2_CHAR(c)) count++;
+ return(count);
}
/*******************************************************************
@@ -819,52 +356,15 @@ Return True if a string consists only of one particular character.
BOOL str_is_all(const char *s,char c)
{
- if(s == NULL)
- return False;
- if(!*s)
- return False;
-
-#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. */
- while (*s)
- {
- if (is_shift_jis (*s))
- s += 2;
- else
- {
- if (*s != c)
- return False;
- s++;
- }
- }
- }
- else
-#endif /* KANJI_WIN95_COMPATIBILITY */
- {
- while (*s)
- {
- size_t skip = get_character_len( *s );
- if( skip != 0 )
- s += skip;
- else {
- if (*s != c)
- return False;
- s++;
- }
- }
- }
- return True;
+ smb_ucs2_t *ptr;
+
+ if(s == NULL) return False;
+ if(!*s) return False;
+
+ push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
+ for(ptr=tmpbuf;*ptr;ptr++) if(*ptr!=UCS2_CHAR(c)) return False;
+
+ return True;
}
/*******************************************************************
@@ -874,29 +374,29 @@ include the terminating zero.
char *safe_strcpy(char *dest,const char *src, size_t maxlength)
{
- size_t len;
+ size_t len;
- if (!dest) {
- DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
- return NULL;
- }
+ if (!dest) {
+ DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
+ return NULL;
+ }
- if (!src) {
- *dest = 0;
- return dest;
- }
+ if (!src) {
+ *dest = 0;
+ return dest;
+ }
- len = strlen(src);
+ len = strlen(src);
- if (len > maxlength) {
- DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
- (int)(len-maxlength), src));
- len = maxlength;
- }
+ if (len > maxlength) {
+ DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
+ (int)(len-maxlength), src));
+ len = maxlength;
+ }
- memmove(dest, src, len);
- dest[len] = 0;
- return dest;
+ memmove(dest, src, len);
+ dest[len] = 0;
+ return dest;
}
/*******************************************************************
@@ -906,29 +406,29 @@ include the terminating zero.
char *safe_strcat(char *dest, const char *src, size_t maxlength)
{
- size_t src_len, dest_len;
+ size_t src_len, dest_len;
- if (!dest) {
- DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
- return NULL;
- }
-
- if (!src) {
- return dest;
- }
-
- src_len = strlen(src);
- dest_len = strlen(dest);
+ if (!dest) {
+ DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
+ return NULL;
+ }
- if (src_len + dest_len > maxlength) {
- DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
- (int)(src_len + dest_len - maxlength), src));
- src_len = maxlength - dest_len;
- }
-
- memcpy(&dest[dest_len], src, src_len);
- dest[dest_len + src_len] = 0;
- return dest;
+ if (!src) {
+ return dest;
+ }
+
+ src_len = strlen(src);
+ dest_len = strlen(dest);
+
+ if (src_len + dest_len > maxlength) {
+ DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
+ (int)(src_len + dest_len - maxlength), src));
+ src_len = maxlength - dest_len;
+ }
+
+ memcpy(&dest[dest_len], src, src_len);
+ dest[dest_len + src_len] = 0;
+ return dest;
}
/*******************************************************************
@@ -979,15 +479,15 @@ char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, si
char *StrnCpy(char *dest,const char *src,size_t n)
{
- char *d = dest;
- if (!dest) return(NULL);
- if (!src) {
- *dest = 0;
- return(dest);
- }
- while (n-- && (*d++ = *src++)) ;
- *d = 0;
- return(dest);
+ char *d = dest;
+ if (!dest) return(NULL);
+ if (!src) {
+ *dest = 0;
+ return(dest);
+ }
+ while (n-- && (*d++ = *src++)) ;
+ *d = 0;
+ return(dest);
}
/****************************************************************************
@@ -1303,3 +803,57 @@ char *string_truncate(char *s, int length)
}
return s;
}
+
+
+/****************************************************************************
+strchr and strrchr are very hard to do on general multi-byte strings.
+we convert via ucs2 for now
+****************************************************************************/
+char *strchr_m(const char *s, char c)
+{
+ wpstring ws;
+ pstring s2;
+ smb_ucs2_t *p;
+
+ push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
+ p = strchr_wa(ws, c);
+ if (!p) return NULL;
+ *p = 0;
+ pull_ucs2_pstring(s2, ws);
+ return (char *)(s+strlen(s2));
+}
+
+char *strrchr_m(const char *s, char c)
+{
+ wpstring ws;
+ pstring s2;
+ smb_ucs2_t *p;
+
+ push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
+ p = strrchr_wa(ws, c);
+ if (!p) return NULL;
+ *p = 0;
+ pull_ucs2_pstring(s2, ws);
+ return (char *)(s+strlen(s2));
+}
+
+/*******************************************************************
+ convert a string to lower case
+********************************************************************/
+void strlower_m(char *s)
+{
+ /* I assume that lowercased string takes the same number of bytes
+ * as source string even in UTF-8 encoding. (VIV) */
+ unix_strlower(s,strlen(s)+1,s,strlen(s)+1);
+}
+
+/*******************************************************************
+ convert a string to upper case
+********************************************************************/
+void strupper_m(char *s)
+{
+ /* I assume that lowercased string takes the same number of bytes
+ * as source string even in multibyte encoding. (VIV) */
+ unix_strupper(s,strlen(s)+1,s,strlen(s)+1);
+}
+
diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c
index 96aa62a283..1bfcd179f4 100644
--- a/source3/lib/util_unistr.c
+++ b/source3/lib/util_unistr.c
@@ -1,8 +1,8 @@
/*
Unix SMB/Netbios implementation.
- Version 1.9.
+ Version 3.0
Samba utility functions
- Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Andrew Tridgell 1992-2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -31,11 +31,7 @@ extern int DEBUGLEVEL;
* These are dynamically loaded from a unicode translation file.
*/
-static smb_ucs2_t *doscp_to_ucs2;
-static uint16 *ucs2_to_doscp;
-
-static smb_ucs2_t *unixcp_to_ucs2;
-static uint16 *ucs2_to_unixcp;
+#define CONV_DEBUGLEVEL 83
#ifndef MAXUNI
#define MAXUNI 1024
@@ -54,62 +50,10 @@ static uint16 *ucs2_to_unixcp;
size_t dos_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate)
{
- size_t ret = 0;
- while (*src && (len >= 2)) {
- size_t skip = get_character_len(*src);
- smb_ucs2_t val = (*src & 0xff);
-
- /*
- * If this is a multibyte character (and all DOS/Windows
- * codepages have at maximum 2 byte multibyte characters)
- * then work out the index value for the unicode conversion.
- */
-
- if (skip == 2)
- val = ((val << 8) | (src[1] & 0xff));
-
- SSVAL(dst,ret,doscp_to_ucs2[val]);
- ret += 2;
- len -= 2;
- if (skip)
- src += skip;
- else
- src++;
- }
- if (null_terminate) {
- SSVAL(dst,ret,0);
- ret += 2;
- }
- return(ret);
+ return push_ucs2(NULL, dst, src, len,
+ STR_UNICODE|STR_NOALIGN | (null_terminate?STR_TERMINATE:0));
}
-/*******************************************************************
- Pull a DOS codepage string out of a UNICODE array. len is in bytes.
-********************************************************************/
-
-void unistr_to_dos(char *dest, const char *src, size_t len)
-{
- char *destend = dest + len;
-
- while (dest < destend) {
- uint16 ucs2_val = SVAL(src,0);
- uint16 cp_val = ucs2_to_doscp[ucs2_val];
-
- src += 2;
-
- if (ucs2_val == 0)
- break;
-
- if (cp_val < 256)
- *dest++ = (char)cp_val;
- else {
- *dest++ = (cp_val >> 8) & 0xff;
- *dest++ = (cp_val & 0xff);
- }
- }
-
- *dest = 0;
-}
/*******************************************************************
Skip past a unicode string, but not more than len. Always move
@@ -129,183 +73,48 @@ char *skip_unibuf(char *src, size_t len)
return src;
}
+/* Copy a string from little-endian or big-endian unicode source (depending
+ * on flags) to internal samba format destination
+ */
+int rpcstr_pull(char* dest, void *src, int dest_len, int src_len, int flags)
+{
+ if(dest_len==-1) dest_len=MAXUNI-3;
+ return pull_ucs2(NULL, dest, src, dest_len, src_len, flags|STR_UNICODE|STR_NOALIGN);
+}
+
+/* Converts a string from internal samba format to unicode
+ */
+int rpcstr_push(void* dest, const char *src, int dest_len, int flags)
+{
+ return push_ucs2(NULL, dest, src, dest_len, flags|STR_UNICODE|STR_NOALIGN);
+}
+
/*******************************************************************
Return a DOS codepage version of a little-endian unicode string.
len is the filename length (ignoring any terminating zero) in uin16
units. Always null terminates.
Hack alert: uses fixed buffer(s).
********************************************************************/
-
char *dos_unistrn2(uint16 *src, int len)
{
static char lbufs[8][MAXUNI];
static int nexti;
char *lbuf = lbufs[nexti];
- char *p;
-
nexti = (nexti+1)%8;
-
- for (p = lbuf; (len > 0) && (p-lbuf < MAXUNI-3) && *src; len--, src++) {
- uint16 ucs2_val = SVAL(src,0);
- uint16 cp_val = ucs2_to_doscp[ucs2_val];
-
- if (cp_val < 256)
- *p++ = (char)cp_val;
- else {
- *p++ = (cp_val >> 8) & 0xff;
- *p++ = (cp_val & 0xff);
- }
- }
-
- *p = 0;
+ pull_ucs2(NULL, lbuf, src, MAXUNI-3, len*2, STR_NOALIGN);
return lbuf;
}
-static char lbufs[8][MAXUNI];
-static int nexti;
-
-/*******************************************************************
- Return a DOS codepage version of a little-endian unicode string.
- Hack alert: uses fixed buffer(s).
-********************************************************************/
-
-char *dos_unistr2(uint16 *src)
-{
- char *lbuf = lbufs[nexti];
- char *p;
-
- nexti = (nexti+1)%8;
-
- for (p = lbuf; (p-lbuf < MAXUNI-3) && *src; src++) {
- uint16 ucs2_val = SVAL(src,0);
- uint16 cp_val = ucs2_to_doscp[ucs2_val];
-
- if (cp_val < 256)
- *p++ = (char)cp_val;
- else {
- *p++ = (cp_val >> 8) & 0xff;
- *p++ = (cp_val & 0xff);
- }
- }
-
- *p = 0;
- return lbuf;
-}
-
-/*******************************************************************
-Return a DOS codepage version of a little-endian unicode string
-********************************************************************/
-
-char *dos_unistr2_to_str(UNISTR2 *str)
-{
- char *lbuf = lbufs[nexti];
- char *p;
- uint16 *src = str->buffer;
-
- nexti = (nexti+1)%8;
-
- for (p = lbuf; (p - lbuf < MAXUNI-3) && (src - str->buffer < str->uni_str_len) && *src; src++) {
- uint16 ucs2_val = SVAL(src,0);
- uint16 cp_val = ucs2_to_doscp[ucs2_val];
-
- if (cp_val < 256)
- *p++ = (char)cp_val;
- else {
- *p++ = (cp_val >> 8) & 0xff;
- *p++ = (cp_val & 0xff);
- }
- }
-
- *p = 0;
- return lbuf;
-}
-
-/*******************************************************************
- Put an ASCII string into a UNICODE array (uint16's).
- use little-endian ucs2
- ********************************************************************/
-void ascii_to_unistr(uint16 *dest, const char *src, int maxlen)
-{
- uint16 *destend = dest + maxlen;
- char c;
-
- while (dest < destend) {
- c = *(src++);
- if (c == 0)
- break;
-
- SSVAL(dest, 0, c);
- dest++;
- }
-
- *dest = 0;
-}
-
-/*******************************************************************
- Pull an ASCII string out of a UNICODE array (uint16's).
- ********************************************************************/
-
-void unistr_to_ascii(char *dest, const uint16 *src, int len)
-{
- char *destend = dest + len;
- uint16 c;
-
- if (src == NULL) {
- *dest = '\0';
- return;
- }
-
- /* normal code path for a valid 'src' */
- while (dest < destend) {
- c = SVAL(src, 0);
- src++;
- if (c == 0)
- break;
-
- *(dest++) = (char)c;
- }
-
- *dest = 0;
- return;
-}
-
/*******************************************************************
Convert a (little-endian) UNISTR2 structure to an ASCII string
- Warning: this version does DOS codepage.
********************************************************************/
-
void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
{
- char *p;
- uint16 *src;
- size_t len;
-
if (str == NULL) {
*dest='\0';
return;
}
-
- src = str->buffer;
- len = MIN(str->uni_str_len, maxlen);
-
- if (len == 0) {
- *dest='\0';
- return;
- }
-
- for (p = dest; (p-dest < len) && *src; src++) {
- uint16 ucs2_val = SVAL(src,0);
- uint16 cp_val = ucs2_to_doscp[ucs2_val];
-
- if (cp_val < 256)
- *p++ = (char)cp_val;
- else {
- *p = (cp_val >> 8) & 0xff;
- *p++ = (cp_val & 0xff);
- }
- }
-
- *p = 0;
+ pull_ucs2(NULL, dest, str->buffer, maxlen, str->uni_str_len, STR_NOALIGN);
}
@@ -322,743 +131,6 @@ uint32 buffer2_to_uint32(BUFFER2 *str)
}
/*******************************************************************
-Return a DOS codepage version of a NOTunicode string
-********************************************************************/
-
-char *dos_buffer2_to_str(BUFFER2 *str)
-{
- char *lbuf = lbufs[nexti];
- char *p;
- uint16 *src = str->buffer;
-
- nexti = (nexti+1)%8;
-
- for (p = lbuf; (p - lbuf < sizeof(str->buffer)-3) && (src - str->buffer < str->buf_len/2) && *src; src++) {
- uint16 ucs2_val = SVAL(src,0);
- uint16 cp_val = ucs2_to_doscp[ucs2_val];
-
- if (cp_val < 256)
- *p++ = (char)cp_val;
- else {
- *p++ = (cp_val >> 8) & 0xff;
- *p++ = (cp_val & 0xff);
- }
- }
-
- *p = 0;
- return lbuf;
-}
-
-/*******************************************************************
- Return a dos codepage version of a NOTunicode string
-********************************************************************/
-
-char *dos_buffer2_to_multistr(BUFFER2 *str)
-{
- char *lbuf = lbufs[nexti];
- char *p;
- uint16 *src = str->buffer;
-
- nexti = (nexti+1)%8;
-
- for (p = lbuf; (p - lbuf < sizeof(str->buffer)-3) && (src - str->buffer < str->buf_len/2); src++) {
- if (*src == 0) {
- *p++ = ' ';
- } else {
- uint16 ucs2_val = SVAL(src,0);
- uint16 cp_val = ucs2_to_doscp[ucs2_val];
-
- if (cp_val < 256)
- *p++ = (char)cp_val;
- else {
- *p++ = (cp_val >> 8) & 0xff;
- *p++ = (cp_val & 0xff);
- }
- }
- }
-
- *p = 0;
- return lbuf;
-}
-
-/*******************************************************************
- Create a null-terminated unicode string from a null-terminated DOS
- codepage string.
- Return number of unicode chars copied, excluding the null character.
- Unicode strings created are in little-endian format.
-********************************************************************/
-
-size_t dos_struni2(char *dst, const char *src, size_t max_len)
-{
- size_t len = 0;
-
- if (dst == NULL)
- return 0;
-
- if (src != NULL) {
- for (; (len < max_len-2) && *src; len++, dst +=2) {
- size_t skip = get_character_len(*src);
- smb_ucs2_t val = (*src & 0xff);
-
- /*
- * If this is a multibyte character (and all DOS/Windows
- * codepages have at maximum 2 byte multibyte characters)
- * then work out the index value for the unicode conversion.
- */
-
- if (skip == 2)
- val = ((val << 8) | (src[1] & 0xff));
-
- SSVAL(dst,0,doscp_to_ucs2[val]);
- if (skip)
- src += skip;
- else
- src++;
- }
- }
-
- SSVAL(dst,0,0);
-
- return len;
-}
-
-/*******************************************************************
- Return a DOS codepage version of a little-endian unicode string.
- Hack alert: uses fixed buffer(s).
-********************************************************************/
-
-char *dos_unistr(char *buf)
-{
- char *lbuf = lbufs[nexti];
- uint16 *src = (uint16 *)buf;
- char *p;
-
- nexti = (nexti+1)%8;
-
- for (p = lbuf; (p-lbuf < MAXUNI-3) && *src; src++) {
- uint16 ucs2_val = SVAL(src,0);
- uint16 cp_val = ucs2_to_doscp[ucs2_val];
-
- if (cp_val < 256)
- *p++ = (char)cp_val;
- else {
- *p++ = (cp_val >> 8) & 0xff;
- *p++ = (cp_val & 0xff);
- }
- }
-
- *p = 0;
- return lbuf;
-}
-
-/*******************************************************************
- Strcpy for unicode strings. returns length (in num of wide chars)
-********************************************************************/
-
-int unistrcpy(char *dst, char *src)
-{
- int num_wchars = 0;
- uint16 *wsrc = (uint16 *)src;
- uint16 *wdst = (uint16 *)dst;
-
- while (*wsrc) {
- *wdst++ = *wsrc++;
- num_wchars++;
- }
- *wdst = 0;
-
- return num_wchars;
-}
-
-/*******************************************************************
- Free any existing maps.
-********************************************************************/
-
-static void free_maps(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
-{
- /* this handles identity mappings where we share the pointer */
- if (*pp_ucs2_to_cp == *pp_cp_to_ucs2) {
- *pp_ucs2_to_cp = NULL;
- }
-
- if (*pp_cp_to_ucs2) {
- free(*pp_cp_to_ucs2);
- *pp_cp_to_ucs2 = NULL;
- }
-
- if (*pp_ucs2_to_cp) {
- free(*pp_ucs2_to_cp);
- *pp_ucs2_to_cp = NULL;
- }
-}
-
-/*******************************************************************
- Build a default (null) codepage to unicode map.
-********************************************************************/
-
-void default_unicode_map(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
-{
- int i;
-
- free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
-
- if ((*pp_ucs2_to_cp = (uint16 *)malloc(2*65536)) == NULL) {
- DEBUG(0,("default_unicode_map: malloc fail for ucs2_to_cp size %u.\n", 2*65536));
- abort();
- }
-
- *pp_cp_to_ucs2 = *pp_ucs2_to_cp; /* Default map is an identity. */
- for (i = 0; i < 65536; i++)
- (*pp_cp_to_ucs2)[i] = i;
-}
-
-/*******************************************************************
- Load a codepage to unicode and vica-versa map.
-********************************************************************/
-
-BOOL load_unicode_map(const char *codepage, smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
-{
- pstring unicode_map_file_name;
- FILE *fp = NULL;
- SMB_STRUCT_STAT st;
- smb_ucs2_t *cp_to_ucs2 = *pp_cp_to_ucs2;
- uint16 *ucs2_to_cp = *pp_ucs2_to_cp;
- size_t cp_to_ucs2_size;
- size_t ucs2_to_cp_size;
- size_t i;
- size_t size;
- char buf[UNICODE_MAP_HEADER_SIZE];
-
- DEBUG(5, ("load_unicode_map: loading unicode map for codepage %s.\n", codepage));
-
- if (*codepage == '\0')
- goto clean_and_exit;
-
- if(strlen(lp_codepagedir()) + 13 + strlen(codepage) >
- sizeof(unicode_map_file_name)) {
- DEBUG(0,("load_unicode_map: filename too long to load\n"));
- goto clean_and_exit;
- }
-
- pstrcpy(unicode_map_file_name, lp_codepagedir());
- pstrcat(unicode_map_file_name, "/");
- pstrcat(unicode_map_file_name, "unicode_map.");
- pstrcat(unicode_map_file_name, codepage);
-
- if(sys_stat(unicode_map_file_name,&st)!=0) {
- DEBUG(0,("load_unicode_map: filename %s does not exist.\n",
- unicode_map_file_name));
- goto clean_and_exit;
- }
-
- size = st.st_size;
-
- if ((size != UNICODE_MAP_HEADER_SIZE + 4*65536) && (size != UNICODE_MAP_HEADER_SIZE +(2*256 + 2*65536))) {
- DEBUG(0,("load_unicode_map: file %s is an incorrect size for a \
-unicode map file (size=%d).\n", unicode_map_file_name, (int)size));
- goto clean_and_exit;
- }
-
- if((fp = sys_fopen( unicode_map_file_name, "r")) == NULL) {
- DEBUG(0,("load_unicode_map: cannot open file %s. Error was %s\n",
- unicode_map_file_name, strerror(errno)));
- goto clean_and_exit;
- }
-
- if(fread( buf, 1, UNICODE_MAP_HEADER_SIZE, fp)!=UNICODE_MAP_HEADER_SIZE) {
- DEBUG(0,("load_unicode_map: cannot read header from file %s. Error was %s\n",
- unicode_map_file_name, strerror(errno)));
- goto clean_and_exit;
- }
-
- /* Check the version value */
- if(SVAL(buf,UNICODE_MAP_VERSION_OFFSET) != UNICODE_MAP_FILE_VERSION_ID) {
- DEBUG(0,("load_unicode_map: filename %s has incorrect version id. \
-Needed %hu, got %hu.\n",
- unicode_map_file_name, (uint16)UNICODE_MAP_FILE_VERSION_ID,
- SVAL(buf,UNICODE_MAP_VERSION_OFFSET)));
- goto clean_and_exit;
- }
-
- /* Check the codepage value */
- if(!strequal(&buf[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET], codepage)) {
- DEBUG(0,("load_unicode_map: codepage %s in file %s is not the same as that \
-requested (%s).\n", &buf[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET], unicode_map_file_name, codepage ));
- goto clean_and_exit;
- }
-
- ucs2_to_cp_size = 2*65536;
- if (size == UNICODE_MAP_HEADER_SIZE + 4*65536) {
- /*
- * This is a multibyte code page.
- */
- cp_to_ucs2_size = 2*65536;
- } else {
- /*
- * Single byte code page.
- */
- cp_to_ucs2_size = 2*256;
- }
-
- /*
- * Free any old translation tables.
- */
-
- free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
-
- if ((cp_to_ucs2 = (smb_ucs2_t *)malloc(cp_to_ucs2_size)) == NULL) {
- DEBUG(0,("load_unicode_map: malloc fail for cp_to_ucs2 size %u.\n", cp_to_ucs2_size ));
- goto clean_and_exit;
- }
-
- if ((ucs2_to_cp = (uint16 *)malloc(ucs2_to_cp_size)) == NULL) {
- DEBUG(0,("load_unicode_map: malloc fail for ucs2_to_cp size %u.\n", ucs2_to_cp_size ));
- goto clean_and_exit;
- }
-
- if(fread( (char *)cp_to_ucs2, 1, cp_to_ucs2_size, fp)!=cp_to_ucs2_size) {
- DEBUG(0,("load_unicode_map: cannot read cp_to_ucs2 from file %s. Error was %s\n",
- unicode_map_file_name, strerror(errno)));
- goto clean_and_exit;
- }
-
- if(fread( (char *)ucs2_to_cp, 1, ucs2_to_cp_size, fp)!=ucs2_to_cp_size) {
- DEBUG(0,("load_unicode_map: cannot read ucs2_to_cp from file %s. Error was %s\n",
- unicode_map_file_name, strerror(errno)));
- goto clean_and_exit;
- }
-
- /*
- * Now ensure the 16 bit values are in the correct endianness.
- */
-
- for (i = 0; i < cp_to_ucs2_size/2; i++)
- cp_to_ucs2[i] = SVAL(cp_to_ucs2,i*2);
-
- for (i = 0; i < ucs2_to_cp_size/2; i++)
- ucs2_to_cp[i] = SVAL(ucs2_to_cp,i*2);
-
- fclose(fp);
-
- *pp_cp_to_ucs2 = cp_to_ucs2;
- *pp_ucs2_to_cp = ucs2_to_cp;
-
- return True;
-
-clean_and_exit:
-
- /* pseudo destructor :-) */
-
- if(fp != NULL)
- fclose(fp);
-
- free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
-
- default_unicode_map(pp_cp_to_ucs2, pp_ucs2_to_cp);
-
- return False;
-}
-
-/*******************************************************************
- Load a dos codepage to unicode and vica-versa map.
-********************************************************************/
-
-BOOL load_dos_unicode_map(int codepage)
-{
- fstring codepage_str;
-
- slprintf(codepage_str, sizeof(fstring)-1, "%03d", codepage);
- return load_unicode_map(codepage_str, &doscp_to_ucs2, &ucs2_to_doscp);
-}
-
-/*******************************************************************
- Load a UNIX codepage to unicode and vica-versa map.
-********************************************************************/
-
-BOOL load_unix_unicode_map(const char *unix_char_set)
-{
- fstring upper_unix_char_set;
-
- fstrcpy(upper_unix_char_set, unix_char_set);
- strupper(upper_unix_char_set);
- return load_unicode_map(upper_unix_char_set, &unixcp_to_ucs2, &ucs2_to_unixcp);
-}
-
-/*******************************************************************
- The following functions reproduce many of the non-UNICODE standard
- string functions in Samba.
-********************************************************************/
-
-/*******************************************************************
- Convert a UNICODE string to multibyte format. Note that the 'src' is in
- native byte order, not little endian. Always zero terminates.
- dst_len is in bytes.
-********************************************************************/
-
-static char *unicode_to_multibyte(char *dst, const smb_ucs2_t *src,
- size_t dst_len, const uint16 *ucs2_to_cp)
-{
- size_t dst_pos;
-
- for(dst_pos = 0; (dst_pos < dst_len - 1) && *src;) {
- smb_ucs2_t val = ucs2_to_cp[*src++];
- if(val < 256) {
- dst[dst_pos++] = (char)val;
- } else {
-
- if(dst_pos >= dst_len - 2)
- break;
-
- /*
- * A 2 byte value is always written as
- * high/low into the buffer stream.
- */
-
- dst[dst_pos++] = (char)((val >> 8) & 0xff);
- dst[dst_pos++] = (char)(val & 0xff);
- }
- }
-
- dst[dst_pos] = '\0';
-
- return dst;
-}
-
-/*******************************************************************
- Convert a multibyte string to UNICODE format. Note that the 'dst' is in
- native byte order, not little endian. Always zero terminates.
- dst_len is in bytes.
-********************************************************************/
-
-smb_ucs2_t *multibyte_to_unicode(smb_ucs2_t *dst, const char *src,
- size_t dst_len, smb_ucs2_t *cp_to_ucs2)
-{
- size_t i;
-
- dst_len /= sizeof(smb_ucs2_t); /* Convert to smb_ucs2_t units. */
-
- for(i = 0; (i < (dst_len - 1)) && src[i];) {
- size_t skip = skip_multibyte_char(*src);
- smb_ucs2_t val = (*src & 0xff);
-
- /*
- * If this is a multibyte character
- * then work out the index value for the unicode conversion.
- */
-
- if (skip == 2)
- val = ((val << 8) | (src[1] & 0xff));
-
- dst[i++] = cp_to_ucs2[val];
- if (skip)
- src += skip;
- else
- src++;
- }
-
- dst[i] = 0;
-
- return dst;
-}
-
-/*******************************************************************
- Convert a UNICODE string to multibyte format. Note that the 'src' is in
- native byte order, not little endian. Always zero terminates.
- This function may be replaced if the MB codepage format is an
- encoded one (ie. utf8, hex). See the code in lib/kanji.c
- for details. dst_len is in bytes.
-********************************************************************/
-
-char *unicode_to_unix(char *dst, const smb_ucs2_t *src, size_t dst_len)
-{
- return unicode_to_multibyte(dst, src, dst_len, ucs2_to_unixcp);
-}
-
-/*******************************************************************
- Convert a UNIX string to UNICODE format. Note that the 'dst' is in
- native byte order, not little endian. Always zero terminates.
- This function may be replaced if the UNIX codepage format is a
- multi-byte one (ie. JIS, SJIS or utf8). See the code in lib/kanji.c
- for details. dst_len is in bytes, not ucs2 units.
-********************************************************************/
-
-smb_ucs2_t *unix_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len)
-{
- return multibyte_to_unicode(dst, src, dst_len, unixcp_to_ucs2);
-}
-
-/*******************************************************************
- Convert a UNICODE string to DOS format. Note that the 'src' is in
- native byte order, not little endian. Always zero terminates.
- dst_len is in bytes.
-********************************************************************/
-
-char *unicode_to_dos(char *dst, const smb_ucs2_t *src, size_t dst_len)
-{
- return unicode_to_multibyte(dst, src, dst_len, ucs2_to_doscp);
-}
-
-/*******************************************************************
- Convert a single UNICODE character to DOS codepage. Returns the
- number of bytes in the DOS codepage character.
-********************************************************************/
-
-size_t unicode_to_dos_char(char *dst, const smb_ucs2_t src)
-{
- smb_ucs2_t val = ucs2_to_doscp[src];
- if(val < 256) {
- *dst = (char)val;
- return (size_t)1;
- }
- /*
- * A 2 byte value is always written as
- * high/low into the buffer stream.
- */
-
- dst[0] = (char)((val >> 8) & 0xff);
- dst[1] = (char)(val & 0xff);
- return (size_t)2;
-}
-
-/*******************************************************************
- Convert a DOS string to UNICODE format. Note that the 'dst' is in
- native byte order, not little endian. Always zero terminates.
- This function may be replaced if the DOS codepage format is a
- multi-byte one (ie. JIS, SJIS or utf8). See the code in lib/kanji.c
- for details. dst_len is in bytes, not ucs2 units.
-********************************************************************/
-
-smb_ucs2_t *dos_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len)
-{
- return multibyte_to_unicode(dst, src, dst_len, doscp_to_ucs2);
-}
-
-/*******************************************************************
- Count the number of characters in a smb_ucs2_t string.
-********************************************************************/
-
-size_t strlen_w(const smb_ucs2_t *src)
-{
- size_t len;
-
- for(len = 0; *src++; len++)
- ;
-
- return len;
-}
-
-/*******************************************************************
- Safe wstring copy into a known length string. maxlength includes
- the terminating zero. maxlength is in ucs2 units.
-********************************************************************/
-
-smb_ucs2_t *safe_strcpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src, size_t maxlength)
-{
- size_t ucs2_len;
-
- if (!dest) {
- DEBUG(0,("ERROR: NULL dest in safe_strcpy_w\n"));
- return NULL;
- }
-
- if (!src) {
- *dest = 0;
- return dest;
- }
-
- maxlength /= sizeof(smb_ucs2_t);
-
- ucs2_len = strlen_w(src);
-
- if (ucs2_len >= maxlength) {
- fstring out;
- DEBUG(0,("ERROR: string overflow by %u bytes in safe_strcpy_w [%.50s]\n",
- (unsigned int)((ucs2_len-maxlength)*sizeof(smb_ucs2_t)),
- unicode_to_unix(out,src,sizeof(out))) );
- ucs2_len = maxlength - 1;
- }
-
- memcpy(dest, src, ucs2_len*sizeof(smb_ucs2_t));
- dest[ucs2_len] = 0;
- return dest;
-}
-
-/*******************************************************************
- Safe string cat into a string. maxlength includes the terminating zero.
- maxlength is in ucs2 units.
-********************************************************************/
-
-smb_ucs2_t *safe_strcat_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength)
-{
- size_t ucs2_src_len, ucs2_dest_len;
-
- if (!dest) {
- DEBUG(0,("ERROR: NULL dest in safe_strcat_w\n"));
- return NULL;
- }
-
- if (!src)
- return dest;
-
- ucs2_src_len = strlen_w(src);
- ucs2_dest_len = strlen_w(dest);
-
- if (ucs2_src_len + ucs2_dest_len >= maxlength) {
- fstring out;
- int new_len = maxlength - ucs2_dest_len - 1;
- DEBUG(0,("ERROR: string overflow by %u characters in safe_strcat_w [%.50s]\n",
- (unsigned int)(sizeof(smb_ucs2_t)*(ucs2_src_len + ucs2_dest_len - maxlength)),
- unicode_to_unix(out,src,sizeof(out))) );
- ucs2_src_len = (size_t)(new_len > 0 ? new_len : 0);
- }
-
- memcpy(&dest[ucs2_dest_len], src, ucs2_src_len*sizeof(smb_ucs2_t));
- dest[ucs2_dest_len + ucs2_src_len] = 0;
- return dest;
-}
-
-/*******************************************************************
- Compare the two strings s1 and s2.
-********************************************************************/
-
-int strcmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
-{
- smb_ucs2_t c1, c2;
-
- for (;;) {
- c1 = *s1++;
- c2 = *s2++;
-
- if (c1 != c2)
- return c1 - c2;
-
- if (c1 == 0)
- break;
- }
- return 0;
-}
-
-/*******************************************************************
- Compare the first n characters of s1 to s2. len is in ucs2 units.
-********************************************************************/
-
-int strncmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2, size_t len)
-{
- smb_ucs2_t c1, c2;
-
- for (; len != 0; --len) {
- c1 = *s1++;
- c2 = *s2++;
-
- if (c1 != c2)
- return c1 - c2;
-
- if (c1 == 0)
- break;
-
- }
- return 0;
-}
-
-/*******************************************************************
- Search string s2 from s1.
-********************************************************************/
-
-smb_ucs2_t *strstr_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
-{
- size_t len = strlen_w(s2);
-
- if (!*s2)
- return (smb_ucs2_t *)s1;
-
- for(;*s1; s1++) {
- if (*s1 == *s2) {
- if (strncmp_w(s1, s2, len) == 0)
- return (smb_ucs2_t *)s1;
- }
- }
- return NULL;
-}
-
-/*******************************************************************
- Search for ucs2 char c from the beginning of s.
-********************************************************************/
-
-smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
-{
- do {
- if (*s == c)
- return (smb_ucs2_t *)s;
- } while (*s++);
-
- return NULL;
-}
-
-/*******************************************************************
- Search for ucs2 char c from the end of s.
-********************************************************************/
-
-smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
-{
- smb_ucs2_t *retval = 0;
-
- do {
- if (*s == c)
- retval = (smb_ucs2_t *)s;
- } while (*s++);
-
- return retval;
-}
-
-/*******************************************************************
- Search token from s1 separated by any ucs2 char of s2.
-********************************************************************/
-
-smb_ucs2_t *strtok_w(smb_ucs2_t *s1, const smb_ucs2_t *s2)
-{
- static smb_ucs2_t *s = NULL;
- smb_ucs2_t *q;
-
- if (!s1) {
- if (!s)
- return NULL;
- s1 = s;
- }
-
- for (q = s1; *s1; s1++) {
- smb_ucs2_t *p = strchr_w(s2, *s1);
- if (p) {
- if (s1 != q) {
- s = s1 + 1;
- *s1 = '\0';
- return q;
- }
- q = s1 + 1;
- }
- }
-
- s = NULL;
- if (*q)
- return q;
-
- return NULL;
-}
-
-/*******************************************************************
- Duplicate a ucs2 string.
-********************************************************************/
-
-smb_ucs2_t *strdup_w(const smb_ucs2_t *s)
-{
- size_t newlen = (strlen_w(s)+1)*sizeof(smb_ucs2_t);
- smb_ucs2_t *newstr = (smb_ucs2_t *)malloc(newlen);
- if (newstr == NULL)
- return NULL;
- safe_strcpy_w(newstr, s, newlen);
- return newstr;
-}
-
-/*******************************************************************
Mapping tables for UNICODE character. Allows toupper/tolower and
isXXX functions to work.
@@ -1125,33 +197,6 @@ int islower_w( smb_ucs2_t val)
}
/*******************************************************************
- Is a digit wchar.
-********************************************************************/
-
-int isdigit_w( smb_ucs2_t val)
-{
- return (map_table_flags(val) & UNI_DIGIT);
-}
-
-/*******************************************************************
- Is a hex digit wchar.
-********************************************************************/
-
-int isxdigit_w( smb_ucs2_t val)
-{
- return (map_table_flags(val) & UNI_XDIGIT);
-}
-
-/*******************************************************************
- Is a space wchar.
-********************************************************************/
-
-int isspace_w( smb_ucs2_t val)
-{
- return (map_table_flags(val) & UNI_SPACE);
-}
-
-/*******************************************************************
Convert a wchar to upper case.
********************************************************************/
@@ -1170,102 +215,33 @@ smb_ucs2_t tolower_w( smb_ucs2_t val )
}
/*******************************************************************
- Case insensitive string compararison.
+ Count the number of characters in a smb_ucs2_t string.
********************************************************************/
-
-int StrCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t)
+size_t strlen_w(const smb_ucs2_t *src)
{
- /*
- * Compare until we run out of string, either t or s, or find a difference.
- */
+ size_t len;
- while (*s && *t && toupper_w(*s) == toupper_w(*t)) {
- s++;
- t++;
- }
+ for(len = 0; *src++; len++) ;
- return(toupper_w(*s) - toupper_w(*t));
+ return len;
}
/*******************************************************************
- Case insensitive string compararison, length limited.
- n is in ucs2 units.
+wide strchr()
********************************************************************/
-
-int StrnCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t, size_t n)
+smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
{
- /*
- * Compare until we run out of string, either t or s, or chars.
- */
-
- while (n && *s && *t && toupper_w(*s) == toupper_w(*t)) {
+ while (*s != 0) {
+ if (c == *s) return (smb_ucs2_t *)s;
s++;
- t++;
- n--;
}
-
- /*
- * Not run out of chars - strings are different lengths.
- */
-
- if (n)
- return(toupper_w(*s) - toupper_w(*t));
-
- /*
- * Identical up to where we run out of chars,
- * and strings are same length.
- */
-
- return(0);
-}
-
-/*******************************************************************
- Compare 2 strings.
-********************************************************************/
-
-BOOL strequal_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
-{
- if (s1 == s2)
- return(True);
- if (!s1 || !s2)
- return(False);
-
- return(StrCaseCmp_w(s1,s2)==0);
+ return NULL;
}
-/*******************************************************************
- Compare 2 strings up to and including the nth char. n is in ucs2
- units.
-******************************************************************/
-
-BOOL strnequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2,size_t n)
-{
- if (s1 == s2)
- return(True);
- if (!s1 || !s2 || !n)
- return(False);
-
- return(StrnCaseCmp_w(s1,s2,n)==0);
-}
-
-/*******************************************************************
- Compare 2 strings (case sensitive).
-********************************************************************/
-
-BOOL strcsequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2)
-{
- if (s1 == s2)
- return(True);
- if (!s1 || !s2)
- return(False);
-
- return(strcmp_w(s1,s2)==0);
-}
/*******************************************************************
Convert a string to lower case.
********************************************************************/
-
void strlower_w(smb_ucs2_t *s)
{
while (*s) {
@@ -1278,7 +254,6 @@ void strlower_w(smb_ucs2_t *s)
/*******************************************************************
Convert a string to upper case.
********************************************************************/
-
void strupper_w(smb_ucs2_t *s)
{
while (*s) {
@@ -1289,547 +264,70 @@ void strupper_w(smb_ucs2_t *s)
}
/*******************************************************************
- Convert a string to "normal" form.
-********************************************************************/
-
-void strnorm_w(smb_ucs2_t *s)
-{
- extern int case_default;
- if (case_default == CASE_UPPER)
- strupper_w(s);
- else
- strlower_w(s);
-}
-
-/*******************************************************************
- Check if a string is in "normal" case.
+case insensitive string comparison
********************************************************************/
-
-BOOL strisnormal_w(smb_ucs2_t *s)
+int strcasecmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b)
{
- extern int case_default;
- if (case_default == CASE_UPPER)
- return(!strhaslower_w(s));
-
- return(!strhasupper_w(s));
+ while (*b && tolower_w(*a) == tolower_w(*b)) { a++; b++; }
+ return (tolower_w(*a) - tolower_w(*b));
}
-/****************************************************************************
- String replace.
-****************************************************************************/
-void string_replace_w(smb_ucs2_t *s, smb_ucs2_t oldc, smb_ucs2_t newc)
-{
- while (*s) {
- if (oldc == *s)
- *s = newc;
- s++;
- }
-}
-
-/*******************************************************************
- Skip past some strings in a buffer. n is in bytes.
-********************************************************************/
-
-smb_ucs2_t *skip_string_w(smb_ucs2_t *buf,size_t n)
-{
- while (n--)
- buf += (strlen_w(buf)*sizeof(smb_ucs2_t)) + 1;
- return(buf);
-}
-
-/*******************************************************************
- Count the number of characters in a string. Same as strlen_w in
- smb_ucs2_t string units.
-********************************************************************/
+/*
+ The *_wa() functions take a combination of 7 bit ascii
+ and wide characters They are used so that you can use string
+ functions combining C string constants with ucs2 strings
-size_t str_charnum_w(const smb_ucs2_t *s)
-{
- return strlen_w(s);
-}
+ The char* arguments must NOT be multibyte - to be completely sure
+ of this only pass string constants */
-/*******************************************************************
- Trim the specified elements off the front and back of a string.
-********************************************************************/
-BOOL trim_string_w(smb_ucs2_t *s,const smb_ucs2_t *front,const smb_ucs2_t *back)
+void pstrcpy_wa(smb_ucs2_t *dest, const char *src)
{
- BOOL ret = False;
- size_t front_len = (front && *front) ? strlen_w(front) : 0;
- size_t back_len = (back && *back) ? strlen_w(back) : 0;
- size_t s_len;
-
- while (front_len && strncmp_w(s, front, front_len) == 0) {
- smb_ucs2_t *p = s;
- ret = True;
-
- while (1) {
- if (!(*p = p[front_len]))
- break;
- p++;
- }
- }
-
- if(back_len) {
- s_len = strlen_w(s);
- while ((s_len >= back_len) &&
- (strncmp_w(s + s_len - back_len, back, back_len)==0)) {
- ret = True;
- s[s_len - back_len] = 0;
- s_len = strlen_w(s);
- }
+ int i;
+ for (i=0;i<PSTRING_LEN;i++) {
+ dest[i] = UCS2_CHAR(src[i]);
+ if (src[i] == 0) return;
}
-
- return(ret);
}
-/****************************************************************************
- Does a string have any uppercase chars in it ?
-****************************************************************************/
-
-BOOL strhasupper_w(const smb_ucs2_t *s)
+int strcmp_wa(const smb_ucs2_t *a, const char *b)
{
- while (*s) {
- if (isupper_w(*s))
- return(True);
- s++;
- }
- return(False);
+ while (*b && *a == UCS2_CHAR(*b)) { a++; b++; }
+ return (*a - UCS2_CHAR(*b));
}
-/****************************************************************************
- Does a string have any lowercase chars in it ?
-****************************************************************************/
-
-BOOL strhaslower_w(const smb_ucs2_t *s)
+smb_ucs2_t *strchr_wa(const smb_ucs2_t *s, char c)
{
- while (*s) {
- if (islower(*s))
- return(True);
+ while (*s != 0) {
+ if (UCS2_CHAR(c) == *s) return (smb_ucs2_t *)s;
s++;
}
- return(False);
+ return NULL;
}
-/****************************************************************************
- Find the number of 'c' chars in a string.
-****************************************************************************/
-
-size_t count_chars_w(const smb_ucs2_t *s,smb_ucs2_t c)
+smb_ucs2_t *strrchr_wa(const smb_ucs2_t *s, char c)
{
- size_t count=0;
-
- while (*s) {
- if (*s == c)
- count++;
- s++;
+ const smb_ucs2_t *p = s;
+ int len = strlen_w(s);
+ if (len == 0) return NULL;
+ p += (len-1);
+ while (p != s) {
+ if (UCS2_CHAR(c) == *p) return (smb_ucs2_t *)p;
+ p--;
}
- return(count);
+ return NULL;
}
-/*******************************************************************
- Return True if a string consists only of one particular character.
-********************************************************************/
-
-BOOL str_is_all_w(const smb_ucs2_t *s,smb_ucs2_t c)
+smb_ucs2_t *strpbrk_wa(const smb_ucs2_t *s, const char *p)
{
- if(s == NULL)
- return False;
- if(!*s)
- return False;
-
- while (*s) {
- if (*s != c)
- return False;
+ while (*s != 0) {
+ int i;
+ for (i=0; p[i] && *s != UCS2_CHAR(p[i]); i++)
+ ;
+ if (p[i]) return (smb_ucs2_t *)s;
s++;
}
- return True;
-}
-
-/*******************************************************************
- Paranoid strcpy into a buffer of given length (includes terminating
- zero. Strips out all but 'a-Z0-9' and replaces with '_'. Deliberately
- does *NOT* check for multibyte characters. Don't change it !
- maxlength is in ucs2 units.
-********************************************************************/
-
-smb_ucs2_t *alpha_strcpy_w(smb_ucs2_t *dest, const smb_ucs2_t *src, const smb_ucs2_t *other_safe_chars, size_t maxlength)
-{
- size_t len, i;
- smb_ucs2_t nullstr_w = (smb_ucs2_t)0;
-
- if (!dest) {
- DEBUG(0,("ERROR: NULL dest in alpha_strcpy_w\n"));
- return NULL;
- }
-
- if (!src) {
- *dest = 0;
- return dest;
- }
-
- len = strlen_w(src);
- if (len >= maxlength)
- len = maxlength - 1;
-
- if (!other_safe_chars)
- other_safe_chars = &nullstr_w;
-
- for(i = 0; i < len; i++) {
- smb_ucs2_t val = src[i];
- if(isupper_w(val) ||islower_w(val) || isdigit_w(val) || strchr_w(other_safe_chars, val))
- dest[i] = src[i];
- else
- dest[i] = (smb_ucs2_t)'_';
- }
-
- dest[i] = 0;
-
- return dest;
-}
-
-/****************************************************************************
- Like strncpy but always null terminates. Make sure there is room !
- The variable n should always be one less than the available size and is in
- ucs2 units.
-****************************************************************************/
-
-smb_ucs2_t *StrnCpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src,size_t n)
-{
- smb_ucs2_t *d = dest;
- if (!dest)
- return(NULL);
- if (!src) {
- *dest = 0;
- return(dest);
- }
-
- while (n-- && (*d++ = *src++))
- ;
- *d = 0;
- return(dest);
-}
-
-/****************************************************************************
- Like strncpy but copies up to the character marker. Always null terminates.
- returns a pointer to the character marker in the source string (src).
- n is in ucs2 units.
-****************************************************************************/
-
-smb_ucs2_t *strncpyn_w(smb_ucs2_t *dest, const smb_ucs2_t *src,size_t n, smb_ucs2_t c)
-{
- smb_ucs2_t *p;
- size_t str_len;
-
- p = strchr_w(src, c);
- if (p == NULL) {
- fstring cval;
- smb_ucs2_t mbcval[2];
- mbcval[0] = c;
- mbcval[1] = 0;
- DEBUG(5, ("strncpyn_w: separator character (%s) not found\n",
- unicode_to_unix(cval,mbcval,sizeof(cval)) ));
- return NULL;
- }
-
- str_len = PTR_DIFF(p, src) + 1;
- safe_strcpy_w(dest, src, MIN(n, str_len));
-
- return p;
-}
-
-/*************************************************************
- Routine to get hex characters and turn them into a 16 byte array.
- The array can be variable length, and any non-hex-numeric
- characters are skipped. "0xnn" or "0Xnn" is specially catered
- for. len is in bytes.
- Valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
-**************************************************************/
-
-static smb_ucs2_t hexprefix[] = { (smb_ucs2_t)'0', (smb_ucs2_t)'x', 0 };
-static smb_ucs2_t hexchars[] = { (smb_ucs2_t)'0', (smb_ucs2_t)'1', (smb_ucs2_t)'2', (smb_ucs2_t)'3',
- (smb_ucs2_t)'4', (smb_ucs2_t)'5', (smb_ucs2_t)'6', (smb_ucs2_t)'7',
- (smb_ucs2_t)'8', (smb_ucs2_t)'9', (smb_ucs2_t)'A', (smb_ucs2_t)'B',
- (smb_ucs2_t)'C', (smb_ucs2_t)'D', (smb_ucs2_t)'E', (smb_ucs2_t)'F', 0 };
-
-size_t strhex_to_str_w(char *p, size_t len, const smb_ucs2_t *strhex)
-{
- size_t i;
- size_t num_chars = 0;
- unsigned char lonybble, hinybble;
- smb_ucs2_t *p1 = NULL, *p2 = NULL;
-
- /*
- * Convert to smb_ucs2_t units.
- */
-
- len /= sizeof(smb_ucs2_t);
-
- for (i = 0; i < len && strhex[i] != 0; i++) {
- if (strnequal_w(hexchars, hexprefix, 2)) {
- i++; /* skip two chars */
- continue;
- }
-
- if (!(p1 = strchr_w(hexchars, toupper_w(strhex[i]))))
- break;
-
- i++; /* next hex digit */
-
- if (!(p2 = strchr_w(hexchars, toupper_w(strhex[i]))))
- break;
-
- /* get the two nybbles */
- hinybble = (PTR_DIFF(p1, hexchars)/sizeof(smb_ucs2_t));
- lonybble = (PTR_DIFF(p2, hexchars)/sizeof(smb_ucs2_t));
-
- p[num_chars] = (hinybble << 4) | lonybble;
- num_chars++;
-
- p1 = NULL;
- p2 = NULL;
- }
- return num_chars;
-}
-
-
-/* This is used to prevent lots of mallocs of size 2 */
-static smb_ucs2_t *null_string = NULL;
-
-/****************************************************************************
- Set a string value, allocing the space for the string.
-****************************************************************************/
-
-BOOL string_init_w(smb_ucs2_t **dest,const smb_ucs2_t *src)
-{
- size_t l;
-
- if (!null_string) {
- if((null_string = (smb_ucs2_t *)malloc(sizeof(smb_ucs2_t))) == NULL) {
- DEBUG(0,("string_init_w: malloc fail for null_string.\n"));
- return False;
- }
- *null_string = 0;
- }
-
- if (!src)
- src = null_string;
-
- l = strlen_w(src);
-
- if (l == 0)
- *dest = null_string;
- else {
- (*dest) = (smb_ucs2_t *)malloc(sizeof(smb_ucs2_t)*(l+1));
- if ((*dest) == NULL) {
- DEBUG(0,("Out of memory in string_init_w\n"));
- return False;
- }
-
- wpstrcpy(*dest,src);
- }
- return(True);
-}
-
-/****************************************************************************
- Free a string value.
-****************************************************************************/
-
-void string_free_w(smb_ucs2_t **s)
-{
- if (!s || !(*s))
- return;
- if (*s == null_string)
- *s = NULL;
- if (*s)
- free((char *)*s);
- *s = NULL;
-}
-
-/****************************************************************************
- Set a string value, allocing the space for the string, and deallocating any
- existing space.
-****************************************************************************/
-
-BOOL string_set_w(smb_ucs2_t **dest,const smb_ucs2_t *src)
-{
- string_free_w(dest);
-
- return(string_init_w(dest,src));
-}
-
-/****************************************************************************
- Substitute a string for a pattern in another string. Make sure there is
- enough room !
-
- This routine looks for pattern in s and replaces it with
- insert. It may do multiple replacements.
-
- Any of " ; ' $ or ` in the insert string are replaced with _
- if len==0 then no length check is performed
- len is in ucs2 units.
-****************************************************************************/
-
-void string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len)
-{
- smb_ucs2_t *p;
- ssize_t ls,lp,li, i;
-
- if (!insert || !pattern || !s)
- return;
-
- ls = (ssize_t)strlen_w(s);
- lp = (ssize_t)strlen_w(pattern);
- li = (ssize_t)strlen_w(insert);
-
- if (!*pattern)
- return;
-
- while (lp <= ls && (p = strstr_w(s,pattern))) {
- if (len && (ls + (li-lp) >= len)) {
- fstring out;
- DEBUG(0,("ERROR: string overflow by %d in string_sub_w(%.50s, %d)\n",
- (int)(sizeof(smb_ucs2_t)*(ls + (li-lp) - len)),
- unicode_to_unix(out,pattern,sizeof(out)), (int)len*sizeof(smb_ucs2_t)));
- break;
- }
- if (li != lp)
- memmove(p+li,p+lp,sizeof(smb_ucs2_t)*(strlen_w(p+lp)+1));
-
- for (i=0;i<li;i++) {
- switch (insert[i]) {
- case (smb_ucs2_t)'`':
- case (smb_ucs2_t)'"':
- case (smb_ucs2_t)'\'':
- case (smb_ucs2_t)';':
- case (smb_ucs2_t)'$':
- case (smb_ucs2_t)'%':
- case (smb_ucs2_t)'\r':
- case (smb_ucs2_t)'\n':
- p[i] = (smb_ucs2_t)'_';
- break;
- default:
- p[i] = insert[i];
- }
- }
- s = p + li;
- ls += (li-lp);
- }
-}
-
-void fstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert)
-{
- string_sub_w(s, pattern, insert, sizeof(wfstring));
-}
-
-void pstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,smb_ucs2_t *insert)
-{
- string_sub_w(s, pattern, insert, sizeof(wpstring));
-}
-
-/****************************************************************************
- Similar to string_sub() but allows for any character to be substituted.
- Use with caution !
- if len==0 then no length check is performed.
-****************************************************************************/
-
-void all_string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len)
-{
- smb_ucs2_t *p;
- ssize_t ls,lp,li;
-
- if (!insert || !pattern || !s)
- return;
-
- ls = (ssize_t)strlen_w(s);
- lp = (ssize_t)strlen_w(pattern);
- li = (ssize_t)strlen_w(insert);
-
- if (!*pattern)
- return;
-
- while (lp <= ls && (p = strstr_w(s,pattern))) {
- if (len && (ls + (li-lp) >= len)) {
- fstring out;
- DEBUG(0,("ERROR: string overflow by %d in all_string_sub_w(%.50s, %d)\n",
- (int)(sizeof(smb_ucs2_t)*(ls + (li-lp) - len)),
- unicode_to_unix(out,pattern,sizeof(out)), (int)len*sizeof(smb_ucs2_t)));
- break;
- }
- if (li != lp)
- memmove(p+li,p+lp,sizeof(smb_ucs2_t)*(strlen_w(p+lp)+1));
-
- memcpy(p, insert, li*sizeof(smb_ucs2_t));
- s = p + li;
- ls += (li-lp);
- }
-}
-
-/****************************************************************************
- Splits out the front and back at a separator.
-****************************************************************************/
-
-void split_at_last_component_w(smb_ucs2_t *path, smb_ucs2_t *front, smb_ucs2_t sep, smb_ucs2_t *back)
-{
- smb_ucs2_t *p = strrchr_w(path, sep);
-
- if (p != NULL)
- *p = 0;
-
- if (front != NULL)
- wpstrcpy(front, path);
-
- if (p != NULL) {
- if (back != NULL)
- wpstrcpy(back, p+1);
- *p = (smb_ucs2_t)'\\';
- } else {
- if (back != NULL)
- back[0] = 0;
- }
-}
-
-
-/****************************************************************************
- Write an octal as a string.
-****************************************************************************/
-
-smb_ucs2_t *octal_string_w(int i)
-{
- static smb_ucs2_t wret[64];
- char ret[64];
-
- if (i == -1)
- slprintf(ret, sizeof(ret)-1, "-1");
- else
- slprintf(ret, sizeof(ret)-1, "0%o", i);
- return unix_to_unicode(wret, ret, sizeof(wret));
-}
-
-
-/****************************************************************************
- Truncate a string at a specified length.
- length is in ucs2 units.
-****************************************************************************/
-
-smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length)
-{
- if (s && strlen_w(s) > length)
- s[length] = 0;
-
- return s;
-}
-
-/******************************************************************
- functions for UTF8 support (using in kanji.c)
- ******************************************************************/
-smb_ucs2_t doscp2ucs2(int w)
-{
- return ((smb_ucs2_t)doscp_to_ucs2[w]);
-}
-
-int ucs2doscp(smb_ucs2_t w)
-{
- return ((int)ucs2_to_doscp[w]);
+ return NULL;
}