~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/lib/X11/lcJis.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Xorg: lcJis.c,v 1.3 2000/08/17 19:45:18 cpqbld Exp $ */
 
2
/*
 
3
 * Copyright 1992, 1993 by TOSHIBA Corp.
 
4
 *
 
5
 * Permission to use, copy, modify, and distribute this software and its
 
6
 * documentation for any purpose and without fee is hereby granted, provided
 
7
 * that the above copyright notice appear in all copies and that both that
 
8
 * copyright notice and this permission notice appear in supporting
 
9
 * documentation, and that the name of TOSHIBA not be used in advertising
 
10
 * or publicity pertaining to distribution of the software without specific,
 
11
 * written prior permission. TOSHIBA make no representations about the
 
12
 * suitability of this software for any purpose.  It is provided "as is"
 
13
 * without express or implied warranty.
 
14
 *
 
15
 * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 
16
 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 
17
 * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 
18
 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 
19
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 
20
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 
21
 * SOFTWARE.
 
22
 *
 
23
 * Author: Katsuhisa Yano       TOSHIBA Corp.
 
24
 *                              mopi@osa.ilab.toshiba.co.jp
 
25
 */
 
26
/* $XFree86: xc/lib/X11/lcJis.c,v 1.10 2003/01/20 04:05:31 dawes Exp $ */
 
27
 
 
28
/*
 
29
 * A Japanese JIS locale.
 
30
 * Supports: all locales with codeset JIS7.
 
31
 * How: Provides converters for JIS.
 
32
 * Platforms: Only those defining X_LOCALE (only Lynx, Linux-libc5, OS/2).
 
33
 */
 
34
 
 
35
#ifdef X_LOCALE
 
36
 
 
37
#include "Xlibint.h"
 
38
#include "XlcGeneric.h"
 
39
#include <stdio.h>
 
40
 
 
41
#if !defined(macII) && !defined(X_LOCALE)
 
42
#define STDCVT
 
43
#endif
 
44
 
 
45
typedef struct _StateRec {
 
46
    XLCd lcd;
 
47
    XlcCharSet charset;
 
48
    XlcCharSet GL_charset;
 
49
    XlcCharSet GR_charset;
 
50
} StateRec, *State;
 
51
 
 
52
static void
 
53
init_state(
 
54
    XlcConv conv)
 
55
{
 
56
    State state = (State) conv->state;
 
57
    XLCdGenericPart *gen = XLC_GENERIC_PART(state->lcd);
 
58
    CodeSet codeset;
 
59
 
 
60
    codeset = gen->initial_state_GL;
 
61
    if (codeset && codeset->charset_list)
 
62
        state->GL_charset = *codeset->charset_list;
 
63
    codeset = gen->initial_state_GR;
 
64
    if (codeset && codeset->charset_list)
 
65
        state->GR_charset = *codeset->charset_list;
 
66
 
 
67
    if (state->GL_charset == NULL)
 
68
        if ((codeset = *gen->codeset_list) != NULL)
 
69
            state->GL_charset = *codeset->charset_list;
 
70
}
 
71
 
 
72
static int
 
73
compare(
 
74
    const char *src,
 
75
    const char *encoding,
 
76
    int length)
 
77
{
 
78
    const char *start = src;
 
79
 
 
80
    while (length-- > 0) {
 
81
        if (*src++ != *encoding++)
 
82
            return 0;
 
83
        if (*encoding == '\0')
 
84
            return src - start;
 
85
    }
 
86
 
 
87
    return 0;
 
88
}
 
89
 
 
90
static int
 
91
mbtocs(
 
92
    XlcConv conv,
 
93
    XPointer *from,
 
94
    int *from_left,
 
95
    XPointer *to,
 
96
    int *to_left,
 
97
    XPointer *args,
 
98
    int num_args)
 
