2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1992-1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 Adding for Japanese language by <fujita@ainix.isac.co.jp> 1994.9.5
22 and extend coding system to EUC/SJIS/JIS/HEX at 1994.10.11
23 and add all jis codes sequence type at 1995.8.16
24 Notes: Hexadecimal code by <ohki@gssm.otuka.tsukuba.ac.jp>
30 /* jis si/so sequence */
31 static char jis_kso = JIS_KSO;
32 static char jis_ksi = JIS_KSI;
33 static char hex_tag = HEXTAG;
35 /*******************************************************************
37 ********************************************************************/
38 /*******************************************************************
39 search token from S1 separated any char of S2
40 S1 contain SHIFT JIS chars.
41 ********************************************************************/
42 char *sj_strtok(char *s1, char *s2)
44 if (lp_client_code_page() != KANJI_CODEPAGE) {
45 return strtok(s1, s2);
47 static char *s = NULL;
56 if (is_shift_jis (*s1)) {
58 } else if (is_kana (*s1)) {
61 char *p = strchr (s2, *s1);
81 /*******************************************************************
82 search string S2 from S1
83 S1 contain SHIFT JIS chars.
84 ********************************************************************/
85 char *sj_strstr(char *s1, char *s2)
87 if (lp_client_code_page() != KANJI_CODEPAGE) {
88 return strstr(s1, s2);
90 int len = strlen ((char *) s2);
95 if (strncmp (s1, s2, len) == 0)
98 if (is_shift_jis (*s1)) {
108 /*******************************************************************
109 Search char C from beginning of S.
110 S contain SHIFT JIS chars.
111 ********************************************************************/
112 char *sj_strchr (char *s, int c)
114 if (lp_client_code_page() != KANJI_CODEPAGE) {
120 if (is_shift_jis (*s)) {
130 /*******************************************************************
131 Search char C end of S.
132 S contain SHIFT JIS chars.
133 ********************************************************************/
134 char *sj_strrchr(char *s, int c)
136 if (lp_client_code_page() != KANJI_CODEPAGE) {
137 return strrchr(s, c);
145 if (is_shift_jis (*s)) {
155 /*******************************************************************
157 ********************************************************************/
158 /* convesion buffer */
159 static char cvtbuf[1024];
161 /*******************************************************************
163 ********************************************************************/
164 static int euc2sjis (int hi, int lo)
167 return ((hi / 2 + (hi < 0xdf ? 0x31 : 0x71)) << 8) |
168 (lo - (lo >= 0xe0 ? 0x60 : 0x61));
170 return ((hi / 2 + (hi < 0xdf ? 0x30 : 0x70)) << 8) | (lo - 2);
173 static int sjis2euc (int hi, int lo)
176 return ((hi * 2 - (hi >= 0xe0 ? 0xe0 : 0x60)) << 8) | (lo + 2);
178 return ((hi * 2 - (hi >= 0xe0 ? 0xe1 : 0x61)) << 8) |
179 (lo + (lo >= 0x7f ? 0x60 : 0x61));
182 /*******************************************************************
183 Convert FROM contain SHIFT JIS codes to EUC codes
184 return converted buffer
185 ********************************************************************/
186 static char *sj_to_euc(char *from, BOOL overwrite)
191 save = (char *) from;
192 for (out = cvtbuf; *from;) {
193 if (is_shift_jis (*from)) {
194 int code = sjis2euc ((int) from[0] & 0xff, (int) from[1] & 0xff);
195 *out++ = (code >> 8) & 0xff;
198 } else if (is_kana (*from)) {
207 strcpy((char *) save, (char *) cvtbuf);
208 return (char *) save;
214 /*******************************************************************
215 Convert FROM contain EUC codes to SHIFT JIS codes
216 return converted buffer
217 ********************************************************************/
218 static char *euc_to_sj(char *from, BOOL overwrite)
223 save = (char *) from;
224 for (out = cvtbuf; *from; ) {
225 if (is_euc (*from)) {
226 int code = euc2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
227 *out++ = (code >> 8) & 0xff;
230 } else if (is_euc_kana (*from)) {
239 strcpy(save, (char *) cvtbuf);
246 /*******************************************************************
247 JIS7,JIS8,JUNET <-> SJIS
248 ********************************************************************/
249 static int sjis2jis(int hi, int lo)
252 return ((hi * 2 - (hi >= 0xe0 ? 0x160 : 0xe0)) << 8) | (lo - 0x7e);
254 return ((hi * 2 - (hi >= 0xe0 ? 0x161 : 0xe1)) << 8) |
255 (lo - (lo >= 0x7f ? 0x20 : 0x1f));
258 static int jis2sjis(int hi, int lo)
261 return ((hi / 2 + (hi < 0x5f ? 0x71 : 0xb1)) << 8) |
262 (lo + (lo >= 0x60 ? 0x20 : 0x1f));
264 return ((hi / 2 + (hi < 0x5f ? 0x70 : 0xb0)) << 8) | (lo + 0x7e);
267 /*******************************************************************
268 Convert FROM contain JIS codes to SHIFT JIS codes
269 return converted buffer
270 ********************************************************************/
271 static char *jis8_to_sj(char *from, BOOL overwrite)
278 save = (char *) from;
279 for (out = cvtbuf; *from;) {
280 if (is_esc (*from)) {
281 if (is_so1 (from[1]) && is_so2 (from[2])) {
284 } else if (is_si1 (from[1]) && is_si2 (from[2])) {
287 } else { /* sequence error */
299 int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
300 *out++ = (code >> 8) & 0xff;
310 strcpy (save, (char *) cvtbuf);
317 /*******************************************************************
318 Convert FROM contain SHIFT JIS codes to JIS codes
319 return converted buffer
320 ********************************************************************/
321 static char *sj_to_jis8(char *from, BOOL overwrite)
328 save = (char *) from;
329 for (out = cvtbuf; *from; ) {
330 if (is_shift_jis (*from)) {
333 case _KJ_ROMAN: /* to KANJI */
340 code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
341 *out++ = (code >> 8) & 0xff;
346 case _KJ_KANJI: /* to ROMAN/KANA */
357 case _KJ_KANJI: /* to ROMAN/KANA */
366 strcpy (save, (char *) cvtbuf);
373 /*******************************************************************
374 Convert FROM contain 7 bits JIS codes to SHIFT JIS codes
375 return converted buffer
376 ********************************************************************/
377 static char *jis7_to_sj(char *from, BOOL overwrite)
384 save = (char *) from;
385 for (out = cvtbuf; *from;) {
386 if (is_esc (*from)) {
387 if (is_so1 (from[1]) && is_so2 (from[2])) {
390 } else if (is_si1 (from[1]) && is_si2 (from[2])) {
393 } else { /* sequence error */
396 } else if (is_so (*from)) {
397 shifted = _KJ_KANA; /* to KANA */
399 } else if (is_si (*from)) {
400 shifted = _KJ_ROMAN; /* to ROMAN */
411 int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
412 *out++ = (code >> 8) & 0xff;
418 *out++ = ((int) from[0]) + 0x80;
425 strcpy (save, (char *) cvtbuf);
432 /*******************************************************************
433 Convert FROM contain SHIFT JIS codes to 7 bits JIS codes
434 return converted buffer
435 ********************************************************************/
436 static char *sj_to_jis7(char *from, BOOL overwrite)
443 save = (char *) from;
444 for (out = cvtbuf; *from; ) {
445 if (is_shift_jis (*from)) {
449 *out++ = jis_si; /* to ROMAN and through down */
450 case _KJ_ROMAN: /* to KANJI */
457 code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
458 *out++ = (code >> 8) & 0xff;
461 } else if (is_kana (from[0])) {
463 case _KJ_KANJI: /* to ROMAN */
467 case _KJ_ROMAN: /* to KANA */
472 *out++ = ((int) *from++) - 0x80;
476 *out++ = jis_si; /* to ROMAN */
479 case _KJ_KANJI: /* to ROMAN */
491 *out++ = jis_si; /* to ROMAN */
493 case _KJ_KANJI: /* to ROMAN */
501 strcpy (save, (char *) cvtbuf);
508 /*******************************************************************
509 Convert FROM contain 7 bits JIS(junet) codes to SHIFT JIS codes
510 return converted buffer
511 ********************************************************************/
512 static char *junet_to_sj(char *from, BOOL overwrite)
519 save = (char *) from;
520 for (out = cvtbuf; *from;) {
521 if (is_esc (*from)) {
522 if (is_so1 (from[1]) && is_so2 (from[2])) {
525 } else if (is_si1 (from[1]) && is_si2 (from[2])) {
528 } else if (is_juk1(from[1]) && is_juk2 (from[2])) {
531 } else { /* sequence error */
543 int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
544 *out++ = (code >> 8) & 0xff;
550 *out++ = ((int) from[0]) + 0x80;
557 strcpy (save, (char *) cvtbuf);
564 /*******************************************************************
565 Convert FROM contain SHIFT JIS codes to 7 bits JIS(junet) codes
566 return converted buffer
567 ********************************************************************/
568 static char *sj_to_junet(char *from, BOOL overwrite)
575 save = (char *) from;
576 for (out = cvtbuf; *from; ) {
577 if (is_shift_jis (*from)) {
581 case _KJ_ROMAN: /* to KANJI */
588 code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
589 *out++ = (code >> 8) & 0xff;
592 } else if (is_kana (from[0])) {
594 case _KJ_KANJI: /* to ROMAN */
595 case _KJ_ROMAN: /* to KANA */
597 *out++ = junet_kana1;
598 *out++ = junet_kana2;
602 *out++ = ((int) *from++) - 0x80;
606 case _KJ_KANJI: /* to ROMAN */
618 case _KJ_KANJI: /* to ROMAN */
626 strcpy (save, (char *) cvtbuf);
633 /*******************************************************************
635 ********************************************************************/
636 /* ":xx" -> a byte */
637 static char *hex_to_sj(char *from, BOOL overwrite)
644 if (*sp == hex_tag && isxdigit (sp[1]) && isxdigit (sp[2])) {
645 *dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2]));
652 strcpy ((char *) from, (char *) cvtbuf);
653 return (char *) from;
659 /*******************************************************************
661 ********************************************************************/
662 static char *sj_to_hex(char *from, BOOL overwrite)
664 unsigned char *sp, *dp;
666 sp = (unsigned char*) from;
667 dp = (unsigned char*) cvtbuf;
671 *dp++ = bin2hex (((*sp)>>4)&0x0f);
672 *dp++ = bin2hex ((*sp)&0x0f);
674 } else if (is_shift_jis (*sp) && is_shift_jis2 (sp[1])) {
676 *dp++ = bin2hex (((*sp)>>4)&0x0f);
677 *dp++ = bin2hex ((*sp)&0x0f);
680 *dp++ = bin2hex (((*sp)>>4)&0x0f);
681 *dp++ = bin2hex ((*sp)&0x0f);
688 strcpy ((char *) from, (char *) cvtbuf);
689 return (char *) from;
695 /*******************************************************************
697 ********************************************************************/
698 /* ":xx" CAP -> a byte */
699 static char *cap_to_sj(char *from, BOOL overwrite)
707 * The only change between this and hex_to_sj is here. sj_to_cap only
708 * translates characters greater or equal to 0x80 - make sure that here
709 * we only do the reverse (that's why the strchr is used rather than
710 * isxdigit. Based on fix from ado@elsie.nci.nih.gov (Arthur David Olson).
712 if (*sp == hex_tag && (strchr ("89abcdefABCDEF", sp[1]) != NULL) && isxdigit (sp[2])) {
713 *dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2]));
720 strcpy ((char *) from, (char *) cvtbuf);
721 return (char *) from;
727 /*******************************************************************
728 kanji/kana -> ":xx" - CAP format.
729 ********************************************************************/
730 static char *sj_to_cap(char *from, BOOL overwrite)
732 unsigned char *sp, *dp;
734 sp = (unsigned char*) from;
735 dp = (unsigned char*) cvtbuf;
739 *dp++ = bin2hex (((*sp)>>4)&0x0f);
740 *dp++ = bin2hex ((*sp)&0x0f);
748 strcpy ((char *) from, (char *) cvtbuf);
749 return (char *) from;
755 /*******************************************************************
757 ********************************************************************/
758 static char *sj_to_sj(char *from, BOOL overwrite)
761 strcpy (cvtbuf, (char *) from);
764 return (char *) from;
768 /************************************************************************
770 _dos_to_unix _unix_to_dos
771 ************************************************************************/
773 char *(*_dos_to_unix)(char *str, BOOL overwrite) = sj_to_sj;
774 char *(*_unix_to_dos)(char *str, BOOL overwrite) = sj_to_sj;
776 static int setup_string_function(int codes)
781 _dos_to_unix = sj_to_sj;
782 _unix_to_dos = sj_to_sj;
787 _dos_to_unix = sj_to_euc;
788 _unix_to_dos = euc_to_sj;
792 _dos_to_unix = sj_to_jis7;
793 _unix_to_dos = jis7_to_sj;
797 _dos_to_unix = sj_to_jis8;
798 _unix_to_dos = jis8_to_sj;
802 _dos_to_unix = sj_to_junet;
803 _unix_to_dos = junet_to_sj;
807 _dos_to_unix = sj_to_hex;
808 _unix_to_dos = hex_to_sj;
812 _dos_to_unix = sj_to_cap;
813 _unix_to_dos = cap_to_sj;
820 * Interpret coding system.
822 int interpret_coding_system(char *str)
824 int codes = UNKNOWN_CODE;
826 if (strequal (str, "sjis")) {
828 } else if (strequal (str, "euc")) {
830 } else if (strequal (str, "cap")) {
833 } else if (strequal (str, "hex")) {
836 } else if (strncasecmp (str, "hex", 3)) {
838 hex_tag = (str[3] ? str[3] : HEXTAG);
839 } else if (strequal (str, "j8bb")) {
843 } else if (strequal (str, "j8bj") || strequal (str, "jis8")) {
847 } else if (strequal (str, "j8bh")) {
851 } else if (strequal (str, "j8@b")) {
855 } else if (strequal (str, "j8@j")) {
859 } else if (strequal (str, "j8@h")) {
863 } else if (strequal (str, "j7bb")) {
867 } else if (strequal (str, "j7bj") || strequal (str, "jis7")) {
871 } else if (strequal (str, "j7bh")) {
875 } else if (strequal (str, "j7@b")) {
879 } else if (strequal (str, "j7@j")) {
883 } else if (strequal (str, "j7@h")) {
887 } else if (strequal (str, "jubb")) {
891 } else if (strequal (str, "jubj") || strequal (str, "junet")) {
895 } else if (strequal (str, "jubh")) {
899 } else if (strequal (str, "ju@b")) {
903 } else if (strequal (str, "ju@j")) {
907 } else if (strequal (str, "ju@h")) {
912 return setup_string_function (codes);