home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / samba-1.9.18p7.tar.gz / samba-1.9.18p7.tar / samba-1.9.18p7 / source / kanji.c < prev    next >
C/C++ Source or Header  |  1998-05-12  |  31KB  |  1,204 lines

  1. /* 
  2.    Unix SMB/Netbios implementation.
  3.    Version 1.9.
  4.    Kanji Extensions
  5.    Copyright (C) Andrew Tridgell 1992-1998
  6.    
  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.
  11.    
  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.
  16.    
  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.
  20.  
  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>
  25. */
  26.  
  27. #define _KANJI_C_
  28. #include "includes.h"
  29.  
  30. /*
  31.  * Function pointers that get overridden when multi-byte code pages
  32.  * are loaded.
  33.  */
  34.  
  35. char *(*multibyte_strchr)(char *, int ) = (char *(*)(char *, int )) strchr;
  36. char *(*multibyte_strrchr)(char *, int ) = (char *(*)(char *, int )) strrchr;
  37. char *(*multibyte_strstr)(char *, char *) = (char *(*)(char *, char *)) strstr;
  38. char *(*multibyte_strtok)(char *, char *) = (char *(*)(char *, char *)) strtok;
  39.  
  40. /*
  41.  * Kanji is treated differently here due to historical accident of
  42.  * it being the first non-English codepage added to Samba.
  43.  * The define 'KANJI' is being overloaded to mean 'use kanji codepage
  44.  * by default' and also 'this is the filename-to-disk conversion 
  45.  * method to use'. This really should be removed and all control
  46.  * over this left in the smb.conf parameters 'client codepage'
  47.  * and 'coding system'.
  48.  */
  49.  
  50. #ifndef KANJI
  51.  
  52. /*
  53.  * Set the default conversion to be the functions in
  54.  * charcnv.c.
  55.  */
  56.  
  57. static int skip_non_multibyte_char(char);
  58. static BOOL not_multibyte_char_1(char);
  59.  
  60. char *(*_dos_to_unix)(char *, BOOL) = dos2unix_format;
  61. char *(*_unix_to_dos)(char *, BOOL) = unix2dos_format;
  62. int (*_skip_multibyte_char)(char) = skip_non_multibyte_char;
  63. BOOL (*is_multibyte_char_1)(char) = not_multibyte_char_1;
  64.  
  65. #else /* KANJI */
  66.  
  67. /*
  68.  * Set the default conversion to be the function
  69.  * sj_to_sj in this file.
  70.  */
  71.  
  72. static char *sj_to_sj(char *from, BOOL overwrite);
  73. static int skip_kanji_multibyte_char(char);
  74. static BOOL is_kanji_multibyte_char_1(char);
  75.  
  76. char *(*_dos_to_unix)(char *, BOOL) = sj_to_sj;
  77. char *(*_unix_to_dos)(char *, BOOL) = sj_to_sj;
  78. int (*_skip_multibyte_char)(char) = skip_kanji_multibyte_char;
  79. int (*is_multibyte_char_1)(char) = is_kanji_multibyte_char_1;
  80.  
  81. #endif /* KANJI */
  82.  
  83. /* jis si/so sequence */
  84. static char jis_kso = JIS_KSO;
  85. static char jis_ksi = JIS_KSI;
  86. static char hex_tag = HEXTAG;
  87.  
  88. /*******************************************************************
  89.   SHIFT JIS functions
  90. ********************************************************************/
  91. /*******************************************************************
  92.  search token from S1 separated any char of S2
  93.  S1 contains SHIFT JIS chars.
  94. ********************************************************************/
  95. static char *sj_strtok(char *s1, char *s2)
  96. {
  97.     static char *s = NULL;
  98.     char *q;
  99.     if (!s1) {
  100.     if (!s) {
  101.         return NULL;
  102.     }
  103.     s1 = s;
  104.     }
  105.     for (q = s1; *s1; ) {
  106.     if (is_shift_jis (*s1)) {
  107.         s1 += 2;
  108.     } else if (is_kana (*s1)) {
  109.         s1++;
  110.     } else {
  111.         char *p = strchr (s2, *s1);
  112.         if (p) {
  113.         if (s1 != q) {
  114.             s = s1 + 1;
  115.             *s1 = '\0';
  116.             return q;
  117.         }
  118.         q = s1 + 1;
  119.         }
  120.         s1++;
  121.     }
  122.     }
  123.     s = NULL;
  124.     if (*q) {
  125.     return q;
  126.     }
  127.     return NULL;
  128. }
  129.  
  130. /*******************************************************************
  131.  search string S2 from S1
  132.  S1 contains SHIFT JIS chars.
  133. ********************************************************************/
  134. static char *sj_strstr(char *s1, char *s2)
  135. {
  136.     int len = strlen ((char *) s2);
  137.     if (!*s2) 
  138.     return (char *) s1;
  139.     for (;*s1;) {
  140.     if (*s1 == *s2) {
  141.         if (strncmp (s1, s2, len) == 0)
  142.         return (char *) s1;
  143.     }
  144.     if (is_shift_jis (*s1)) {
  145.         s1 += 2;
  146.     } else {
  147.         s1++;
  148.     }
  149.     }
  150.     return 0;
  151. }
  152.  
  153. /*******************************************************************
  154.  Search char C from beginning of S.
  155.  S contains SHIFT JIS chars.
  156. ********************************************************************/
  157. static char *sj_strchr (char *s, int c)
  158. {
  159.     for (; *s; ) {
  160.     if (*s == c)
  161.         return (char *) s;
  162.     if (is_shift_jis (*s)) {
  163.         s += 2;
  164.     } else {
  165.         s++;
  166.     }
  167.     }
  168.     return 0;
  169. }
  170.  
  171. /*******************************************************************
  172.  Search char C end of S.
  173.  S contains SHIFT JIS chars.
  174. ********************************************************************/
  175. static char *sj_strrchr(char *s, int c)
  176. {
  177.     char *q;
  178.  
  179.     for (q = 0; *s; ) {
  180.     if (*s == c) {
  181.         q = (char *) s;
  182.     }
  183.     if (is_shift_jis (*s)) {
  184.         s += 2;
  185.     } else {
  186.         s++;
  187.     }
  188.     }
  189.     return q;
  190. }
  191.  
  192. /*******************************************************************
  193.  Kanji multibyte char skip function.
  194. *******************************************************************/
  195.    
  196. static int skip_kanji_multibyte_char(char c)
  197. {
  198.   if(is_shift_jis(c)) {
  199.     return 2;
  200.   } else if (is_kana(c)) {
  201.     return 1;
  202.   }
  203.   return 0;
  204. }
  205.  
  206. /*******************************************************************
  207.  Kanji multibyte char identification.
  208. *******************************************************************/
  209.    
  210. static BOOL is_kanji_multibyte_char_1(char c)
  211. {
  212.   return is_shift_jis(c);
  213. }
  214.  
  215. /*******************************************************************
  216.  The following functions are the only ones needed to do multibyte
  217.  support for Hangul, Big5 and Simplified Chinese. Most of the
  218.  real work for these codepages is done in the generic multibyte
  219.  functions. The only reason these functions are needed at all
  220.  is that the is_xxx(c) calls are really preprocessor macros.
  221. ********************************************************************/
  222.  
  223. /*******************************************************************
  224.   Hangul (Korean - code page 949) function.
  225. ********************************************************************/
  226.  
  227. static BOOL hangul_is_multibyte_char_1(char c)
  228. {
  229.   return is_hangul(c);
  230. }
  231.  
  232. /*******************************************************************
  233.   Big5 Traditional Chinese (code page 950) function.
  234. ********************************************************************/
  235.  
  236. static BOOL big5_is_multibyte_char_1(char c)
  237. {
  238.   return is_big5_c1(c);
  239. }
  240.  
  241. /*******************************************************************
  242.   Simplified Chinese (code page 936) function.
  243. ********************************************************************/
  244.  
  245. static BOOL simpch_is_multibyte_char_1(char c)
  246. {
  247.   return is_simpch_c1(c);
  248. }
  249.  
  250. /*******************************************************************
  251.   Generic multibyte functions - used by Hangul, Big5 and Simplified
  252.   Chinese codepages.
  253. ********************************************************************/
  254.  
  255. /*******************************************************************
  256.  search token from S1 separated any char of S2
  257.  S1 contains generic multibyte chars.
  258. ********************************************************************/
  259.  
  260. static char *generic_multibyte_strtok(char *s1, char *s2)
  261. {
  262.     static char *s = NULL;
  263.     char *q;
  264.     if (!s1) {
  265.         if (!s) {
  266.             return NULL;
  267.         }
  268.         s1 = s;
  269.     }
  270.     for (q = s1; *s1; ) {
  271.         if ((*is_multibyte_char_1)(*s1)) {
  272.             s1 += 2;
  273.         } else {
  274.             char *p = strchr (s2, *s1);
  275.             if (p) {
  276.                 if (s1 != q) {
  277.                     s = s1 + 1;
  278.                     *s1 = '\0';
  279.                     return q;
  280.                 }
  281.                 q = s1 + 1;
  282.             }
  283.             s1++;
  284.         }
  285.     }
  286.     s = NULL;
  287.     if (*q) {
  288.         return q;
  289.     }
  290.     return NULL;
  291. }
  292.  
  293. /*******************************************************************
  294.  search string S2 from S1
  295.  S1 contains generic multibyte chars.
  296. ********************************************************************/
  297.  
  298. static char *generic_multibyte_strstr(char *s1, char *s2)
  299. {
  300.     int len = strlen ((char *) s2);
  301.     if (!*s2)
  302.         return (char *) s1;
  303.     for (;*s1;) {
  304.         if (*s1 == *s2) {
  305.             if (strncmp (s1, s2, len) == 0)
  306.                 return (char *) s1;
  307.         }
  308.         if ((*is_multibyte_char_1)(*s1)) {
  309.             s1 += 2;
  310.         } else {
  311.             s1++;
  312.         }
  313.     }
  314.     return 0;
  315. }
  316.  
  317. /*******************************************************************
  318.  Search char C from beginning of S.
  319.  S contains generic multibyte chars.
  320. ********************************************************************/
  321.  
  322. static char *generic_multibyte_strchr(char *s, int c)
  323. {
  324.     for (; *s; ) {
  325.         if (*s == c)
  326.             return (char *) s;
  327.         if ((*is_multibyte_char_1)(*s)) {
  328.             s += 2;
  329.         } else {
  330.             s++;
  331.         }
  332.     }
  333.     return 0;
  334. }
  335.  
  336. /*******************************************************************
  337.  Search char C end of S.
  338.  S contains generic multibyte chars.
  339. ********************************************************************/
  340.  
  341. static char *generic_multibyte_strrchr(char *s, int c)
  342. {
  343.     char *q;
  344.  
  345.     for (q = 0; *s; ) {
  346.         if (*s == c) {
  347.             q = (char *) s;
  348.         }
  349.         if ((*is_multibyte_char_1)(*s)) {
  350.             s += 2;
  351.         } else {
  352.             s++;
  353.         }
  354.     }
  355.     return q;
  356. }
  357.  
  358. /*******************************************************************
  359.  Generic multibyte char skip function.
  360. *******************************************************************/
  361.  
  362. static int skip_generic_multibyte_char(char c)
  363. {
  364.   if( (*is_multibyte_char_1)(c)) {
  365.     return 2;
  366.   }
  367.   return 0;
  368. }
  369.  
  370. /*******************************************************************
  371.   Code conversion
  372. ********************************************************************/
  373. /* convesion buffer */
  374. static char cvtbuf[1024];
  375.  
  376. /*******************************************************************
  377.   EUC <-> SJIS
  378. ********************************************************************/
  379. static int euc2sjis (int hi, int lo)
  380. {
  381.     if (hi & 1)
  382.     return ((hi / 2 + (hi < 0xdf ? 0x31 : 0x71)) << 8) |
  383.         (lo - (lo >= 0xe0 ? 0x60 : 0x61));
  384.     else
  385.     return ((hi / 2 + (hi < 0xdf ? 0x30 : 0x70)) << 8) | (lo - 2);
  386. }
  387.  
  388. static int sjis2euc (int hi, int lo)
  389. {
  390.     if (lo >= 0x9f)
  391.     return ((hi * 2 - (hi >= 0xe0 ? 0xe0 : 0x60)) << 8) | (lo + 2);
  392.     else
  393.     return ((hi * 2 - (hi >= 0xe0 ? 0xe1 : 0x61)) << 8) |
  394.         (lo + (lo >= 0x7f ? 0x60 : 0x61));
  395. }
  396.  
  397. /*******************************************************************
  398.  Convert FROM contain SHIFT JIS codes to EUC codes
  399.  return converted buffer
  400. ********************************************************************/
  401. static char *sj_to_euc(char *from, BOOL overwrite)
  402. {
  403.     char *out;
  404.     char *save;
  405.  
  406.     save = (char *) from;
  407.     for (out = cvtbuf; *from;) {
  408.     if (is_shift_jis (*from)) {
  409.         int code = sjis2euc ((int) from[0] & 0xff, (int) from[1] & 0xff);
  410.         *out++ = (code >> 8) & 0xff;
  411.         *out++ = code;
  412.         from += 2;
  413.     } else if (is_kana (*from)) {
  414.         *out++ = euc_kana;
  415.         *out++ = *from++;
  416.     } else {
  417.         *out++ = *from++;
  418.     }
  419.     }
  420.     *out = 0;
  421.     if (overwrite) {
  422.     pstrcpy((char *) save, (char *) cvtbuf);
  423.     return (char *) save;
  424.     } else {
  425.     return cvtbuf;
  426.     }
  427. }
  428.  
  429. /*******************************************************************
  430.  Convert FROM contain EUC codes to SHIFT JIS codes
  431.  return converted buffer
  432. ********************************************************************/
  433. static char *euc_to_sj(char *from, BOOL overwrite)
  434. {
  435.     char *out;
  436.     char *save;
  437.  
  438.     save = (char *) from;
  439.     for (out = cvtbuf; *from; ) {
  440.     if (is_euc (*from)) {
  441.         int code = euc2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
  442.         *out++ = (code >> 8) & 0xff;
  443.         *out++ = code;
  444.         from += 2;
  445.     } else if (is_euc_kana (*from)) {
  446.         *out++ = from[1];
  447.         from += 2;
  448.     } else {
  449.         *out++ = *from++;
  450.     }
  451.     }
  452.     *out = 0;
  453.     if (overwrite) {
  454.     pstrcpy(save, (char *) cvtbuf);
  455.     return save;
  456.     } else {
  457.     return cvtbuf;
  458.     }
  459. }
  460.  
  461. /*******************************************************************
  462.   JIS7,JIS8,JUNET <-> SJIS
  463. ********************************************************************/
  464. static int sjis2jis(int hi, int lo)
  465. {
  466.     if (lo >= 0x9f)
  467.     return ((hi * 2 - (hi >= 0xe0 ? 0x160 : 0xe0)) << 8) | (lo - 0x7e);
  468.     else
  469.     return ((hi * 2 - (hi >= 0xe0 ? 0x161 : 0xe1)) << 8) |
  470.         (lo - (lo >= 0x7f ? 0x20 : 0x1f));
  471. }
  472.  
  473. static int jis2sjis(int hi, int lo)
  474. {
  475.     if (hi & 1)
  476.     return ((hi / 2 + (hi < 0x5f ? 0x71 : 0xb1)) << 8) |
  477.         (lo + (lo >= 0x60 ? 0x20 : 0x1f));
  478.     else
  479.     return ((hi / 2 + (hi < 0x5f ? 0x70 : 0xb0)) << 8) | (lo + 0x7e);
  480. }
  481.  
  482. /*******************************************************************
  483.  Convert FROM contain JIS codes to SHIFT JIS codes
  484.  return converted buffer
  485. ********************************************************************/
  486. static char *jis8_to_sj(char *from, BOOL overwrite)
  487. {
  488.     char *out;
  489.     int shifted;
  490.     char *save;
  491.  
  492.     shifted = _KJ_ROMAN;
  493.     save = (char *) from;
  494.     for (out = cvtbuf; *from;) {
  495.     if (is_esc (*from)) {
  496.         if (is_so1 (from[1]) && is_so2 (from[2])) {
  497.         shifted = _KJ_KANJI;
  498.         from += 3;
  499.         } else if (is_si1 (from[1]) && is_si2 (from[2])) {
  500.         shifted = _KJ_ROMAN;
  501.         from += 3;
  502.         } else {            /* sequence error */
  503.         goto normal;
  504.         }
  505.     } else {
  506.     normal:
  507.         switch (shifted) {
  508.         default:
  509.         case _KJ_ROMAN:
  510.         *out++ = *from++;
  511.         break;
  512.         case _KJ_KANJI:
  513.         {
  514.             int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
  515.             *out++ = (code >> 8) & 0xff;
  516.             *out++ = code;
  517.             from += 2;
  518.         }
  519.         break;
  520.         }
  521.     }
  522.     }
  523.     *out = 0;
  524.     if (overwrite) {
  525.     pstrcpy (save, (char *) cvtbuf);
  526.     return save;
  527.     } else {
  528.     return cvtbuf;
  529.     }
  530. }
  531.  
  532. /*******************************************************************
  533.  Convert FROM contain SHIFT JIS codes to JIS codes
  534.  return converted buffer
  535. ********************************************************************/
  536. static char *sj_to_jis8(char *from, BOOL overwrite)
  537. {
  538.     char *out;
  539.     int shifted;
  540.     char *save;
  541.  
  542.     shifted = _KJ_ROMAN;
  543.     save = (char *) from;
  544.     for (out = cvtbuf; *from; ) {
  545.     if (is_shift_jis (*from)) {
  546.         int code;
  547.         switch (shifted) {
  548.         case _KJ_ROMAN:        /* to KANJI */
  549.         *out++ = jis_esc;
  550.         *out++ = jis_so1;
  551.         *out++ = jis_kso;
  552.         shifted = _KJ_KANJI;
  553.         break;
  554.         }
  555.         code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
  556.         *out++ = (code >> 8) & 0xff;
  557.         *out++ = code;
  558.         from += 2;
  559.     } else {
  560.         switch (shifted) {
  561.         case _KJ_KANJI:        /* to ROMAN/KANA */
  562.         *out++ = jis_esc;
  563.         *out++ = jis_si1;
  564.         *out++ = jis_ksi;
  565.         shifted = _KJ_ROMAN;
  566.         break;
  567.         }
  568.         *out++ = *from++;
  569.     }
  570.     }
  571.     switch (shifted) {
  572.     case _KJ_KANJI:            /* to ROMAN/KANA */
  573.     *out++ = jis_esc;
  574.     *out++ = jis_si1;
  575.     *out++ = jis_ksi;
  576.     shifted = _KJ_ROMAN;
  577.     break;
  578.     }
  579.     *out = 0;
  580.     if (overwrite) {
  581.     pstrcpy (save, (char *) cvtbuf);
  582.     return save;
  583.     } else {
  584.     return cvtbuf;
  585.     }
  586. }
  587.  
  588. /*******************************************************************
  589.  Convert FROM contain 7 bits JIS codes to SHIFT JIS codes
  590.  return converted buffer
  591. ********************************************************************/
  592. static char *jis7_to_sj(char *from, BOOL overwrite)
  593. {
  594.     char *out;
  595.     int shifted;
  596.     char *save;
  597.  
  598.     shifted = _KJ_ROMAN;
  599.     save = (char *) from;
  600.     for (out = cvtbuf; *from;) {
  601.     if (is_esc (*from)) {
  602.         if (is_so1 (from[1]) && is_so2 (from[2])) {
  603.         shifted = _KJ_KANJI;
  604.         from += 3;
  605.         } else if (is_si1 (from[1]) && is_si2 (from[2])) {
  606.         shifted = _KJ_ROMAN;
  607.         from += 3;
  608.         } else {            /* sequence error */
  609.         goto normal;
  610.         }
  611.     } else if (is_so (*from)) {
  612.         shifted = _KJ_KANA;        /* to KANA */
  613.         from++;
  614.     } else if (is_si (*from)) {
  615.         shifted = _KJ_ROMAN;    /* to ROMAN */
  616.         from++;
  617.     } else {
  618.     normal:
  619.         switch (shifted) {
  620.         default:
  621.         case _KJ_ROMAN:
  622.         *out++ = *from++;
  623.         break;
  624.         case _KJ_KANJI:
  625.         {
  626.             int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
  627.             *out++ = (code >> 8) & 0xff;
  628.             *out++ = code;
  629.             from += 2;
  630.         }
  631.         break;
  632.         case _KJ_KANA:
  633.         *out++ = ((int) from[0]) + 0x80;
  634.         break;
  635.         }
  636.     }
  637.     }
  638.     *out = 0;
  639.     if (overwrite) {
  640.     pstrcpy (save, (char *) cvtbuf);
  641.     return save;
  642.     } else {
  643.     return cvtbuf;
  644.     }
  645. }
  646.  
  647. /*******************************************************************
  648.  Convert FROM contain SHIFT JIS codes to 7 bits JIS codes
  649.  return converted buffer
  650. ********************************************************************/
  651. static char *sj_to_jis7(char *from, BOOL overwrite)
  652. {
  653.     char *out;
  654.     int shifted;
  655.     char *save;
  656.  
  657.     shifted = _KJ_ROMAN;
  658.     save = (char *) from;
  659.     for (out = cvtbuf; *from; ) {
  660.     if (is_shift_jis (*from)) {
  661.         int code;
  662.         switch (shifted) {
  663.         case _KJ_KANA:
  664.         *out++ = jis_si;    /* to ROMAN and through down */
  665.         case _KJ_ROMAN:        /* to KANJI */
  666.         *out++ = jis_esc;
  667.         *out++ = jis_so1;
  668.         *out++ = jis_kso;
  669.         shifted = _KJ_KANJI;
  670.         break;
  671.         }
  672.         code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
  673.         *out++ = (code >> 8) & 0xff;
  674.         *out++ = code;
  675.         from += 2;
  676.     } else if (is_kana (from[0])) {
  677.         switch (shifted) {
  678.         case _KJ_KANJI:        /* to ROMAN */
  679.         *out++ = jis_esc;
  680.         *out++ = jis_si1;
  681.         *out++ = jis_ksi;
  682.         case _KJ_ROMAN:        /* to KANA */
  683.         *out++ = jis_so;
  684.         shifted = _KJ_KANA;
  685.         break;
  686.         }
  687.         *out++ = ((int) *from++) - 0x80;
  688.     } else {
  689.         switch (shifted) {
  690.         case _KJ_KANA:
  691.         *out++ = jis_si;    /* to ROMAN */
  692.         shifted = _KJ_ROMAN;
  693.         break;
  694.         case _KJ_KANJI:        /* to ROMAN */
  695.         *out++ = jis_esc;
  696.         *out++ = jis_si1;
  697.         *out++ = jis_ksi;
  698.         shifted = _KJ_ROMAN;
  699.         break;
  700.         }
  701.         *out++ = *from++;
  702.     }
  703.     }
  704.     switch (shifted) {
  705.     case _KJ_KANA:
  706.     *out++ = jis_si;        /* to ROMAN */
  707.     break;
  708.     case _KJ_KANJI:            /* to ROMAN */
  709.     *out++ = jis_esc;
  710.     *out++ = jis_si1;
  711.     *out++ = jis_ksi;
  712.     break;
  713.     }
  714.     *out = 0;
  715.     if (overwrite) {
  716.     pstrcpy (save, (char *) cvtbuf);
  717.     return save;
  718.     } else {
  719.     return cvtbuf;
  720.     }
  721. }
  722.  
  723. /*******************************************************************
  724.  Convert FROM contain 7 bits JIS(junet) codes to SHIFT JIS codes
  725.  return converted buffer
  726. ********************************************************************/
  727. static char *junet_to_sj(char *from, BOOL overwrite)
  728. {
  729.     char *out;
  730.     int shifted;
  731.     char *save;
  732.  
  733.     shifted = _KJ_ROMAN;
  734.     save = (char *) from;
  735.     for (out = cvtbuf; *from;) {
  736.     if (is_esc (*from)) {
  737.         if (is_so1 (from[1]) && is_so2 (from[2])) {
  738.         shifted = _KJ_KANJI;
  739.         from += 3;
  740.         } else if (is_si1 (from[1]) && is_si2 (from[2])) {
  741.         shifted = _KJ_ROMAN;
  742.         from += 3;
  743.         } else if (is_juk1(from[1]) && is_juk2 (from[2])) {
  744.         shifted = _KJ_KANA;
  745.         from += 3;
  746.         } else {            /* sequence error */
  747.         goto normal;
  748.         }
  749.     } else {
  750.     normal:
  751.         switch (shifted) {
  752.         default:
  753.         case _KJ_ROMAN:
  754.         *out++ = *from++;
  755.         break;
  756.         case _KJ_KANJI:
  757.         {
  758.             int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
  759.             *out++ = (code >> 8) & 0xff;
  760.             *out++ = code;
  761.             from += 2;
  762.         }
  763.         break;
  764.         case _KJ_KANA:
  765.         *out++ = ((int) from[0]) + 0x80;
  766.         break;
  767.         }
  768.     }
  769.     }
  770.     *out = 0;
  771.     if (overwrite) {
  772.     pstrcpy (save, (char *) cvtbuf);
  773.     return save;
  774.     } else {
  775.     return cvtbuf;
  776.     }
  777. }
  778.  
  779. /*******************************************************************
  780.  Convert FROM contain SHIFT JIS codes to 7 bits JIS(junet) codes
  781.  return converted buffer
  782. ********************************************************************/
  783. static char *sj_to_junet(char *from, BOOL overwrite)
  784. {
  785.     char *out;
  786.     int shifted;
  787.     char *save;
  788.  
  789.     shifted = _KJ_ROMAN;
  790.     save = (char *) from;
  791.     for (out = cvtbuf; *from; ) {
  792.     if (is_shift_jis (*from)) {
  793.         int code;
  794.         switch (shifted) {
  795.         case _KJ_KANA:
  796.         case _KJ_ROMAN:        /* to KANJI */
  797.         *out++ = jis_esc;
  798.         *out++ = jis_so1;
  799.         *out++ = jis_so2;
  800.         shifted = _KJ_KANJI;
  801.         break;
  802.         }
  803.         code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
  804.         *out++ = (code >> 8) & 0xff;
  805.         *out++ = code;
  806.         from += 2;
  807.     } else if (is_kana (from[0])) {
  808.         switch (shifted) {
  809.         case _KJ_KANJI:        /* to ROMAN */
  810.         case _KJ_ROMAN:        /* to KANA */
  811.         *out++ = jis_esc;
  812.         *out++ = junet_kana1;
  813.         *out++ = junet_kana2;
  814.         shifted = _KJ_KANA;
  815.         break;
  816.         }
  817.         *out++ = ((int) *from++) - 0x80;
  818.     } else {
  819.         switch (shifted) {
  820.         case _KJ_KANA:
  821.         case _KJ_KANJI:        /* to ROMAN */
  822.         *out++ = jis_esc;
  823.         *out++ = jis_si1;
  824.         *out++ = jis_si2;
  825.         shifted = _KJ_ROMAN;
  826.         break;
  827.         }
  828.         *out++ = *from++;
  829.     }
  830.     }
  831.     switch (shifted) {
  832.     case _KJ_KANA:
  833.     case _KJ_KANJI:            /* to ROMAN */
  834.     *out++ = jis_esc;
  835.     *out++ = jis_si1;
  836.     *out++ = jis_si2;
  837.     break;
  838.     }
  839.     *out = 0;
  840.     if (overwrite) {
  841.     pstrcpy (save, (char *) cvtbuf);
  842.     return save;
  843.     } else {
  844.     return cvtbuf;
  845.     }
  846. }
  847.  
  848. /*******************************************************************
  849.   HEX <-> SJIS
  850. ********************************************************************/
  851. /* ":xx" -> a byte */
  852. static char *hex_to_sj(char *from, BOOL overwrite)
  853. {
  854.     char *sp, *dp;
  855.     
  856.     sp = (char *) from;
  857.     dp = cvtbuf;
  858.     while (*sp) {
  859.     if (*sp == hex_tag && isxdigit (sp[1]) && isxdigit (sp[2])) {
  860.         *dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2]));
  861.         sp += 3;
  862.     } else
  863.         *dp++ = *sp++;
  864.     }
  865.     *dp = '\0';
  866.     if (overwrite) {
  867.     pstrcpy ((char *) from, (char *) cvtbuf);
  868.     return (char *) from;
  869.     } else {
  870.     return cvtbuf;
  871.     }
  872. }
  873.  
  874. /*******************************************************************
  875.   kanji/kana -> ":xx" 
  876. ********************************************************************/
  877. static char *sj_to_hex(char *from, BOOL overwrite)
  878. {
  879.     unsigned char *sp, *dp;
  880.     
  881.     sp = (unsigned char*) from;
  882.     dp = (unsigned char*) cvtbuf;
  883.     while (*sp) {
  884.     if (is_kana(*sp)) {
  885.         *dp++ = hex_tag;
  886.         *dp++ = bin2hex (((*sp)>>4)&0x0f);
  887.         *dp++ = bin2hex ((*sp)&0x0f);
  888.         sp++;
  889.     } else if (is_shift_jis (*sp) && is_shift_jis2 (sp[1])) {
  890.         *dp++ = hex_tag;
  891.         *dp++ = bin2hex (((*sp)>>4)&0x0f);
  892.         *dp++ = bin2hex ((*sp)&0x0f);
  893.         sp++;
  894.         *dp++ = hex_tag;
  895.         *dp++ = bin2hex (((*sp)>>4)&0x0f);
  896.         *dp++ = bin2hex ((*sp)&0x0f);
  897.         sp++;
  898.     } else
  899.         *dp++ = *sp++;
  900.     }
  901.     *dp = '\0';
  902.     if (overwrite) {
  903.     pstrcpy ((char *) from, (char *) cvtbuf);
  904.     return (char *) from;
  905.     } else {
  906.     return cvtbuf;
  907.     }
  908. }
  909.  
  910. /*******************************************************************
  911.   CAP <-> SJIS
  912. ********************************************************************/
  913. /* ":xx" CAP -> a byte */
  914. static char *cap_to_sj(char *from, BOOL overwrite)
  915. {
  916.     char *sp, *dp;
  917.  
  918.     sp = (char *) from;
  919.     dp = cvtbuf;
  920.     while (*sp) {
  921.         /*
  922.          * The only change between this and hex_to_sj is here. sj_to_cap only
  923.          * translates characters greater or equal to 0x80 - make sure that here
  924.          * we only do the reverse (that's why the strchr is used rather than
  925.          * isxdigit. Based on fix from ado@elsie.nci.nih.gov (Arthur David Olson).
  926.          */
  927.         if (*sp == hex_tag && (strchr ("89abcdefABCDEF", sp[1]) != NULL) && isxdigit (sp[2])) {
  928.             *dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2]));
  929.             sp += 3;
  930.         } else
  931.             *dp++ = *sp++;
  932.     }
  933.     *dp = '\0';
  934.     if (overwrite) {
  935.         pstrcpy ((char *) from, (char *) cvtbuf);
  936.         return (char *) from;
  937.     } else {
  938.         return cvtbuf;
  939.     }
  940. }
  941.  
  942. /*******************************************************************
  943.   kanji/kana -> ":xx" - CAP format.
  944. ********************************************************************/
  945. static char *sj_to_cap(char *from, BOOL overwrite)
  946. {
  947.     unsigned char *sp, *dp;
  948.  
  949.     sp = (unsigned char*) from;
  950.     dp = (unsigned char*) cvtbuf;
  951.     while (*sp) {
  952.     if (*sp >= 0x80) {
  953.         *dp++ = hex_tag;
  954.         *dp++ = bin2hex (((*sp)>>4)&0x0f);
  955.         *dp++ = bin2hex ((*sp)&0x0f);
  956.         sp++;
  957.     } else {
  958.         *dp++ = *sp++;
  959.     }
  960.     }
  961.     *dp = '\0';
  962.     if (overwrite) {
  963.     pstrcpy ((char *) from, (char *) cvtbuf);
  964.     return (char *) from;
  965.     } else {
  966.     return cvtbuf;
  967.     }
  968. }
  969.  
  970. /*******************************************************************
  971.  sj to sj
  972. ********************************************************************/
  973. static char *sj_to_sj(char *from, BOOL overwrite)
  974. {
  975.     if (!overwrite) {
  976.     pstrcpy (cvtbuf, (char *) from);
  977.     return cvtbuf;
  978.     } else {
  979.     return (char *) from;
  980.     }
  981. }
  982.  
  983. /************************************************************************
  984.  conversion:
  985.  _dos_to_unix        _unix_to_dos
  986. ************************************************************************/
  987.  
  988. static void setup_string_function(int codes)
  989. {
  990.     switch (codes) {
  991.     default:
  992.         _dos_to_unix = dos2unix_format;
  993.         _unix_to_dos = unix2dos_format;
  994.         break;
  995.  
  996.     case SJIS_CODE:
  997.     _dos_to_unix = sj_to_sj;
  998.     _unix_to_dos = sj_to_sj;
  999.     break;
  1000.     
  1001.     case EUC_CODE:
  1002.     _dos_to_unix = sj_to_euc;
  1003.     _unix_to_dos = euc_to_sj;
  1004.     break;
  1005.     
  1006.     case JIS7_CODE:
  1007.     _dos_to_unix = sj_to_jis7;
  1008.     _unix_to_dos = jis7_to_sj;
  1009.     break;
  1010.  
  1011.     case JIS8_CODE:
  1012.     _dos_to_unix = sj_to_jis8;
  1013.     _unix_to_dos = jis8_to_sj;
  1014.     break;
  1015.  
  1016.     case JUNET_CODE:
  1017.     _dos_to_unix = sj_to_junet;
  1018.     _unix_to_dos = junet_to_sj;
  1019.     break;
  1020.  
  1021.     case HEX_CODE:
  1022.     _dos_to_unix = sj_to_hex;
  1023.     _unix_to_dos = hex_to_sj;
  1024.     break;
  1025.  
  1026.     case CAP_CODE:
  1027.     _dos_to_unix = sj_to_cap;
  1028.     _unix_to_dos = cap_to_sj;
  1029.     break;
  1030.     }
  1031. }
  1032.  
  1033. /************************************************************************
  1034.  Interpret coding system.
  1035. ************************************************************************/
  1036.  
  1037. void interpret_coding_system(char *str)
  1038. {
  1039.     int codes = UNKNOWN_CODE;
  1040.     
  1041.     if (strequal (str, "sjis")) {
  1042.     codes = SJIS_CODE;
  1043.     } else if (strequal (str, "euc")) {
  1044.     codes = EUC_CODE;
  1045.     } else if (strequal (str, "cap")) {
  1046.     codes = CAP_CODE;
  1047.     hex_tag = HEXTAG;
  1048.     } else if (strequal (str, "hex")) {
  1049.     codes = HEX_CODE;
  1050.     hex_tag = HEXTAG;
  1051.     } else if (!strncasecmp (str, "hex", 3)) {
  1052.     codes = HEX_CODE;
  1053.     hex_tag = (str[3] ? str[3] : HEXTAG);
  1054.     } else if (strequal (str, "j8bb")) {
  1055.     codes = JIS8_CODE;
  1056.     jis_kso = 'B';
  1057.     jis_ksi = 'B';
  1058.     } else if (strequal (str, "j8bj") || strequal (str, "jis8")) {
  1059.     codes = JIS8_CODE;
  1060.     jis_kso = 'B';
  1061.     jis_ksi = 'J';
  1062.     } else if (strequal (str, "j8bh")) {
  1063.     codes = JIS8_CODE;
  1064.     jis_kso = 'B';
  1065.     jis_ksi = 'H';
  1066.     } else if (strequal (str, "j8@b")) {
  1067.     codes = JIS8_CODE;
  1068.     jis_kso = '@';
  1069.     jis_ksi = 'B';
  1070.     } else if (strequal (str, "j8@j")) {
  1071.     codes = JIS8_CODE;
  1072.     jis_kso = '@';
  1073.     jis_ksi = 'J';
  1074.     } else if (strequal (str, "j8@h")) {
  1075.     codes = JIS8_CODE;
  1076.     jis_kso = '@';
  1077.     jis_ksi = 'H';
  1078.     } else if (strequal (str, "j7bb")) {
  1079.     codes = JIS7_CODE;
  1080.     jis_kso = 'B';
  1081.     jis_ksi = 'B';
  1082.     } else if (strequal (str, "j7bj") || strequal (str, "jis7")) {
  1083.     codes = JIS7_CODE;
  1084.     jis_kso = 'B';
  1085.     jis_ksi = 'J';
  1086.     } else if (strequal (str, "j7bh")) {
  1087.     codes = JIS7_CODE;
  1088.     jis_kso = 'B';
  1089.     jis_ksi = 'H';
  1090.     } else if (strequal (str, "j7@b")) {
  1091.     codes = JIS7_CODE;
  1092.     jis_kso = '@';
  1093.     jis_ksi = 'B';
  1094.     } else if (strequal (str, "j7@j")) {
  1095.     codes = JIS7_CODE;
  1096.     jis_kso = '@';
  1097.     jis_ksi = 'J';
  1098.     } else if (strequal (str, "j7@h")) {
  1099.     codes = JIS7_CODE;
  1100.     jis_kso = '@';
  1101.     jis_ksi = 'H';
  1102.     } else if (strequal (str, "jubb")) {
  1103.     codes = JUNET_CODE;
  1104.     jis_kso = 'B';
  1105.     jis_ksi = 'B';
  1106.     } else if (strequal (str, "jubj") || strequal (str, "junet")) {
  1107.     codes = JUNET_CODE;
  1108.     jis_kso = 'B';
  1109.     jis_ksi = 'J';
  1110.     } else if (strequal (str, "jubh")) {
  1111.     codes = JUNET_CODE;
  1112.     jis_kso = 'B';
  1113.     jis_ksi = 'H';
  1114.     } else if (strequal (str, "ju@b")) {
  1115.     codes = JUNET_CODE;
  1116.     jis_kso = '@';
  1117.     jis_ksi = 'B';
  1118.     } else if (strequal (str, "ju@j")) {
  1119.     codes = JUNET_CODE;
  1120.     jis_kso = '@';
  1121.     jis_ksi = 'J';
  1122.     } else if (strequal (str, "ju@h")) {
  1123.     codes = JUNET_CODE;
  1124.     jis_kso = '@';
  1125.     jis_ksi = 'H';
  1126.     }    
  1127.     setup_string_function (codes);
  1128. }
  1129.  
  1130. /*******************************************************************
  1131.  Non multibyte char function.
  1132. *******************************************************************/
  1133.    
  1134. static int skip_non_multibyte_char(char c)
  1135. {
  1136.   return 0;
  1137. }
  1138.  
  1139. /*******************************************************************
  1140.  Function that always says a character isn't multibyte.
  1141. *******************************************************************/
  1142.  
  1143. static BOOL not_multibyte_char_1(char c)
  1144. {
  1145.   return False;
  1146. }
  1147.  
  1148. /*******************************************************************
  1149.  Setup the function pointers for the functions that are replaced
  1150.  when multi-byte codepages are used.
  1151.  
  1152.  The dos_to_unix and unix_to_dos function pointers are only
  1153.  replaced by setup_string_function called by interpret_coding_system
  1154.  above.
  1155. *******************************************************************/
  1156.  
  1157. void initialize_multibyte_vectors( int client_codepage)
  1158. {
  1159.   switch( client_codepage )
  1160.   {
  1161.   case KANJI_CODEPAGE:
  1162.     multibyte_strchr = (char *(*)(char *, int )) sj_strchr;
  1163.     multibyte_strrchr = (char *(*)(char *, int )) sj_strrchr;
  1164.     multibyte_strstr = (char *(*)(char *, char *)) sj_strstr;
  1165.     multibyte_strtok = (char *(*)(char *, char *)) sj_strtok;
  1166.     _skip_multibyte_char = skip_kanji_multibyte_char;
  1167.     is_multibyte_char_1 = is_kanji_multibyte_char_1;
  1168.     break;
  1169.   case HANGUL_CODEPAGE:
  1170.     multibyte_strchr = (char *(*)(char *, int )) generic_multibyte_strchr;
  1171.     multibyte_strrchr = (char *(*)(char *, int )) generic_multibyte_strrchr;
  1172.     multibyte_strstr = (char *(*)(char *, char *)) generic_multibyte_strstr;
  1173.     multibyte_strtok = (char *(*)(char *, char *)) generic_multibyte_strtok;
  1174.     _skip_multibyte_char = skip_generic_multibyte_char;
  1175.     is_multibyte_char_1 = hangul_is_multibyte_char_1;
  1176.   case BIG5_CODEPAGE:
  1177.     multibyte_strchr = (char *(*)(char *, int )) generic_multibyte_strchr;
  1178.     multibyte_strrchr = (char *(*)(char *, int )) generic_multibyte_strrchr;
  1179.     multibyte_strstr = (char *(*)(char *, char *)) generic_multibyte_strstr;
  1180.     multibyte_strtok = (char *(*)(char *, char *)) generic_multibyte_strtok;
  1181.     _skip_multibyte_char = skip_generic_multibyte_char;
  1182.     is_multibyte_char_1 = big5_is_multibyte_char_1;
  1183.   case SIMPLIFIED_CHINESE_CODEPAGE:
  1184.     multibyte_strchr = (char *(*)(char *, int )) generic_multibyte_strchr;
  1185.     multibyte_strrchr = (char *(*)(char *, int )) generic_multibyte_strrchr;
  1186.     multibyte_strstr = (char *(*)(char *, char *)) generic_multibyte_strstr;
  1187.     multibyte_strtok = (char *(*)(char *, char *)) generic_multibyte_strtok;
  1188.     _skip_multibyte_char = skip_generic_multibyte_char;
  1189.     is_multibyte_char_1 = simpch_is_multibyte_char_1;
  1190.     break;
  1191.   /*
  1192.    * Single char size code page.
  1193.    */
  1194.   default:
  1195.     multibyte_strchr = (char *(*)(char *, int )) strchr;
  1196.     multibyte_strrchr = (char *(*)(char *, int )) strrchr;
  1197.     multibyte_strstr = (char *(*)(char *, char *)) strstr;
  1198.     multibyte_strtok = (char *(*)(char *, char *)) strtok;
  1199.     _skip_multibyte_char = skip_non_multibyte_char;
  1200.     is_multibyte_char_1 = not_multibyte_char_1;
  1201.     break; 
  1202.   }
  1203. }
  1204.