99
{
 
100
    State state = (State) conv->state;
 
101
    XLCd lcd = state->lcd;
 
102
    const char *src;
 
103
    char *dst;
 
104
    unsigned char *mb_parse_table;
 
105
    ParseInfo *parse_list, parse_info;
 
106
    XlcCharSet charset;
 
107
    int length, number, encoding_len = 0;
 
108
    int i;
 
109
 
 
110
    src = *((const char **) from);
 
111
    dst = *((char **) to);
 
112
 
 
113
    mb_parse_table = XLC_GENERIC(lcd, mb_parse_table);
 
114
    if (mb_parse_table != NULL) {
 
115
        number = mb_parse_table[(unsigned char) *src];
 
116
        if (number > 0) {
 
117
            parse_list = XLC_GENERIC(lcd, mb_parse_list) + number - 1;
 
118
            for ( ; (parse_info = *parse_list) != NULL; parse_list++) {
 
119
                encoding_len = compare(src, parse_info->encoding, *from_left);
 
120
                if (encoding_len > 0) {
 
121
                    switch (parse_info->type) {
 
122
                        case E_SS:
 
123
                            src += encoding_len;
 
124
                            charset = *parse_info->codeset->charset_list;
 
125
                            goto found;
 
126
                        case E_LSL:
 
127
                        case E_LSR:
 
128
                            src += encoding_len;
 
129
                            charset = *parse_info->codeset->charset_list;
 
130
                            if (parse_info->type == E_LSL)
 
131
                                state->GL_charset = charset;
 
132
                            else
 
133
                                state->GR_charset = charset;
 
134
                            length = 0;
 
135
                            goto end;
 
136
                        case E_GL:
 
137
                            charset = state->GL_charset;
 
138
                            goto found;
 
139
                        case E_GR:
 
140
                            charset = state->GR_charset;
 
141
                            goto found;
 
142
                        default:
 
143
                            break;
 
144
                    }
 
145
                }
 
146
            }
 
147
        }
 
148
    }
 
149
 
 
150
    if ((*src & 0x80) && state->GR_charset)
 
151
        charset = state->GR_charset;
 
152
    else
 
153
        charset = state->GL_charset;
 
154
 
 
155
found:
 
156
    if (charset == NULL ||
 
157
        (num_args == 2 && (XlcCharSet) args[1] != charset))
 
158
        return -1;
 
159
 
 
160
    length = charset->char_size;
 
161
    if (length > *from_left - encoding_len)
 
162
        return -1;
 
163
 
 
164
    if (dst) {
 
165
        if (length > *to_left)
 
166
            return -1;
 
167
        if (charset->side == XlcGL) {
 
168
            for (i = 0; i < length; i++)
 
169
                *dst++ = *src++ & 0x7f;
 
170
        } else if (charset->side == XlcGR) {
 
171
            for (i = 0; i < length; i++)
 
172
                *dst++ = *src++ | 0x80;
 
173
        } else {
 
174
            for (i = 0; i < length; i++)
 
175
                *dst++ = *src++;
 
176
        }
 
177
        *to = (XPointer) dst;
 
178
        *to_left -= length;
 
179
    }
 
180
end:
 
181
    *from = (XPointer) src;
 
182
    *from_left -= encoding_len + length;
 
183
    state->charset = charset;
 
184
    if (num_args == 1)
 
185
        *((XlcCharSet *) args[0]) = charset;
 
186
 
 
187
    return 0;
 
188
}
 
189
 
 
190
static int
 
191
mbstocs(
 
192
    XlcConv conv,
 
193
    XPointer *from,
 
194
    int *from_left,
 
195
    XPointer *to,
 
196
    int *to_left,
 
197
    XPointer *args,
 
198
    int num_args)
 
199
{
 
200
    XlcCharSet charset = NULL;
 
201
    XPointer tmp_args[2], save_from = *from;
 
202
    int ret, unconv_num = 0, tmp_num = 1;
 
203
 
 
204
    tmp_args[0] = (XPointer) &charset;
 
205
 
 
206
    while (*from_left > 0 && *to_left > 0) {
 
207
        ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, tmp_num);
 
208
        if (ret < 0)
 
209
            break;
 
210
        unconv_num += ret;
 
211
        if (tmp_num == 1 && charset) {
 
212
            tmp_args[1] = (XPointer) charset;
 
213
            tmp_num = 2;
 
214
        }
 
215
    }
 
216
 
 
217
    if (save_from == *from)
 
218
        return -1;
 
219
 
 
220
    if (num_args > 0)
 
221
        *((XlcCharSet *) args[0]) = charset;
 
222
    
 
223
    return unconv_num;
 
