source: trunk/samba-3.0.25pre1/source/ndpsmb/iconvbug.c@ 5

Last change on this file since 5 was 5, checked in by Yuri Dario, 18 years ago

OS/2 client code, initial import.

  • Property svn:eol-style set to native
File size: 3.1 KB
Line 
1// special iconv for smbd
2
3//#include <os2emx.h>
4#include <uconv.h>
5
6typedef struct _iconv_t
7{
8 int way; // 0 - to ucs, 1 - from ucs
9 UniChar ucp[20];
10} *iconv_t;
11
12/* Tell "iconv.h" to not define iconv_t by itself. */
13#define _ICONV_T
14
15#include "includes.h"
16
17/* Convert an encoding name to te form understood by UniCreateUconvObject. */
18static void __convert_codepage (const char *cp, UniChar *ucp)
19{
20 size_t sl = 0;
21
22 if (!stricmp (cp, "SYSTEM"))
23 return;
24 else if (!stricmp (cp, "EUC-JP"))
25 memcpy (ucp, L"IBM-954", 8*2);
26 else if (!stricmp (cp, "EUC-KR"))
27 memcpy (ucp, L"IBM-970", 8*2);
28 else if (!stricmp (cp, "EUC-TW"))
29 memcpy (ucp, L"IBM-964", 8*2);
30 else if (!stricmp (cp, "EUC-CN"))
31 memcpy (ucp, L"IBM-1383", 9*2);
32 else if (!stricmp (cp, "BIG5"))
33 memcpy (ucp, L"IBM-950", 8*2);
34 else if (!stricmp (cp, "UCS-2LE"))
35 memcpy (ucp, L"IBM-1200", 9*2);
36 else
37 {
38 /* Transform CPXXX naming style to IBM-XXX style */
39 if ((cp[0] == 'C' || cp[0] == 'c') && (cp[1] == 'P' || cp[1] == 'p'))
40 {
41 ucp[sl++] = 'I';
42 ucp[sl++] = 'B';
43 ucp[sl++] = 'M';
44 ucp[sl++] = '-';
45 cp += 2;
46 }
47
48 while (*cp != '\0')
49 ucp[sl++] = *cp++;
50 ucp[sl] = 0;
51 }
52}
53
54iconv_t
55iconv_open (const char *cp_to, const char *cp_from)
56{
57 UniChar *ucp;
58 char * cp;
59 iconv_t conv;
60 uconv_attribute_t attr;
61 UconvObject uo;
62
63 if (!cp_to || !cp_from)
64 {
65 errno = EINVAL;
66 return (iconv_t)(-1);
67 }
68
69 conv = (iconv_t)calloc(sizeof (struct _iconv_t), 1);
70 if (conv == NULL)
71 {
72 errno = ENOMEM;
73 return (iconv_t)(-1);
74 }
75
76 if (!stricmp (cp_to, "UCS-2LE"))
77 {
78 cp = (char *)cp_from;
79 conv->way = 0;
80 } else
81 if (!stricmp (cp_from, "UCS-2LE"))
82 {
83 cp = (char *)cp_to;
84 conv->way = 1;
85 } else
86 {
87 // samba never calls so
88 errno = EINVAL;
89 return (iconv_t)(-1);
90 }
91 __convert_codepage(cp, conv->ucp);
92 if (UniCreateUconvObject(conv->ucp, &uo))
93 {
94 free (conv);
95 errno = EINVAL;
96 return (iconv_t)(-1);
97 }
98 UniFreeUconvObject(uo);
99
100 return conv;
101}
102
103size_t
104iconv (iconv_t conv,
105 char **in, size_t *in_left,
106 char **out, size_t *out_left)
107{
108 int rc;
109 size_t sl;
110 size_t retval = 0;
111 UconvObject uo;
112
113 /* The caller wishes to reset iconv state by calling
114 iconv(conv, NULL, NULL, NULL, NULL). We should handle it */
115 if (!in || !in_left || !out || !out_left)
116 {
117 return 0;
118 }
119 if (UniCreateUconvObject(conv->ucp, &uo))
120 {
121 errno = EINVAL;
122 return (size_t)(-1);
123 }
124
125 if (conv->way)
126 {
127 sl = (*in_left) >> 1;
128 rc = UniUconvFromUcs (uo, (UniChar **)in, &sl, (void **)out, out_left, &retval);
129 *in_left = sl << 1;
130 }
131 else
132 {
133 sl = (*out_left) >> 1;
134 rc = UniUconvToUcs (uo, (void **)in, in_left, (UniChar **)out, &sl, &retval);
135 *out_left = sl << 1;
136 }
137
138 UniFreeUconvObject(uo);
139 if (!rc)
140 {
141 return retval;
142 }
143 switch (rc)
144 {
145 case ULS_ILLEGALSEQUENCE:
146 errno = ESPIPE;
147 break;
148 case ULS_INVALID:
149 errno = EINVAL;
150 break;
151 case ULS_BUFFERFULL:
152 errno = E2BIG;
153 break;
154 default:
155 errno = EBADF;
156 break;
157 }
158 return (size_t)(-1);
159}
160
161int
162iconv_close (iconv_t conv)
163{
164 if (conv && conv != (iconv_t)(-1))
165 {
166 free (conv);
167 }
168 return 0;
169}
Note: See TracBrowser for help on using the repository browser.