Herb's warning fixes. Also the POSIX locking fix.
[samba.git] / source3 / lib / kanji.c
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    Adding features about Machine dependent codes and User Defined Codes
26      by Hiroshi MIURA <miura@samba.gr.jp> 2000.3.19
27 */
28
29 #define _KANJI_C_
30 #include "includes.h"
31
32 /*
33  * Function pointers that get overridden when multi-byte code pages
34  * are loaded.
35  */
36
37 const char *(*multibyte_strchr)(const char *, int ) = (const char *(*)(const char *, int )) strchr;
38 const char *(*multibyte_strrchr)(const char *, int ) = (const char *(*)(const char *, int )) strrchr;
39 const char *(*multibyte_strstr)(const char *, const char *) = (const char *(*)(const char *, const char *)) strstr;
40 char *(*multibyte_strtok)(char *, const char *) = (char *(*)(char *, const char *)) strtok;
41
42 /*
43  * Kanji is treated differently here due to historical accident of
44  * it being the first non-English codepage added to Samba.
45  * The define 'KANJI' is being overloaded to mean 'use kanji codepage
46  * by default' and also 'this is the filename-to-disk conversion 
47  * method to use'. This really should be removed and all control
48  * over this left in the smb.conf parameters 'client codepage'
49  * and 'coding system'.
50  */
51
52 #ifndef KANJI
53
54 /*
55  * Set the default conversion to be the functions in
56  * charcnv.c.
57  */
58
59 static size_t skip_non_multibyte_char(char);
60 static BOOL not_multibyte_char_1(char);
61
62 char *(*_dos_to_unix)(char *, BOOL) = dos2unix_format;
63 char *(*_unix_to_dos)(char *, BOOL) = unix2dos_format;
64 size_t (*_skip_multibyte_char)(char) = skip_non_multibyte_char;
65 BOOL (*is_multibyte_char_1)(char) = not_multibyte_char_1;
66
67 #else /* KANJI */
68
69 /*
70  * Set the default conversion to be the function
71  * sj_to_sj in this file.
72  */
73
74 static char *sj_to_sj(char *from, BOOL overwrite);
75 static size_t skip_kanji_multibyte_char(char);
76 static BOOL is_kanji_multibyte_char_1(char);
77
78 char *(*_dos_to_unix)(char *, BOOL) = sj_to_sj;
79 char *(*_unix_to_dos)(char *, BOOL) = sj_to_sj;
80 size_t (*_skip_multibyte_char)(char) = skip_kanji_multibyte_char;
81 int (*is_multibyte_char_1)(char) = is_kanji_multibyte_char_1;
82
83 #endif /* KANJI */
84
85 BOOL global_is_multibyte_codepage = False;
86
87 /* jis si/so sequence */
88 static char jis_kso = JIS_KSO;
89 static char jis_ksi = JIS_KSI;
90 static char hex_tag = HEXTAG;
91
92 /*******************************************************************
93   SHIFT JIS functions
94 ********************************************************************/
95
96 /*******************************************************************
97  search token from S1 separated any char of S2
98  S1 contains SHIFT JIS chars.
99 ********************************************************************/
100
101 static char *sj_strtok(char *s1, const char *s2)
102 {
103   static char *s = NULL;
104   char *q;
105   if (!s1) {
106     if (!s) {
107       return NULL;
108     }
109     s1 = s;
110   }
111   for (q = s1; *s1; ) {
112     if (is_shift_jis (*s1)) {
113       s1 += 2;
114     } else if (is_kana (*s1)) {
115       s1++;
116     } else {
117       char *p = strchr (s2, *s1);
118       if (p) {
119         if (s1 != q) {
120           s = s1 + 1;
121           *s1 = '\0';
122           return q;
123         }
124         q = s1 + 1;
125       }
126       s1++;
127     }
128   }
129   s = NULL;
130   if (*q) {
131     return q;
132   }
133   return NULL;
134 }
135
136 /*******************************************************************
137  search string S2 from S1
138  S1 contains SHIFT JIS chars.
139 ********************************************************************/
140
141 static const char *sj_strstr(const char *s1, const char *s2)
142 {
143   size_t len = strlen (s2);
144   if (!*s2) 
145     return (const char *) s1;
146   for (;*s1;) {
147     if (*s1 == *s2) {
148       if (strncmp (s1, s2, len) == 0)
149         return (const char *) s1;
150     }
151     if (is_shift_jis (*s1)) {
152       s1 += 2;
153     } else {
154       s1++;
155     }
156   }
157   return NULL;
158 }
159
160 /*******************************************************************
161  Search char C from beginning of S.
162  S contains SHIFT JIS chars.
163 ********************************************************************/
164
165 static const char *sj_strchr (const char *s, int c)
166 {
167   for (; *s; ) {
168     if (*s == c)
169       return (const char *) s;
170     if (is_shift_jis (*s)) {
171       s += 2;
172     } else {
173       s++;
174     }
175   }
176   return NULL;
177 }
178
179 /*******************************************************************
180  Search char C end of S.
181  S contains SHIFT JIS chars.
182 ********************************************************************/
183
184 static const char *sj_strrchr(const char *s, int c)
185 {
186   const char *q;
187
188   for (q = 0; *s; ) {
189     if (*s == c) {
190       q = (const char *) s;
191     }
192     if (is_shift_jis (*s)) {
193       s += 2;
194     } else {
195       s++;
196     }
197   }
198   return q;
199 }
200
201 /*******************************************************************
202  Kanji multibyte char skip function.
203 *******************************************************************/
204    
205 static size_t skip_kanji_multibyte_char(char c)
206 {
207   if(is_shift_jis(c)) {
208     return 2;
209   } else if (is_kana(c)) {
210     return 1;
211   }
212   return 0;
213 }
214
215 /*******************************************************************
216  Kanji multibyte char identification.
217 *******************************************************************/
218    
219 static BOOL is_kanji_multibyte_char_1(char c)
220 {
221   return is_shift_jis(c);
222 }
223
224 /*******************************************************************
225  The following functions are the only ones needed to do multibyte
226  support for Hangul, Big5 and Simplified Chinese. Most of the
227  real work for these codepages is done in the generic multibyte
228  functions. The only reason these functions are needed at all
229  is that the is_xxx(c) calls are really preprocessor macros.
230 ********************************************************************/
231
232 /*******************************************************************
233   Hangul (Korean - code page 949) function.
234 ********************************************************************/
235
236 static BOOL hangul_is_multibyte_char_1(char c)
237 {
238   return is_hangul(c);
239 }
240
241 /*******************************************************************
242   Big5 Traditional Chinese (code page 950) function.
243 ********************************************************************/
244
245 static BOOL big5_is_multibyte_char_1(char c)
246 {
247   return is_big5_c1(c);
248 }
249
250 /*******************************************************************
251   Simplified Chinese (code page 936) function.
252 ********************************************************************/
253
254 static BOOL simpch_is_multibyte_char_1(char c)
255 {
256   return is_simpch_c1(c);
257 }
258
259 /*******************************************************************
260   Generic multibyte functions - used by Hangul, Big5 and Simplified
261   Chinese codepages.
262 ********************************************************************/
263
264 /*******************************************************************
265  search token from S1 separated any char of S2
266  S1 contains generic multibyte chars.
267 ********************************************************************/
268
269 static char *generic_multibyte_strtok(char *s1, const char *s2)
270 {
271   static char *s = NULL;
272   char *q;
273   if (!s1) {
274     if (!s) {
275       return NULL;
276     }
277     s1 = s;
278   }
279   for (q = s1; *s1; ) {
280     if ((*is_multibyte_char_1)(*s1)) {
281         s1 += 2;
282     } else {
283       char *p = strchr (s2, *s1);
284       if (p) {
285         if (s1 != q) {
286           s = s1 + 1;
287           *s1 = '\0';
288           return q;
289         }
290         q = s1 + 1;
291       }
292     s1++;
293     }
294   }
295   s = NULL;
296   if (*q) {
297     return q;
298   }
299   return NULL;
300 }
301
302 /*******************************************************************
303  search string S2 from S1
304  S1 contains generic multibyte chars.
305 ********************************************************************/
306
307 static const char *generic_multibyte_strstr(const char *s1, const char *s2)
308 {
309   size_t len = strlen (s2);
310   if (!*s2)
311     return (const char *) s1;
312   for (;*s1;) {
313     if (*s1 == *s2) {
314       if (strncmp (s1, s2, len) == 0)
315         return (const char *) s1;
316     }
317     if ((*is_multibyte_char_1)(*s1)) {
318       s1 += 2;
319     } else {
320       s1++;
321     }
322   }
323   return NULL;
324 }
325
326 /*******************************************************************
327  Search char C from beginning of S.
328  S contains generic multibyte chars.
329 ********************************************************************/
330
331 static const char *generic_multibyte_strchr(const char *s, int c)
332 {
333   for (; *s; ) {
334     if (*s == c)
335       return (const char *) s;
336     if ((*is_multibyte_char_1)(*s)) {
337       s += 2;
338     } else {
339       s++;
340     }
341   }
342   return NULL;
343 }
344
345 /*******************************************************************
346  Search char C end of S.
347  S contains generic multibyte chars.
348 ********************************************************************/
349
350 static const char *generic_multibyte_strrchr(const char *s, int c)
351 {
352   const char *q;
353  
354   for (q = 0; *s; ) {
355     if (*s == c) {
356       q = (const char *) s;
357     }
358     if ((*is_multibyte_char_1)(*s)) {
359       s += 2;
360     } else {
361       s++;
362     }
363   }
364   return q;
365 }
366
367 /*******************************************************************
368  Generic multibyte char skip function.
369 *******************************************************************/
370
371 static size_t skip_generic_multibyte_char(char c)
372 {
373   if( (*is_multibyte_char_1)(c)) {
374     return 2;
375   }
376   return 0;
377 }
378
379 /*******************************************************************
380   Code conversion
381 ********************************************************************/
382
383 /* convesion buffer */
384 static char cvtbuf[2*sizeof(pstring)];
385
386 /*******************************************************************
387   EUC <-> SJIS
388 ********************************************************************/
389
390 static int euc2sjis (int hi, int lo)
391 {
392   int w;
393   int maxidx = SJISREVTBLSIZ;
394   int minidx = 0;
395   int i = 2;
396
397   if (hi & 1) {
398     hi = hi / 2 + (hi < 0xdf ? 0x31 : 0x71);
399     w =  (hi << 8) | (lo - (lo >= 0xe0 ? 0x60 : 0x61));
400   } else {
401     hi = hi / 2 + (hi < 0xdf ? 0x30 : 0x70);
402     w = (hi << 8) | (lo - 2);
403   }
404   if  ( (0x87 < hi ) && (hi < 0xed ) ) {
405     return w;
406   }
407   while ( maxidx >= minidx ) {
408     if ( sjisrev[i].start > w ) {
409       maxidx = i-1;
410     } else if ( w > sjisrev[i].end ) {
411       minidx = i+1;
412     } else {
413       w -= sjisrev[i].start;
414       w += sjisrev[i].rstart;
415       break;
416     }
417    i = (int)( minidx + (maxidx - minidx) % 2 );  
418   }
419   return w;  
420 }
421
422 static int sjis2euc (int hi, int lo)
423 {
424   int minidx = 0;
425   int maxidx = SJISCONVTBLSIZ -1; /* max index 1 less than number of entries */
426   int i = ( 0 + SJISCONVTBLSIZ ) % 2;
427   int w = (int)((hi << 8) | lo);
428
429   if ( (sjisconv[0].start < w) && (w < sjisconv[SJISCONVTBLSIZ-1].end) ) {
430     while (maxidx >= minidx) {
431       if ( sjisconv[i].start > w ) {
432         maxidx = i-1;
433       } else if (w > sjisconv[i].end) {
434         minidx = i+1;
435       } else {
436         w -= sjisconv[i].start;
437         w += sjisconv[i].rstart;
438         break;
439       }
440       i = (int)( minidx + (maxidx-minidx)%2 );
441     }
442     hi = (int) ((w >> 8) & 0xff);
443     lo = (int) (w & 0xff);
444   }
445   if (hi >= 0xf0) {
446      hi = GETAHI;
447      lo = GETALO;
448   }
449   if (lo >= 0x9f)
450     return ((hi * 2 - (hi >= 0xe0 ? 0xe0 : 0x60)) << 8) | (lo + 2);
451   else
452     return ((hi * 2 - (hi >= 0xe0 ? 0xe1 : 0x61)) << 8) |
453             (lo + (lo >= 0x7f ? 0x60 : 0x61));
454 }
455
456 /*******************************************************************
457  Convert FROM contain SHIFT JIS codes to EUC codes
458  return converted buffer
459 ********************************************************************/
460
461 static char *sj_to_euc(char *from, BOOL overwrite)
462 {
463   char *out;
464   char *save;
465
466   save = (char *) from;
467   for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
468     if (is_shift_jis (*from)) {
469       int code = sjis2euc ((int) from[0] & 0xff, (int) from[1] & 0xff);
470       *out++ = (code >> 8) & 0xff;
471       *out++ = code & 0xff;
472       from += 2;
473     } else if (is_kana (*from)) {
474       *out++ = (char)euc_kana;
475       *out++ = *from++;
476     } else {
477       *out++ = *from++;
478     }
479   }
480   *out = 0;
481   if (overwrite) {
482     pstrcpy((char *) save, (char *) cvtbuf);
483     return (char *) save;
484   } else {
485     return cvtbuf;
486   }
487 }
488
489 /*******************************************************************
490  Convert FROM contain EUC codes to SHIFT JIS codes
491  return converted buffer
492 ********************************************************************/
493
494 static char *euc_to_sj(char *from, BOOL overwrite)
495 {
496   char *out;
497   char *save;
498
499   save = (char *) from;
500   for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3); ) {
501     if (is_euc (*from)) {
502       int code = euc2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
503       *out++ = (code >> 8) & 0xff;
504       *out++ = code & 0xff;
505       from += 2;
506     } else if (is_euc_kana (*from)) {
507       *out++ = from[1];
508       from += 2;
509     } else {
510       *out++ = *from++;
511     }
512   }
513   *out = 0;
514
515   if (overwrite) {
516         pstrcpy(save, (char *) cvtbuf); 
517     return save;
518   } else {
519     return cvtbuf;
520   }
521 }
522
523 /*******************************************************************
524   EUC3 <-> SJIS
525 ********************************************************************/
526 static int sjis3euc (int hi, int lo, int *len)
527 {
528   int i,w;
529   int minidx;
530   int maxidx;
531
532   w = (int)((hi << 8) | lo);
533
534   /* no sjis */
535  if ( ( 0x40 >= lo ) && (lo >= 0xfc) && (lo == 0x7f )) {
536      w = (GETAHI << 8) | GETALO;
537
538  /* IBM Extended Kanji */
539  } else  if (( w == 0xfa54 )||( w == 0x81ca )) {
540     *len = 2;
541     return (0xa2cc);
542
543   } else if (( w ==  0xfa5b )||( w == 0x81e6)) {
544     *len = 2;
545     return (0xa2e8);
546
547   } else if (( 0xfa <= hi ) && ( hi <= 0xfc ) ) {
548     i = w - 0xfa40 - ( hi - 0xfa )*( 0xfb40 - 0xfafc) - ((lo < 0x7f)? 0 : 1 );
549     if ( i <= EUC3CONVTBLSIZ ){
550       *len = 3;
551       return euc3conv[i];
552     }  
553
554 /* NEC selected IBM Extend Kanji */
555     /* there are 3 code that is not good for conv */
556   } else if (( 0x8754 <= w ) && ( w <= 0x878a)) {
557     minidx = 0;
558     maxidx = EUC3CONV2TBLSIZ;
559     i = minidx + (maxidx - minidx) % 2;
560     while ( maxidx >= minidx ) {
561       if ( euc3conv2[i].sjis > w ) {
562         maxidx = i-1;
563       } else if ( w > euc3conv2[i].sjis ) {
564         minidx = i+1;
565       } else {
566         *len = 3;
567         return (euc3conv2[i].euc);
568       }
569       i = (int)( minidx + (maxidx - minidx) % 2 );  
570     }
571     /* else normal EUC */
572
573   } else if (( w == 0xeef9 ) || ( w == 0x81ca )) {  
574     *len = 2; 
575     return (0xa2cc);
576
577   } else if (( 0xed <= hi ) && ( hi <= 0xef )) {
578     minidx = 0;
579     maxidx = SJISREVTBLSIZ;
580     i = 10;
581     while ( maxidx >= minidx ) {
582       if ( sjisrev[i].start > w ) {
583         maxidx = i-1;
584       } else if ( w > sjisrev[i].end ) {
585         minidx = i+1;
586       } else {
587         w -= sjisrev[i].start;
588         w += sjisrev[i].rstart;
589         break;
590       }
591       i = (int)( minidx + (maxidx - minidx) % 2 );  
592     }
593     if ( w >= 0xfa40 ) {
594       i = w - 0xfa40 - ( hi - 0xfa )*( 0xfb40 - 0xfafc) - ((lo < 0x7f)? 0 : 1 );
595       if ( i <= EUC3CONVTBLSIZ ){
596         *len = 3;
597         return euc3conv[i];
598       } else {
599         w = (GETAHI << 8) | GETALO;
600       }
601     }
602     /* else normal EUC */
603
604 /* UDC half low*/
605 /* this area maps to the G2 UDC area: 0xf5a1 -- 0xfefe */
606   } else if ((0xf0 <= hi) && (hi <= 0xf4)) {
607     *len = 2;
608     if (lo >= 0x9f) {
609       return (((hi * 2 - 0xea) << 8) | (lo + 2));
610     } else {
611       return (((hi * 2 - 0xeb) << 8) | (lo + (lo >=0x7f ? 0x60: 0x61 )));
612     }
613
614 /* UDC half high*/
615 /* this area maps to the G3 UDC area: 0xf8f5a1 -- 0xf8fefe */
616   } else if ((0xf5 <= hi) && (hi <= 0xf9)) {  
617     *len = 3;
618     if (lo >= 0x9f) {
619       return (((hi*2 - 0xf4) << 8) | (lo + 2));
620     } else {
621       return (((hi*2 - 0xf5) << 8) | (lo + (lo >= 0x7f ? 0x60: 0x61 )));
622     }
623     /* ....checked all special case */
624   }
625
626   /*  These Normal 2 byte EUC */
627   *len = 2;
628   hi = (int) ((w >> 8) & 0xff);
629   lo = (int) (w & 0xff);
630
631   if (hi >= 0xf0) {    /* Check range */
632      hi = GETAHI;
633      lo = GETALO;
634   }
635
636   if (lo >= 0x9f)
637     return ((hi * 2 - (hi >= 0xe0 ? 0xe0 : 0x60)) << 8) | (lo + 2);
638   else
639     return ((hi * 2 - (hi >= 0xe0 ? 0xe1 : 0x61)) << 8) |
640             (lo + (lo >= 0x7f ? 0x60 : 0x61));
641 }
642
643 static int  euc3sjis (int hi, int lo, BOOL is_3byte)
644 {
645   int w;
646
647   w = (int)((hi << 8) | lo);
648   if (is_3byte) {
649     if (( 0xf5 <= hi) && ( hi <= 0xfe)) {
650      /* UDC half high*/
651      /* this area maps to the G3 UDC area */
652      /* 0xf8f5a1 -- 0xf8fefe --> 0xf540 -- 0xf9fc */
653       if (hi & 1) {
654         return (((hi / 2 + 0x7b) << 8) | (lo - (lo >= 0xe0 ? 0x60 : 0x61)));
655       } else {
656         return (((hi / 2 + 0x7a) << 8) | (lo - 2));
657       }
658     } else {
659       /* Using map table */
660       int minidx = 0;
661       int maxidx = EUC3REVTBLSIZ;
662       int i = minidx + (maxidx - minidx) % 2;
663
664       while ( maxidx >= minidx ) {
665         if (euc3rev[i].euc > w) {
666           maxidx = i-1;
667         } else if (euc3rev[i].euc < w) {
668           minidx = i+1;
669         } else {
670           return (euc3rev[i].sjis);
671         }
672         i = (int)( minidx + ( maxidx - minidx ) % 2);
673       }
674       return ((GETAHI << 8 ) | GETALO);
675     }
676   } else { /* is_2byte */
677     if ((0xf5 <= hi) && (hi <= 0xfe)) {
678       /* UDC half low*/
679       /* this area maps to the G2 UDC area */
680       /* 0xf5a1 -- 0xfefe  --> 0xf040 -- 0xf4fc */
681       if (hi & 1) {
682         return (((hi / 2 + 0x76) << 8) | (lo - (lo >= 0xe0 ? 0x60 : 0x61)));
683       } else {
684         return (((hi / 2 + 0x75) << 8) | (lo - 2));
685       }
686     } else { /* Normal EUC */
687       if (hi & 1) {
688         hi = hi / 2 + (hi < 0xdf ? 0x31 : 0x71);
689         return ((hi << 8) | (lo - (lo >= 0xe0 ? 0x60 : 0x61)));
690       } else {
691         hi = hi / 2 + (hi < 0xdf ? 0x30 : 0x70);
692         return ((hi << 8) | (lo - 2));
693       }
694     }
695   }
696 }
697
698 /*******************************************************************
699  Convert FROM contain SHIFT JIS codes to EUC codes (with SS2)
700  return converted buffer
701 ********************************************************************/
702
703 static char *sj_to_euc3(char *from, BOOL overwrite)
704 {
705   char *out;
706   char *save;
707   int len;
708
709   save = (char *) from;
710   for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4);) {
711     if (is_shift_jis (*from)) {
712       int code = sjis3euc ((int) from[0] & 0xff, (int) from[1] & 0xff, &len);
713       if (len == 3) {
714         *out++ = (char)euc_sup;
715       }
716       *out++ = (code >> 8) & 0xff;
717       *out++ = code & 0xff;
718       from += 2;
719     } else if (is_kana (*from)) {
720       *out++ = (char)euc_kana;
721       *out++ = *from++;
722     } else {
723       *out++ = *from++;
724     }
725   }
726   *out = 0;
727   if (overwrite) {
728     pstrcpy((char *) save, (char *) cvtbuf);
729     return (char *) save;
730   } else {
731     return cvtbuf;
732   }
733 }
734
735 /*******************************************************************
736  Convert FROM contain EUC codes (with Sup-Kanji) to SHIFT JIS codes
737  return converted buffer
738 ********************************************************************/
739 static char *euc3_to_sj(char *from, BOOL overwrite)
740 {
741   char *out;
742   char *save;
743
744   save = (char *) from;
745   for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3); ) {
746     if (is_euc_sup (*from)) {
747       int code = euc3sjis((int) from[1] & 0xff, (int) from[2] & 0xff, True);
748       *out++ = (code >> 8) & 0xff;
749       *out++ = code & 0xff;
750       from += 3;
751     } else if (is_euc (*from)) {
752       int code = euc3sjis ((int) from[0] & 0xff, (int) from[1] & 0xff,False);
753       *out++ = (code >> 8) & 0xff;
754       *out++ = code & 0xff;
755       from += 2;
756     } else if (is_euc_kana (*from)) {
757       *out++ = from[1];
758       from += 2;
759     } else {
760       *out++ = *from++;
761     }
762   }
763   *out = 0;
764
765   if (overwrite) {
766         pstrcpy(save, (char *) cvtbuf); 
767     return save;
768   } else {
769     return cvtbuf;
770   }
771 }
772
773 /*******************************************************************
774   JIS7,JIS8,JUNET <-> SJIS
775 ********************************************************************/
776
777 static int sjis2jis(int hi, int lo)
778 {
779   int minidx = 0;
780   int maxidx = SJISCONVTBLSIZ -1; /* max index 1 less than number of entries */
781   int i = (0 + SJISCONVTBLSIZ) % 2;
782   int w = (int)((hi << 8) | lo);
783
784   if ((sjisconv[0].start < w) && (w < sjisconv[SJISCONVTBLSIZ-1].end)) {
785     while (maxidx >= minidx) {
786       if (sjisconv[i].start > w) {
787         maxidx = i-1;
788       } else if (w > sjisconv[i].end) {
789         minidx = i+1;
790       } else {
791         w -= sjisconv[i].start;
792         w += sjisconv[i].rstart;
793         break;
794       }
795       i = (int)( minidx + (maxidx-minidx) %2 );
796     }
797     hi = (int) ((w >> 8) & 0xff);
798     lo = (int) (w & 0xff);
799   }
800   if (hi >= 0xf0) {
801      hi = GETAHI;
802      lo = GETALO;
803   }
804   if (lo >= 0x9f)
805     return ((hi * 2 - (hi >= 0xe0 ? 0x160 : 0xe0)) << 8) | (lo - 0x7e);
806   else
807     return ((hi * 2 - (hi >= 0xe0 ? 0x161 : 0xe1)) << 8) |
808             (lo - (lo >= 0x7f ? 0x20 : 0x1f));
809 }
810
811 static int jis2sjis(int hi, int lo)
812 {
813   int w;
814   int minidx = 0;
815   int maxidx = SJISREVTBLSIZ;
816   int i = 2;
817
818   if (hi & 1) {
819     hi = hi / 2 + (hi < 0x5f ? 0x71 : 0xb1);
820     w  = (hi << 8) | (lo + (lo >= 0x60 ? 0x20 : 0x1f));
821   } else {
822     hi = hi / 2 + (hi < 0x5f ? 0x70 : 0xb0); 
823     w  = (hi << 8) | (lo + 0x7e);
824   }
825
826   if  (( 0x87 < hi ) && ( hi < 0xed )) {
827     return w;
828   }
829   while (maxidx >= minidx) {
830     if (sjisrev[i].start > w) {
831       maxidx = i-1;
832     } else if (w > sjisrev[i].end) {
833       minidx = i+1;
834     } else {
835       w -= sjisrev[i].start;
836       w += sjisrev[i].rstart;
837       break;
838     }
839     i = (int)( minidx + (maxidx-minidx) %2 );
840   }
841   return w;  
842 }
843
844 /*******************************************************************
845  Convert FROM contain JIS codes to SHIFT JIS codes
846  return converted buffer
847 ********************************************************************/
848
849 static char *jis8_to_sj(char *from, BOOL overwrite)
850 {
851   char *out;
852   int shifted;
853   char *save;
854
855   shifted = _KJ_ROMAN;
856   save = (char *) from;
857   for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
858     if (is_esc (*from)) {
859       if (is_so1 (from[1]) && is_so2 (from[2])) {
860         shifted = _KJ_KANJI;
861         from += 3;
862       } else if (is_si1 (from[1]) && is_si2 (from[2])) {
863         shifted = _KJ_ROMAN;
864         from += 3;
865       } else { /* sequence error */
866         goto normal;
867       }
868     } else {
869
870 normal:
871
872       switch (shifted) {
873       default:
874       case _KJ_ROMAN:
875         *out++ = *from++;
876         break;
877       case _KJ_KANJI:
878         {
879           int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
880           *out++ = (code >> 8) & 0xff;
881           *out++ = code;
882           from += 2;
883           break;
884         }
885       }
886     }
887   }
888
889   *out = 0;
890   if (overwrite) {
891     pstrcpy (save, (char *) cvtbuf);
892     return save;
893   } else {
894     return cvtbuf;
895   }
896 }
897
898 /*******************************************************************
899  Convert FROM contain SHIFT JIS codes to JIS codes
900  return converted buffer
901 ********************************************************************/
902
903 static char *sj_to_jis8(char *from, BOOL overwrite)
904 {
905   char *out;
906   int shifted;
907   char *save;
908
909   shifted = _KJ_ROMAN;
910   save = (char *) from;
911   for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
912     if (is_shift_jis (*from)) {
913       int code;
914       switch (shifted) {
915       case _KJ_ROMAN: /* to KANJI */
916         *out++ = jis_esc;
917         *out++ = jis_so1;
918         *out++ = jis_kso;
919         shifted = _KJ_KANJI;
920         break;
921       }
922       code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
923       *out++ = (code >> 8) & 0xff;
924       *out++ = code;
925       from += 2;
926     } else {
927       switch (shifted) {
928       case _KJ_KANJI: /* to ROMAN/KANA */
929         *out++ = jis_esc;
930         *out++ = jis_si1;
931         *out++ = jis_ksi;
932         shifted = _KJ_ROMAN;
933         break;
934       }
935       *out++ = *from++;
936     }
937   }
938
939   switch (shifted) {
940   case _KJ_KANJI: /* to ROMAN/KANA */
941     *out++ = jis_esc;
942     *out++ = jis_si1;
943     *out++ = jis_ksi;
944     shifted = _KJ_ROMAN;
945     break;
946   }
947   *out = 0;
948   if (overwrite) {
949     pstrcpy (save, (char *) cvtbuf);
950     return save;
951   } else {
952     return cvtbuf;
953   }
954 }
955
956 /*******************************************************************
957  Convert FROM contain 7 bits JIS codes to SHIFT JIS codes
958  return converted buffer
959 ********************************************************************/
960 static char *jis7_to_sj(char *from, BOOL overwrite)
961 {
962     char *out;
963     int shifted;
964     char *save;
965
966     shifted = _KJ_ROMAN;
967     save = (char *) from;
968     for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
969         if (is_esc (*from)) {
970             if (is_so1 (from[1]) && is_so2 (from[2])) {
971                 shifted = _KJ_KANJI;
972                 from += 3;
973             } else if (is_si1 (from[1]) && is_si2 (from[2])) {
974                 shifted = _KJ_ROMAN;
975                 from += 3;
976             } else {                    /* sequence error */
977                 goto normal;
978             }
979         } else if (is_so (*from)) {
980             shifted = _KJ_KANA;         /* to KANA */
981             from++;
982         } else if (is_si (*from)) {
983             shifted = _KJ_ROMAN;        /* to ROMAN */
984             from++;
985         } else {
986         normal:
987             switch (shifted) {
988             default:
989             case _KJ_ROMAN:
990                 *out++ = *from++;
991                 break;
992             case _KJ_KANJI:
993                 {
994                     int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
995                     *out++ = (code >> 8) & 0xff;
996                     *out++ = code;
997                     from += 2;
998                 }
999                 break;
1000             case _KJ_KANA:
1001                 *out++ = ((int) from[0]) + 0x80;
1002                 break;
1003             }
1004         }
1005     }
1006     *out = 0;
1007     if (overwrite) {
1008         pstrcpy (save, (char *) cvtbuf);
1009         return save;
1010     } else {
1011         return cvtbuf;
1012     }
1013 }
1014
1015 /*******************************************************************
1016  Convert FROM contain SHIFT JIS codes to 7 bits JIS codes
1017  return converted buffer
1018 ********************************************************************/
1019 static char *sj_to_jis7(char *from, BOOL overwrite)
1020 {
1021     char *out;
1022     int shifted;
1023     char *save;
1024
1025     shifted = _KJ_ROMAN;
1026     save = (char *) from;
1027     for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
1028         if (is_shift_jis (*from)) {
1029             int code;
1030             switch (shifted) {
1031             case _KJ_KANA:
1032                 *out++ = jis_si;        /* to ROMAN and through down */
1033             case _KJ_ROMAN:             /* to KANJI */
1034                 *out++ = jis_esc;
1035                 *out++ = jis_so1;
1036                 *out++ = jis_kso;
1037                 shifted = _KJ_KANJI;
1038                 break;
1039             }
1040             code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
1041             *out++ = (code >> 8) & 0xff;
1042             *out++ = code;
1043             from += 2;
1044         } else if (is_kana (from[0])) {
1045             switch (shifted) {
1046             case _KJ_KANJI:             /* to ROMAN */
1047                 *out++ = jis_esc;
1048                 *out++ = jis_si1;
1049                 *out++ = jis_ksi;
1050             case _KJ_ROMAN:             /* to KANA */
1051                 *out++ = jis_so;
1052                 shifted = _KJ_KANA;
1053                 break;
1054             }
1055             *out++ = ((int) *from++) - 0x80;
1056         } else {
1057             switch (shifted) {
1058             case _KJ_KANA:
1059                 *out++ = jis_si;        /* to ROMAN */
1060                 shifted = _KJ_ROMAN;
1061                 break;
1062             case _KJ_KANJI:             /* to ROMAN */
1063                 *out++ = jis_esc;
1064                 *out++ = jis_si1;
1065                 *out++ = jis_ksi;
1066                 shifted = _KJ_ROMAN;
1067                 break;
1068             }
1069             *out++ = *from++;
1070         }
1071     }
1072     switch (shifted) {
1073     case _KJ_KANA:
1074         *out++ = jis_si;                /* to ROMAN */
1075         break;
1076     case _KJ_KANJI:                     /* to ROMAN */
1077         *out++ = jis_esc;
1078         *out++ = jis_si1;
1079         *out++ = jis_ksi;
1080         break;
1081     }
1082     *out = 0;
1083     if (overwrite) {
1084         pstrcpy (save, (char *) cvtbuf);
1085         return save;
1086     } else {
1087         return cvtbuf;
1088     }
1089 }
1090
1091 /*******************************************************************
1092  Convert FROM contain 7 bits JIS(junet) codes to SHIFT JIS codes
1093  return converted buffer
1094 ********************************************************************/
1095
1096 static char *junet_to_sj(char *from, BOOL overwrite)
1097 {
1098     char *out;
1099     int shifted;
1100     char *save;
1101
1102     shifted = _KJ_ROMAN;
1103     save = (char *) from;
1104     for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
1105         if (is_esc (*from)) {
1106             if (is_so1 (from[1]) && is_so2 (from[2])) {
1107                 shifted = _KJ_KANJI;
1108                 from += 3;
1109             } else if (is_si1 (from[1]) && is_si2 (from[2])) {
1110                 shifted = _KJ_ROMAN;
1111                 from += 3;
1112             } else if (is_juk1(from[1]) && is_juk2 (from[2])) {
1113                 shifted = _KJ_KANA;
1114                 from += 3;
1115             } else {                    /* sequence error */
1116                 goto normal;
1117             }
1118         } else {
1119         normal:
1120             switch (shifted) {
1121             default:
1122             case _KJ_ROMAN:
1123                 *out++ = *from++;
1124                 break;
1125             case _KJ_KANJI:
1126                 {
1127                     int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
1128                     *out++ = (code >> 8) & 0xff;
1129                     *out++ = code;
1130                     from += 2;
1131                 }
1132                 break;
1133             case _KJ_KANA:
1134                 *out++ = ((int) from[0]) + 0x80;
1135                 break;
1136             }
1137         }
1138     }
1139     *out = 0;
1140     if (overwrite) {
1141         pstrcpy (save, (char *) cvtbuf);
1142         return save;
1143     } else {
1144         return cvtbuf;
1145     }
1146 }
1147
1148 /*******************************************************************
1149  Convert FROM contain SHIFT JIS codes to 7 bits JIS(junet) codes
1150  return converted buffer
1151 ********************************************************************/
1152 static char *sj_to_junet(char *from, BOOL overwrite)
1153 {
1154     char *out;
1155     int shifted;
1156     char *save;
1157
1158     shifted = _KJ_ROMAN;
1159     save = (char *) from;
1160     for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
1161         if (is_shift_jis (*from)) {
1162             int code;
1163             switch (shifted) {
1164             case _KJ_KANA:
1165             case _KJ_ROMAN:             /* to KANJI */
1166                 *out++ = jis_esc;
1167                 *out++ = jis_so1;
1168                 *out++ = jis_so2;
1169                 shifted = _KJ_KANJI;
1170                 break;
1171             }
1172             code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
1173             *out++ = (code >> 8) & 0xff;
1174             *out++ = code;
1175             from += 2;
1176         } else if (is_kana (from[0])) {
1177             switch (shifted) {
1178             case _KJ_KANJI:             /* to ROMAN */
1179             case _KJ_ROMAN:             /* to KANA */
1180                 *out++ = jis_esc;
1181                 *out++ = junet_kana1;
1182                 *out++ = junet_kana2;
1183                 shifted = _KJ_KANA;
1184                 break;
1185             }
1186             *out++ = ((int) *from++) - 0x80;
1187         } else {
1188             switch (shifted) {
1189             case _KJ_KANA:
1190             case _KJ_KANJI:             /* to ROMAN */
1191                 *out++ = jis_esc;
1192                 *out++ = jis_si1;
1193                 *out++ = jis_si2;
1194                 shifted = _KJ_ROMAN;
1195                 break;
1196             }
1197             *out++ = *from++;
1198         }
1199     }
1200     switch (shifted) {
1201     case _KJ_KANA:
1202     case _KJ_KANJI:                     /* to ROMAN */
1203         *out++ = jis_esc;
1204         *out++ = jis_si1;
1205         *out++ = jis_si2;
1206         break;
1207     }
1208     *out = 0;
1209     if (overwrite) {
1210         pstrcpy (save, (char *) cvtbuf);
1211         return save;
1212     } else {
1213         return cvtbuf;
1214     }
1215 }
1216
1217 /*******************************************************************
1218   HEX <-> SJIS
1219 ********************************************************************/
1220 /* ":xx" -> a byte */
1221 static char *hex_to_sj(char *from, BOOL overwrite)
1222 {
1223     char *sp, *dp;
1224     
1225     sp = (char *) from;
1226     dp = cvtbuf;
1227     while (*sp && (dp - cvtbuf < sizeof(cvtbuf)-3)) {
1228         if (*sp == hex_tag && isxdigit((int)sp[1]) && isxdigit((int)sp[2])) {
1229             *dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2]));
1230             sp += 3;
1231         } else
1232             *dp++ = *sp++;
1233     }
1234     *dp = '\0';
1235     if (overwrite) {
1236         pstrcpy ((char *) from, (char *) cvtbuf);
1237         return (char *) from;
1238     } else {
1239         return cvtbuf;
1240     }
1241 }
1242  
1243 /*******************************************************************
1244   kanji/kana -> ":xx" 
1245 ********************************************************************/
1246 static char *sj_to_hex(char *from, BOOL overwrite)
1247 {
1248     unsigned char *sp, *dp;
1249     
1250     sp = (unsigned char*) from;
1251     dp = (unsigned char*) cvtbuf;
1252     while (*sp && (((char *)dp)- cvtbuf < sizeof(cvtbuf)-7)) {
1253         if (is_kana(*sp)) {
1254             *dp++ = hex_tag;
1255             *dp++ = bin2hex (((*sp)>>4)&0x0f);
1256             *dp++ = bin2hex ((*sp)&0x0f);
1257             sp++;
1258         } else if (is_shift_jis (*sp) && is_shift_jis2 (sp[1])) {
1259             *dp++ = hex_tag;
1260             *dp++ = bin2hex (((*sp)>>4)&0x0f);
1261             *dp++ = bin2hex ((*sp)&0x0f);
1262             sp++;
1263             *dp++ = hex_tag;
1264             *dp++ = bin2hex (((*sp)>>4)&0x0f);
1265             *dp++ = bin2hex ((*sp)&0x0f);
1266             sp++;
1267         } else
1268             *dp++ = *sp++;
1269     }
1270     *dp = '\0';
1271     if (overwrite) {
1272         pstrcpy ((char *) from, (char *) cvtbuf);
1273         return (char *) from;
1274     } else {
1275         return cvtbuf;
1276     }
1277 }
1278
1279 /*******************************************************************
1280   CAP <-> SJIS
1281 ********************************************************************/
1282 /* ":xx" CAP -> a byte */
1283 static char *cap_to_sj(char *from, BOOL overwrite)
1284 {
1285     char *sp, *dp;
1286
1287     sp = (char *) from;
1288     dp = cvtbuf;
1289     while (*sp && (dp- cvtbuf < sizeof(cvtbuf)-2)) {
1290         /*
1291          * The only change between this and hex_to_sj is here. sj_to_cap only
1292          * translates characters greater or equal to 0x80 - make sure that here
1293          * we only do the reverse (that's why the strchr is used rather than
1294          * isxdigit. Based on fix from ado@elsie.nci.nih.gov (Arthur David Olson).
1295          */
1296         if (*sp == hex_tag && (strchr ("89abcdefABCDEF", sp[1]) != NULL) && isxdigit((int)sp[2])) {
1297             *dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2]));
1298             sp += 3;
1299         } else
1300             *dp++ = *sp++;
1301     }
1302     *dp = '\0';
1303     if (overwrite) {
1304         pstrcpy ((char *) from, (char *) cvtbuf);
1305         return (char *) from;
1306     } else {
1307         return cvtbuf;
1308     }
1309 }
1310
1311 /*******************************************************************
1312   kanji/kana -> ":xx" - CAP format.
1313 ********************************************************************/
1314 static char *sj_to_cap(char *from, BOOL overwrite)
1315 {
1316     unsigned char *sp, *dp;
1317
1318     sp = (unsigned char*) from;
1319     dp = (unsigned char*) cvtbuf;
1320     while (*sp && (((char *)dp) - cvtbuf < sizeof(cvtbuf)-4)) {
1321         if (*sp >= 0x80) {
1322             *dp++ = hex_tag;
1323             *dp++ = bin2hex (((*sp)>>4)&0x0f);
1324             *dp++ = bin2hex ((*sp)&0x0f);
1325             sp++;
1326         } else {
1327             *dp++ = *sp++;
1328         }
1329     }
1330     *dp = '\0';
1331     if (overwrite) {
1332         pstrcpy ((char *) from, (char *) cvtbuf);
1333         return (char *) from;
1334     } else {
1335         return cvtbuf;
1336     }
1337 }
1338
1339 /*******************************************************************
1340  sj to sj
1341 ********************************************************************/
1342 static char *sj_to_sj(char *from, BOOL overwrite)
1343 {
1344     if (!overwrite) {
1345         pstrcpy (cvtbuf, (char *) from);
1346         return cvtbuf;
1347     } else {
1348         return (char *) from;
1349     }
1350 }
1351
1352 /*******************************************************************
1353  cp to utf8
1354 ********************************************************************/
1355 static char *cp_to_utf8(char *from, BOOL overwrite)
1356 {
1357   unsigned char *dst;
1358   unsigned char *src;
1359   smb_ucs2_t val;
1360   int w;
1361   size_t len;
1362
1363   src = (unsigned char *)from;
1364   dst = (unsigned char *)cvtbuf;
1365   while (*src && (((char *)dst - cvtbuf) < sizeof(cvtbuf)-4)) {
1366     len = _skip_multibyte_char(*src);
1367     if ( len == 2 ) {
1368       w = (int)(*src++ & 0xff);
1369       w = (int)((w << 8)|(*src++ & 0xff));
1370     } else {
1371       w = (int)(*src++ & 0xff);
1372     }
1373     val = doscp2ucs2(w);
1374
1375     if ( val <= 0x7f ) {
1376       *dst++ = (char)(val & 0xff);
1377     } else if ( val <= 0x7ff ){
1378       *dst++ = (char)( 0xc0 | ((val >> 6) & 0xff)); 
1379       *dst++ = (char)( 0x80 | ( val & 0x3f ));
1380     } else {
1381       *dst++ = (char)( 0xe0 | ((val >> 12) & 0x0f));
1382       *dst++ = (char)( 0x80 | ((val >> 6)  & 0x3f));
1383       *dst++ = (char)( 0x80 | (val & 0x3f));
1384     }
1385
1386   }
1387   *dst++='\0';
1388   if (overwrite) {
1389     pstrcpy ((char *) from, (char *) cvtbuf);
1390     return (char *) from;
1391   } else {
1392     return cvtbuf;
1393   }
1394 }
1395
1396 /*******************************************************************
1397  utf8 to cp
1398 ********************************************************************/
1399 static char *utf8_to_cp(char *from, BOOL overwrite)
1400 {
1401   unsigned char *src;
1402   unsigned char *dst;
1403   smb_ucs2_t val;
1404   int w;
1405
1406   src = (unsigned char *)from; 
1407   dst = (unsigned char *)cvtbuf; 
1408
1409   while (*src && ((char *)dst - cvtbuf < sizeof(cvtbuf)-4)) {
1410     val = (*src++ & 0xff);
1411     if (val < 0x80) {
1412       *dst++ = (char)(val & 0x7f); 
1413     } else if ((0xc0 <= val) && (val <= 0xdf) 
1414                && (0x80 <= *src) && (*src <= 0xbf)) {
1415       w = ucs2doscp( ((val & 31) << 6)  | ((*src++) & 63 ));
1416       *dst++ = (char)((w >> 8) & 0xff);
1417       *dst++ = (char)(w & 0xff);
1418     } else {
1419       val  = (val & 0x0f) << 12;
1420       val |= ((*src++ & 0x3f) << 6);
1421       val |= (*src++ & 0x3f);
1422       w = ucs2doscp(val);
1423       *dst++ = (char)((w >> 8) & 0xff);
1424       *dst++ = (char)(w & 0xff);
1425     }
1426   }
1427   *dst++='\0';
1428   if (overwrite) {
1429     pstrcpy ((char *) from, (char *) cvtbuf);
1430     return (char *) from;
1431   } else {
1432     return cvtbuf;
1433   }
1434 }
1435
1436 /************************************************************************
1437  conversion:
1438  _dos_to_unix           _unix_to_dos
1439 ************************************************************************/
1440
1441 static void setup_string_function(int codes)
1442 {
1443     switch (codes) {
1444     default:
1445         _dos_to_unix = dos2unix_format;
1446         _unix_to_dos = unix2dos_format;
1447         break;
1448
1449     case SJIS_CODE:
1450         _dos_to_unix = sj_to_sj;
1451         _unix_to_dos = sj_to_sj;
1452         break;
1453         
1454     case EUC_CODE:
1455         _dos_to_unix = sj_to_euc;
1456         _unix_to_dos = euc_to_sj;
1457         break;
1458         
1459     case JIS7_CODE:
1460         _dos_to_unix = sj_to_jis7;
1461         _unix_to_dos = jis7_to_sj;
1462         break;
1463
1464     case JIS8_CODE:
1465         _dos_to_unix = sj_to_jis8;
1466         _unix_to_dos = jis8_to_sj;
1467         break;
1468
1469     case JUNET_CODE:
1470         _dos_to_unix = sj_to_junet;
1471         _unix_to_dos = junet_to_sj;
1472         break;
1473
1474     case HEX_CODE:
1475         _dos_to_unix = sj_to_hex;
1476         _unix_to_dos = hex_to_sj;
1477         break;
1478
1479     case CAP_CODE:
1480         _dos_to_unix = sj_to_cap;
1481         _unix_to_dos = cap_to_sj;
1482         break;
1483     case UTF8_CODE:
1484         _dos_to_unix = cp_to_utf8;
1485         _unix_to_dos = utf8_to_cp;
1486         break;
1487     case EUC3_CODE:
1488         _dos_to_unix = sj_to_euc3;
1489         _unix_to_dos = euc3_to_sj;
1490         break;
1491     }
1492 }
1493
1494 /************************************************************************
1495  Interpret coding system.
1496 ************************************************************************/
1497
1498 void interpret_coding_system(char *str)
1499 {
1500     int codes = UNKNOWN_CODE;
1501     
1502     if (strequal (str, "sjis")) {
1503         codes = SJIS_CODE;
1504     } else if (strequal (str, "euc")) {
1505         codes = EUC_CODE;
1506     } else if (strequal (str, "cap")) {
1507         codes = CAP_CODE;
1508         hex_tag = HEXTAG;
1509     } else if (strequal (str, "hex")) {
1510         codes = HEX_CODE;
1511         hex_tag = HEXTAG;
1512     } else if (!strncasecmp (str, "hex", 3)) {
1513         codes = HEX_CODE;
1514         hex_tag = (str[3] ? str[3] : HEXTAG);
1515     } else if (strequal (str, "j8bb")) {
1516         codes = JIS8_CODE;
1517         jis_kso = 'B';
1518         jis_ksi = 'B';
1519     } else if (strequal (str, "j8bj") || strequal (str, "jis8")) {
1520         codes = JIS8_CODE;
1521         jis_kso = 'B';
1522         jis_ksi = 'J';
1523     } else if (strequal (str, "j8bh")) {
1524         codes = JIS8_CODE;
1525         jis_kso = 'B';
1526         jis_ksi = 'H';
1527     } else if (strequal (str, "j8@b")) {
1528         codes = JIS8_CODE;
1529         jis_kso = '@';
1530         jis_ksi = 'B';
1531     } else if (strequal (str, "j8@j")) {
1532         codes = JIS8_CODE;
1533         jis_kso = '@';
1534         jis_ksi = 'J';
1535     } else if (strequal (str, "j8@h")) {
1536         codes = JIS8_CODE;
1537         jis_kso = '@';
1538         jis_ksi = 'H';
1539     } else if (strequal (str, "j7bb")) {
1540         codes = JIS7_CODE;
1541         jis_kso = 'B';
1542         jis_ksi = 'B';
1543     } else if (strequal (str, "j7bj") || strequal (str, "jis7")) {
1544         codes = JIS7_CODE;
1545         jis_kso = 'B';
1546         jis_ksi = 'J';
1547     } else if (strequal (str, "j7bh")) {
1548         codes = JIS7_CODE;
1549         jis_kso = 'B';
1550         jis_ksi = 'H';
1551     } else if (strequal (str, "j7@b")) {
1552         codes = JIS7_CODE;
1553         jis_kso = '@';
1554         jis_ksi = 'B';
1555     } else if (strequal (str, "j7@j")) {
1556         codes = JIS7_CODE;
1557         jis_kso = '@';
1558         jis_ksi = 'J';
1559     } else if (strequal (str, "j7@h")) {
1560         codes = JIS7_CODE;
1561         jis_kso = '@';
1562         jis_ksi = 'H';
1563     } else if (strequal (str, "jubb")) {
1564         codes = JUNET_CODE;
1565         jis_kso = 'B';
1566         jis_ksi = 'B';
1567     } else if (strequal (str, "jubj") || strequal (str, "junet")) {
1568         codes = JUNET_CODE;
1569         jis_kso = 'B';
1570         jis_ksi = 'J';
1571     } else if (strequal (str, "jubh")) {
1572         codes = JUNET_CODE;
1573         jis_kso = 'B';
1574         jis_ksi = 'H';
1575     } else if (strequal (str, "ju@b")) {
1576         codes = JUNET_CODE;
1577         jis_kso = '@';
1578         jis_ksi = 'B';
1579     } else if (strequal (str, "ju@j")) {
1580         codes = JUNET_CODE;
1581         jis_kso = '@';
1582         jis_ksi = 'J';
1583     } else if (strequal (str, "ju@h")) {
1584         codes = JUNET_CODE;
1585         jis_kso = '@';
1586         jis_ksi = 'H';
1587     } else if (strequal (str, "utf8")) {
1588       codes = UTF8_CODE;
1589     } else if (strequal (str, "euc3")) {
1590       codes = EUC3_CODE;
1591     }   
1592     setup_string_function (codes);
1593 }
1594
1595 /*******************************************************************
1596  Non multibyte char function.
1597 *******************************************************************/
1598    
1599 static size_t skip_non_multibyte_char(char c)
1600 {
1601   return 0;
1602 }
1603
1604 /*******************************************************************
1605  Function that always says a character isn't multibyte.
1606 *******************************************************************/
1607
1608 static BOOL not_multibyte_char_1(char c)
1609 {
1610   return False;
1611 }
1612
1613 /*******************************************************************
1614  Setup the function pointers for the functions that are replaced
1615  when multi-byte codepages are used.
1616
1617  The dos_to_unix and unix_to_dos function pointers are only
1618  replaced by setup_string_function called by interpret_coding_system
1619  above.
1620 *******************************************************************/
1621
1622 void initialize_multibyte_vectors( int client_codepage)
1623 {
1624   switch( client_codepage )
1625   {
1626   case KANJI_CODEPAGE:
1627     multibyte_strchr = sj_strchr;
1628     multibyte_strrchr = sj_strrchr;
1629     multibyte_strstr = sj_strstr;
1630     multibyte_strtok = sj_strtok;
1631     _skip_multibyte_char = skip_kanji_multibyte_char;
1632     is_multibyte_char_1 = is_kanji_multibyte_char_1;
1633     global_is_multibyte_codepage = True;
1634     break;
1635   case HANGUL_CODEPAGE:
1636     multibyte_strchr = generic_multibyte_strchr;
1637     multibyte_strrchr = generic_multibyte_strrchr;
1638     multibyte_strstr = generic_multibyte_strstr;
1639     multibyte_strtok = generic_multibyte_strtok;
1640     _skip_multibyte_char = skip_generic_multibyte_char;
1641     is_multibyte_char_1 = hangul_is_multibyte_char_1;
1642     global_is_multibyte_codepage = True;
1643     break;
1644   case BIG5_CODEPAGE:
1645     multibyte_strchr = generic_multibyte_strchr;
1646     multibyte_strrchr = generic_multibyte_strrchr;
1647     multibyte_strstr = generic_multibyte_strstr;
1648     multibyte_strtok = generic_multibyte_strtok;
1649     _skip_multibyte_char = skip_generic_multibyte_char;
1650     is_multibyte_char_1 = big5_is_multibyte_char_1;
1651     global_is_multibyte_codepage = True;
1652     break;
1653   case SIMPLIFIED_CHINESE_CODEPAGE:
1654     multibyte_strchr = generic_multibyte_strchr;
1655     multibyte_strrchr = generic_multibyte_strrchr;
1656     multibyte_strstr = generic_multibyte_strstr;
1657     multibyte_strtok = generic_multibyte_strtok;
1658     _skip_multibyte_char = skip_generic_multibyte_char;
1659     is_multibyte_char_1 = simpch_is_multibyte_char_1;
1660     global_is_multibyte_codepage = True;
1661     break;
1662   /*
1663    * Single char size code page.
1664    */
1665   default:
1666     multibyte_strchr = (const char *(*)(const char *, int )) strchr;
1667     multibyte_strrchr = (const char *(*)(const char *, int )) strrchr;
1668     multibyte_strstr = (const char *(*)(const char *, const char *)) strstr;
1669     multibyte_strtok = (char *(*)(char *, const char *)) strtok;
1670     _skip_multibyte_char = skip_non_multibyte_char;
1671     is_multibyte_char_1 = not_multibyte_char_1;
1672     global_is_multibyte_codepage = False;
1673     break; 
1674   }
1675 }