224
}
 
225
 
 
226
static CodeSet
 
227
wc_parse_codeset(
 
228
    XLCd lcd,
 
229
    const wchar_t *wcstr)
 
230
{
 
231
    CodeSet *codeset;
 
232
    unsigned long wc_encoding;
 
233
    int num;
 
234
 
 
235
    wc_encoding = *wcstr & XLC_GENERIC(lcd, wc_encode_mask);
 
236
    num = XLC_GENERIC(lcd, codeset_num);
 
237
    codeset = XLC_GENERIC(lcd, codeset_list);
 
238
    while (num-- > 0) {
 
239
        if (wc_encoding == (*codeset)->wc_encoding)
 
240
            return *codeset;
 
241
        codeset++;
 
242
    }
 
243
 
 
244
    return NULL;
 
245
}
 
246
 
 
247
static int
 
248
wcstocs(
 
249
    XlcConv conv,
 
250
    XPointer *from,
 
251
    int *from_left,
 
252
    XPointer *to,
 
253
    int *to_left,
 
254
    XPointer *args,
 
255
    int num_args)
 
256
{
 
257
    State state = (State) conv->state;
 
258
    XLCd lcd = state->lcd;
 
259
    const wchar_t *wcptr;
 
260
    char *bufptr;
 
261
    wchar_t wch;
 
262
    char *tmpptr;
 
263
    int length;
 
264
    CodeSet codeset;
 
265
    unsigned long wc_encoding;
 
266
    int wcstr_len, buf_len;
 
267
 
 
268
    if (from == NULL || *from == NULL)
 
269
        return 0;
 
270
 
 
271
    wcptr = *((const wchar_t **) from);
 
272
    bufptr = *((char **) to);
 
273
    wcstr_len = *from_left;
 
274
    buf_len = *to_left;
 
275
 
 
276
    codeset = wc_parse_codeset(lcd, wcptr);
 
277
    if (codeset == NULL)
 
278
        return -1;
 
279
    wc_encoding = codeset->wc_encoding;
 
280
 
 
281
    if (wcstr_len < buf_len / codeset->length)
 
282
        buf_len = wcstr_len * codeset->length;
 
283
 
 
284
    for ( ; wcstr_len > 0 && buf_len > 0; wcptr++, wcstr_len--) {
 
285
        wch = *wcptr;
 
286
        if ((wch & XLC_GENERIC(lcd, wc_encode_mask)) != wc_encoding)
 
287
            break;
 
288
        length = codeset->length;
 
289
        buf_len -= length;
 
290
        bufptr += length;
 
291
 
 
292
        tmpptr = bufptr - 1;
 
293
        if ((*codeset->charset_list)->side == XlcGL) {
 
294
            while (length--) {
 
295
                *tmpptr-- = (unsigned char) (wch & 0x7f);
 
296
                wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits);
 
297
            }
 
298
        } else if ((*codeset->charset_list)->side == XlcGR) {
 
299
            while (length--) {
 
300
                *tmpptr-- = (unsigned char) (wch | 0x80);
 
301
                wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits);
 
302
            }
 
303
        } else {
 
304
            while (length--) {
 
305
                *tmpptr-- = (unsigned char) wch;
 
306
                wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits);
 
307
            }
 
308
        }
 
309
    }
 
310
 
 
311
    if (num_args > 0)
 
312
        *((XlcCharSet *) args[0]) = *codeset->charset_list;
 
313
 
 
314
    *from_left -= wcptr - *((wchar_t **) from);
 
315
    *from = (XPointer) wcptr;
 
316
 
 
317
    *to_left -= bufptr - *((char **) to);
 
318
    *to = bufptr;
 
319
 
 
320
    return 0;
 
321
}
 
322
 
 
323
static CodeSet
 
324
GetCodeSetFromCharSet(
 
325
    XLCd lcd,
 
326
    XlcCharSet charset)
 
327
{
 
328
    CodeSet *codeset = XLC_GENERIC(lcd, codeset_list);
 
329
    XlcCharSet *charset_list;
 
330
    int codeset_num, num_charsets;
 
331
 
 
332
    codeset_num = XLC_GENERIC(lcd, codeset_num);
 
333
 
 
334
    for ( ; codeset_num-- > 0; codeset++) {
 
335
        num_charsets = (*codeset)->num_charsets;
 
336
        charset_list = (*codeset)->charset_list;
 
337
 
 
338
        for ( ; num_charsets-- > 0; charset_list++)
 
339
            if (*charset_list == charset)
 
340
                return *codeset;
 
341
    }
 
342
 
 
343
    return (CodeSet) NULL;
 
344
}
 
345
 
 
346
static int
 
347
cstombs(
 
348
    XlcConv conv,
 
349
    XPointer *from,
 
350
    int *from_left,
 
351
    XPointer *to,
 
352
    int *to_left,
 
353
    XPointer *args,
 
354
    int num_args)
 
355
{
 
356
    State state = (State) conv->state;
 
357
    const char *csptr;
 
358
    char *bufptr;
 
359
    int csstr_len;
 
360
    int buf_len;
 
361
    int num, encoding_len = 0;
 
362
    CodeSet codeset;
 
363
    XlcCharSet charset;
 
364
    EncodingType type;
 
365
    int cvt_length;
 
366
 
 
367
    csptr = *((const char **) from);
 
368
    bufptr = *((char **) to);
 
369
    csstr_len = *from_left;
 
370
    buf_len = *to_left;
 
371
 
 
372
    if (num_args < 1)
 
373
        return -1;
 
374
    
 
375
    charset = (XlcCharSet) args[0];
 
376
 
 
377
    codeset = GetCodeSetFromCharSet(state->lcd, charset);
 
378
    if (codeset == NULL)
 
379
        return -1;
 
380
 
 
381
    cvt_length = 0;
 
382
    if (codeset->parse_info) {
 
383
        switch (type = codeset->parse_info->type) {
 
384
            case E_SS:
 
385
                encoding_len = strlen(codeset->parse_info->encoding);
 
386
                break;
 
387
            case E_LSL:
 
388
            case E_LSR:
 
389
                if (type == E_LSL) {
 
390
                    if (charset == state->GL_charset)
 
391
                        break;
 
392
                } else {
 
393
                    if (charset == state->GR_charset)
 
394
                        break;
 
395
                }
 
396
                encoding_len = strlen(codeset->parse_info->encoding);
 
397
                if (encoding_len > buf_len)
 
398
                    return -1;
 
399
                cvt_length += encoding_len;
 
400
                if (bufptr) {
 
401
                    strcpy(bufptr, codeset->parse_info->encoding);
 
402
                    bufptr += encoding_len;
 
403
                }
 
404
                buf_len -= encoding_len;
 
405
                encoding_len = 0;
 
406
                if (type == E_LSL)
 
407
                    state->GL_charset = charset;
 
408
                else
 
409
                    state->GR_charset = charset;
 
410
                break;
 
411
            default:
 
412
                break;
 
413
        }
 
414
    }
 
415
 
 
416
    csstr_len /= codeset->length;
 
417
    buf_len /= codeset->length + encoding_len;
 
418
    if (csstr_len < buf_len)
 
419
        buf_len = csstr_len;
 
420
    
 
421
    cvt_length += buf_len * (encoding_len + codeset->length);
 
422
    if (bufptr) {
 
423
        while (buf_len--) {
 
424
            if (encoding_len) {
 
425
                strcpy(bufptr, codeset->parse_info->encoding);
 
426
                bufptr += encoding_len;
 
427
            }
 
428
            num = codeset->length;
 
429
            if (codeset->side == XlcGL) {
 
430
                while (num--)
 
431
                    *bufptr++ = *csptr++ & 0x7f;
 
432
            } else if (codeset->side == XlcGR) {
 
433
                while (num--)
 
434
                    *bufptr++ = *csptr++ | 0x80;
 
435
            } else {
 
436
                while (num--)
 
437
                    *bufptr++ = *csptr++;
 
438
            }
 
439
        }
 
440
    }
 
441
 
 
442
    *from_left -= csptr - *((char **) from);
 
443
    *from = (XPointer) csptr;
 
444
 
 
445
    if (bufptr)
 
446
        *to = (XPointer) bufptr;
 
447
    *to_left -= cvt_length;
 
448
 
 
449
    return 0;
 
450
}
 
451
 
 
452
static int
 
453
cstowcs(
 
454
    XlcConv conv,
 
455
    XPointer *from,
 
456
    int *from_left,
 
457
    XPointer *to,
 
458
    int *to_left,
 
459
    XPointer *args,
 
460
    int num_args)
 
461
{
 
462
    State state = (State) conv->state;
 
463
    XLCd lcd = state->lcd;
 
464
    const char *csptr;
 
465
    wchar_t *bufptr;
 
466
    int csstr_len;
 
467
    int buf_len;
 
468
    wchar_t wch;
 
469
    unsigned long code_mask, wc_encoding;
 
470
    int num, length, wc_shift_bits;
 
471
    CodeSet codeset;
 
472
 
 
473
    csptr = *((const char **) from);
 
474
    bufptr = *((wchar_t **) to);
 
475
    csstr_len = *from_left;
 
476
    buf_len = *to_left;
 
477
 
 
478
    if (num_args < 1)
 
479
        return -1;
 
480
    
 
481
    codeset = GetCodeSetFromCharSet(lcd, (XlcCharSet) args[0]);
 
482
    if (codeset == NULL)
 
483
        return -1;
 
484
 
 
485
    length = codeset->length;
 
486
    csstr_len /= length;
 
487
    if (csstr_len < buf_len)
 
488
        buf_len = csstr_len;
 
489
    
 
490
    code_mask = ~XLC_GENERIC(lcd, wc_encode_mask);
 
491
    wc_encoding = codeset->wc_encoding;
 
492
    wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits);
 
493
 
 
494
    *to_left -= buf_len;
 
495
 
 
496
    if (bufptr) {
 
497
        while (buf_len--) {
 
498
            wch = (wchar_t) (*csptr++ & 0x7f);
 
499
            num = length - 1;
 
500
            while (num--)
 
501
                wch = (wch << wc_shift_bits) | (*csptr++ & 0x7f);
 
502
 
 
503
            *bufptr++ = (wch & code_mask) | wc_encoding;
 
504
        }
 
505
    }
 
506
 
 
507
    *from_left -= csptr - *((char **) from);
 
508
    *from = (XPointer) csptr;
 
509
 
 
510
    if (bufptr)
 
511
        *to = (XPointer) bufptr;
 
512
 
 
513
    return 0;
 
514
}
 
515
 
 
516
 
 
517
static void
 
518
close_converter(
 
519
    XlcConv conv)
 
520
{
 
521
    if (conv->state) {
 
522
        Xfree((char *) conv->state);
 
523
    }
 
524
 
 
525
    Xfree((char *) conv);
 
526
}
 
527
 
 
528
static XlcConv
 
529
create_conv(
 
530
    XLCd lcd,
 
531
    XlcConvMethods methods)
 
532
{
 
533
    XlcConv conv;
 
534
    State state;
 
535
 
 
536
    conv = (XlcConv) Xmalloc(sizeof(XlcConvRec));
 
537
    if (conv == NULL)
 
538
        return (XlcConv) NULL;
 
539
    
 
540
    conv->methods = (XlcConvMethods) Xmalloc(sizeof(XlcConvMethodsRec));
 
541
    if (conv->methods == NULL)
 
542
        goto err;
 
543
    *conv->methods = *methods;
 
544
    if (XLC_PUBLIC(lcd, is_state_depend))
 
545
        conv->methods->reset = init_state;
 
546
 
 
547
    conv->state = (XPointer) Xmalloc(sizeof(StateRec));
 
548
    if (conv->state == NULL)
 
549
        goto err;
 
550
    bzero((char *) conv->state, sizeof(StateRec));
 
551
    
 
552
    state = (State) conv->state;
 
553
    state->lcd = lcd;
 
554
    init_state(conv);
 
555
    
 
556
    return conv;
 
557
 
 
558
err:
 
559
    close_converter(conv);
 
560
 
 
561
    return (XlcConv) NULL;
 
562
}
 
563
 
 
564
static XlcConvMethodsRec mbstocs_methods = {
 
565
    close_converter,
 
566
    mbstocs,
 
567
    NULL
 
568
};
 
569
 
 
570
static XlcConv
 
571
open_mbstocs(
 
572
    XLCd from_lcd,
 
573
    const char *from_type,
 
574
    XLCd to_lcd,
 
575
    const char *to_type)
 
576
{
 
577
    return create_conv(from_lcd, &mbstocs_methods);
 
578
}
 
579
 
 
580
static XlcConvMethodsRec wcstocs_methods = {
 
581
    close_converter,
 
582
    wcstocs,
 
583
    NULL
 
584
};
 
585
 
 
586
static XlcConv
 
587
open_wcstocs(
 
588
    XLCd from_lcd,
 
589
    const char *from_type,
 
590
    XLCd to_lcd,
 
591
    const char *to_type)
 
592
{
 
593
    return create_conv(from_lcd, &wcstocs_methods);
 
594
}
 
595
 
 
596
static XlcConvMethodsRec mbtocs_methods = {
 
597
    close_converter,
 
598
    mbtocs,
 
599
    NULL
 
600
};
 
601
 
 
602
static XlcConv
 
603
open_mbtocs(
 
604
    XLCd from_lcd,
 
605
    const char *from_type,
 
606
    XLCd to_lcd,
 
607
    const char *to_type)
 
608
{
 
609
    return create_conv(from_lcd, &mbtocs_methods);
 
610
}
 
611
 
 
612
static XlcConvMethodsRec cstombs_methods = {
 
613
    close_converter,
 
614
    cstombs,
 
615
    NULL
 
616
};
 
617
 
 
618
static XlcConv
 
619
open_cstombs(
 
620
    XLCd from_lcd,
 
621
    const char *from_type,
 
622
    XLCd to_lcd,
 
623
    const char *to_type)
 
624
{
 
625
    return create_conv(from_lcd, &cstombs_methods);
 
626
}
 
627
 
 
628
static XlcConvMethodsRec cstowcs_methods = {
 
629
    close_converter,
 
630
    cstowcs,
 
631
    NULL
 
632
};
 
633
 
 
634
static XlcConv
 
635
open_cstowcs(
 
636
    XLCd from_lcd,
 
637
    const char *from_type,
 
638
    XLCd to_lcd,
 
639
    const char *to_type)
 
640
{
 
641
    return create_conv(from_lcd, &cstowcs_methods);
 
642
}
 
643
 
 
644
#ifdef STDCVT
 
645
static int
 
646
stdc_mbstowcs(
 
647
    XlcConv conv,
 
648
    XPointer *from,
 
649
    int *from_left,
 
650
    XPointer *to,
 
651
    int *to_left,
 
652
    XPointer *args,
 
653
    int num_args)
 
654
{
 
655
    const char *src = *((const char **) from);
 
656
    wchar_t *dst = *((wchar_t **) to);
 
657
    int src_left = *from_left;
 
658
    int dst_left = *to_left;
 
659
    int length;
 
660
 
 
661
    while (src_left > 0 && dst_left > 0) {
 
662
        length = mbtowc(dst, src, src_left);
 
663
        if (length < 0)
 
664
            break;
 
665
 
 
666
        src += length;
 
667
        src_left -= length;
 
668
        if (dst)
 
669
            dst++;
 
670
        dst_left--;
 
671
 
 
672
        if (length == 0) {
 
673
            src++;
 
674
            src_left--;
 
675
            break;
 
676
        }
 
677
    }
 
678
 
 
679
    if (*from_left == src_left)
 
680
        return -1;
 
681
 
 
682
    *from = (XPointer) src;
 
683
    if (dst)
 
684
        *to = (XPointer) dst;
 
685
    *from_left = src_left;
 
686
    *to_left = dst_left;
 
687
 
 
688
    return 0;
 
689
}
 
690
 
 
691
static int
 
692
stdc_wcstombs(
 
693
    XlcConv conv,
 
694
    XPointer *from,
 
695
    int *from_left,
 
696
    XPointer *to,
 
697
    int *to_left,
 
698
    XPointer *args,
 
699
    int num_args)
 
700
{
 
701
    const wchar_t *src = *((const wchar_t **) from);
 
702
    char *dst = *((char **) to);
 
703
    int src_left = *from_left;
 
704
    int dst_left = *to_left;
 
705
    int length;
 
706
 
 
707
    while (src_left > 0 && dst_left > 0) {
 
708
        length = wctomb(dst, *src);             /* XXX */
 
709
        if (length < 0 || dst_left < length)
 
710
            break;
 
711
 
 
712
        src++;
 
713
        src_left--;
 
714
        dst += length;
 
715
        dst_left -= length;
 
716
 
 
717
        if (length == 0) {
 
718
            dst++;
 
719
            dst_left--;
 
720
            break;
 
721
        }
 
722
    }
 
723
 
 
724
    if (*from_left == src_left)
 
725
        return -1;
 
726
 
 
727
    *from = (XPointer) src;
 
728
    *to = (XPointer) dst;
 
729
    *from_left = src_left;
 
730
    *to_left = dst_left;
 
731
 
 
732
    return 0;
 
733
}
 
734
 
 
735
static int
 
736
stdc_wcstocs(
 
737
    XlcConv conv,
 
738
    XPointer *from,
 
739
    int *from_left,
 
740
    XPointer *to,
 
741
    int *to_left,
 
742
    XPointer *args,
 
743
    int num_args)
 
744
{
 
745
    const wchar_t *src = *((const wchar_t **) from);
 
746
    wchar_t wch;
 
747
    XlcCharSet charset = NULL;
 
748
    XPointer tmp_args[2], tmp_from, save_from = *from;
 
749
    char tmp[32];
 
750
    int length, ret, src_left = *from_left;
 
751
    int unconv_num = 0, tmp_num = 1;
 
752
 
 
753
    tmp_args[0] = (XPointer) &charset;
 
754
 
 
755
    while (src_left > 0 && *to_left > 0) {
 
756
        if (wch = *src) {
 
757
            length = wctomb(tmp, wch);
 
758
        } else {
 
759
            length = 1;
 
760
            *tmp = '\0';
 
761
        }
 
762
                
 
763
        if (length < 0)
 
764
            break;
 
765
 
 
766
        tmp_from = (XPointer) tmp;
 
767
        ret = mbtocs(conv, &tmp_from, &length, to, to_left, tmp_args, tmp_num);
 
768
        if (ret < 0)
 
769
            break;
 
770
        unconv_num += ret;
 
771
        if (tmp_num == 1 && charset) {
 
772
            tmp_args[1] = (XPointer) charset;
 
773
            tmp_num = 2;
 
774
        }
 
775
 
 
776
        src++;
 
777
        src_left--;
 
778
    }
 
779
 
 
780
    if (save_from == (XPointer) src)
 
781
        return -1;
 
782
 
 
783
    *from = (XPointer) src;
 
784
    *from_left = src_left;
 
785
 
 
786
    if (num_args > 0)
 
787
        *((XlcCharSet *) args[0]) = charset;
 
788
    
 
789
    return unconv_num;
 
790
}
 
791
 
 
792
#define DefineLocalBuf          char local_buf[BUFSIZ]
 
793
#define AllocLocalBuf(length)   (length > BUFSIZ ? (char*) Xmalloc(length) : local_buf)
 
794
#define FreeLocalBuf(ptr)       if (ptr != local_buf) Xfree(ptr)
 
795
 
 
796
static int
 
797
stdc_cstowcs(
 
798
    XlcConv conv,
 
799
    XPointer *from,
 
800
    int *from_left,
 
801
    XPointer *to,
 
802
    int *to_left,
 
803
    XPointer *args,
 
804
    int num_args)
 
805
{
 
806
    XLCd lcd = ((State) conv->state)->lcd;
 
807
    DefineLocalBuf;
 
808
    XPointer buf, save_buf;
 
809
    int length, left, ret;
 
810
    
 
811
    left = length = *to_left * XLC_PUBLIC(lcd, mb_cur_max);
 
812
    buf = save_buf = (XPointer) AllocLocalBuf(length);
 
813
    if (buf == NULL)
 
814
        return -1;
 
815
 
 
816
    ret = cstombs(conv, from, from_left, &buf, &left, args, num_args);
 
817
    if (ret < 0)
 
818
        goto err;
 
819
    
 
820
    buf = save_buf;
 
821
    length -= left;
 
822
    if (stdc_mbstowcs(conv, &buf, &length, to, to_left, args, num_args) < 0)
 
823
        ret = -1;
 
824
 
 
825
err:
 
826
    FreeLocalBuf(save_buf);
 
827
 
 
828
    return ret;
 
829
}
 
830
 
 
831
static XlcConvMethodsRec stdc_mbstowcs_methods = {
 
832
    close_converter,
 
833
    stdc_mbstowcs,
 
834
    NULL
 
835
};
 
836
 
 
837
static XlcConv
 
838
open_stdc_mbstowcs(
 
839
    XLCd from_lcd,
 
840
    const char *from_type,
 
841
    XLCd to_lcd,
 
842
    const char *to_type)
 
843
{
 
844
    return create_conv(from_lcd, &stdc_mbstowcs_methods);
 
845
}
 
846
 
 
847
static XlcConvMethodsRec stdc_wcstombs_methods = {
 
848
    close_converter,
 
849
    stdc_wcstombs,
 
850
    NULL
 
851
};
 
852
 
 
853
static XlcConv
 
854
open_stdc_wcstombs(
 
855
    XLCd from_lcd,
 
856
    const char *from_type,
 
857
    XLCd to_lcd,
 
858
    const char *to_type)
 
859
{
 
860
    return create_conv(from_lcd, &stdc_wcstombs_methods);
 
861
}
 
862
 
 
863
static XlcConvMethodsRec stdc_wcstocs_methods = {
 
864
    close_converter,
 
865
    stdc_wcstocs,
 
866
    NULL
 
867
};
 
868
 
 
869
static XlcConv
 
870
open_stdc_wcstocs(
 
871
    XLCd from_lcd,
 
872
    const char *from_type,
 
873
    XLCd to_lcd,
 
874
    const char *to_type)
 
875
{
 
876
    return create_conv(from_lcd, &stdc_wcstocs_methods);
 
877
}
 
878
 
 
879
static XlcConvMethodsRec stdc_cstowcs_methods = {
 
880
    close_converter,
 
881
    stdc_cstowcs,
 
882
    NULL
 
883
};
 
884
 
 
885
static XlcConv
 
886
open_stdc_cstowcs(
 
887
    XLCd from_lcd,
 
888
    const char *from_type,
 
889
    XLCd to_lcd,
 
890
    const char *to_type)
 
891
{
 
892
    return create_conv(from_lcd, &stdc_cstowcs_methods);
 
893
}
 
894
#endif /* STDCVT */
 
895
 
 
896
XLCd
 
897
_XlcJisLoader(
 
898
    const char *name)
 
899
{
 
900
    XLCd lcd;
 
901
#ifdef STDCVT
 
902
    XLCdGenericPart *gen;
 
903
#endif
 
904
 
 
905
    lcd = _XlcCreateLC(name, _XlcGenericMethods);
 
906
    if (lcd == NULL)
 
907
        return lcd;
 
908
 
 
909
    if (!XLC_PUBLIC_PART(lcd)->codeset ||
 
910
        (_XlcCompareISOLatin1(XLC_PUBLIC_PART(lcd)->codeset, "JIS7"))) {
 
911
        _XlcDestroyLC(lcd);
 
912
        return (XLCd) NULL;
 
913
    }
 
914
 
 
915
    _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbtocs);
 
916
    _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs);
 
917
    _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs);
 
918
 
 
919
#ifdef STDCVT
 
920
    gen = XLC_GENERIC_PART(lcd);
 
921
 
 
922
    if (gen->use_stdc_env == True) {
 
923
        _XlcSetConverter(lcd,XlcNMultiByte,lcd,XlcNWideChar,open_stdc_mbstowcs);
 
924
        _XlcSetConverter(lcd,XlcNWideChar,lcd,XlcNMultiByte,open_stdc_wcstombs);
 
925
    }
 
926
    if (gen->force_convert_to_mb == True) {
 
927
        _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet,open_stdc_wcstocs);
 
928
        _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar,open_stdc_cstowcs);
 
929
    } else {
 
930
#endif
 
931
    _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs);
 
932
    _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs);
 
933
#ifdef STDCVT
 
934
    }
 
935
#endif
 
936
 
 
937
    _XlcAddUtf8Converters(lcd);
 
938
 
 
939
    return lcd;
 
940
}
 
941
 
 
942
#else
 
943
typedef int dummy;
 
944
#endif /* X_LOCALE */