1*16d86563SAlexander Pyhalov /*
2*16d86563SAlexander Pyhalov * CDDL HEADER START
3*16d86563SAlexander Pyhalov *
4*16d86563SAlexander Pyhalov * The contents of this file are subject to the terms of the
5*16d86563SAlexander Pyhalov * Common Development and Distribution License (the "License").
6*16d86563SAlexander Pyhalov * You may not use this file except in compliance with the License.
7*16d86563SAlexander Pyhalov *
8*16d86563SAlexander Pyhalov * You can obtain a copy of the license at src/OPENSOLARIS.LICENSE
9*16d86563SAlexander Pyhalov * or http://www.opensolaris.org/os/licensing.
10*16d86563SAlexander Pyhalov * See the License for the specific language governing permissions
11*16d86563SAlexander Pyhalov * and limitations under the License.
12*16d86563SAlexander Pyhalov *
13*16d86563SAlexander Pyhalov * When distributing Covered Code, include this CDDL HEADER in each
14*16d86563SAlexander Pyhalov * file and include the License file at src/OPENSOLARIS.LICENSE.
15*16d86563SAlexander Pyhalov * If applicable, add the following below this CDDL HEADER, with the
16*16d86563SAlexander Pyhalov * fields enclosed by brackets "[]" replaced with your own identifying
17*16d86563SAlexander Pyhalov * information: Portions Copyright [yyyy] [name of copyright owner]
18*16d86563SAlexander Pyhalov *
19*16d86563SAlexander Pyhalov * CDDL HEADER END
20*16d86563SAlexander Pyhalov */
21*16d86563SAlexander Pyhalov /*
22*16d86563SAlexander Pyhalov * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
23*16d86563SAlexander Pyhalov * Use is subject to license terms.
24*16d86563SAlexander Pyhalov */
25*16d86563SAlexander Pyhalov
26*16d86563SAlexander Pyhalov #include <stdlib.h>
27*16d86563SAlexander Pyhalov #include <errno.h>
28*16d86563SAlexander Pyhalov #include <sys/types.h>
29*16d86563SAlexander Pyhalov #include <dlfcn.h>
30*16d86563SAlexander Pyhalov #include <link.h>
31*16d86563SAlexander Pyhalov #include <sys/utsname.h>
32*16d86563SAlexander Pyhalov #include <ctype.h>
33*16d86563SAlexander Pyhalov #include <strings.h>
34*16d86563SAlexander Pyhalov #include <string.h>
35*16d86563SAlexander Pyhalov #include <idn/api.h>
36*16d86563SAlexander Pyhalov #include <idn/version.h>
37*16d86563SAlexander Pyhalov #include "ace.h"
38*16d86563SAlexander Pyhalov
39*16d86563SAlexander Pyhalov
40*16d86563SAlexander Pyhalov void *
_icv_open()41*16d86563SAlexander Pyhalov _icv_open()
42*16d86563SAlexander Pyhalov {
43*16d86563SAlexander Pyhalov ace_state_t *cd;
44*16d86563SAlexander Pyhalov
45*16d86563SAlexander Pyhalov cd = (ace_state_t *)calloc(1, sizeof(ace_state_t));
46*16d86563SAlexander Pyhalov if (cd == (ace_state_t *)NULL) {
47*16d86563SAlexander Pyhalov errno = ENOMEM;
48*16d86563SAlexander Pyhalov return ((void *)-1);
49*16d86563SAlexander Pyhalov }
50*16d86563SAlexander Pyhalov
51*16d86563SAlexander Pyhalov cd->libidnkit = dlopen(ICV_LIBIDNKITPATH, RTLD_LAZY);
52*16d86563SAlexander Pyhalov if (cd->libidnkit == (void *)NULL) {
53*16d86563SAlexander Pyhalov free((void *)cd);
54*16d86563SAlexander Pyhalov errno = EINVAL;
55*16d86563SAlexander Pyhalov return ((void *)-1);
56*16d86563SAlexander Pyhalov }
57*16d86563SAlexander Pyhalov
58*16d86563SAlexander Pyhalov cd->idn_function = (idn_result_t(*)(int, const char *, char *,
59*16d86563SAlexander Pyhalov #if defined(ICV_ACE_TO_UTF8)
60*16d86563SAlexander Pyhalov size_t))dlsym(cd->libidnkit, "idn_decodename");
61*16d86563SAlexander Pyhalov #else
62*16d86563SAlexander Pyhalov size_t))dlsym(cd->libidnkit, "idn_encodename");
63*16d86563SAlexander Pyhalov #endif /* defined(ICV_ACE_TO_UTF8) */
64*16d86563SAlexander Pyhalov if (cd->idn_function ==
65*16d86563SAlexander Pyhalov (idn_result_t(*)(int, const char *, char *, size_t))NULL) {
66*16d86563SAlexander Pyhalov (void) dlclose(cd->libidnkit);
67*16d86563SAlexander Pyhalov free((void *)cd);
68*16d86563SAlexander Pyhalov errno = EINVAL;
69*16d86563SAlexander Pyhalov return ((void *)-1);
70*16d86563SAlexander Pyhalov }
71*16d86563SAlexander Pyhalov
72*16d86563SAlexander Pyhalov cd->ib = (uchar_t *)malloc(_SYS_NMLN);
73*16d86563SAlexander Pyhalov if (cd->ib == (uchar_t *)NULL) {
74*16d86563SAlexander Pyhalov (void) dlclose(cd->libidnkit);
75*16d86563SAlexander Pyhalov free((void *)cd);
76*16d86563SAlexander Pyhalov errno = ENOMEM;
77*16d86563SAlexander Pyhalov return ((void *)-1);
78*16d86563SAlexander Pyhalov }
79*16d86563SAlexander Pyhalov
80*16d86563SAlexander Pyhalov cd->ob = (uchar_t *)malloc(_SYS_NMLN);
81*16d86563SAlexander Pyhalov if (cd->ob == (uchar_t *)NULL) {
82*16d86563SAlexander Pyhalov (void) dlclose(cd->libidnkit);
83*16d86563SAlexander Pyhalov free((void *)cd->ib);
84*16d86563SAlexander Pyhalov free((void *)cd);
85*16d86563SAlexander Pyhalov errno = ENOMEM;
86*16d86563SAlexander Pyhalov return ((void *)-1);
87*16d86563SAlexander Pyhalov }
88*16d86563SAlexander Pyhalov
89*16d86563SAlexander Pyhalov cd->ibl = cd->obl = _SYS_NMLN;
90*16d86563SAlexander Pyhalov cd->iblconsumed = cd->oblremaining = 0;
91*16d86563SAlexander Pyhalov
92*16d86563SAlexander Pyhalov return ((void *)cd);
93*16d86563SAlexander Pyhalov }
94*16d86563SAlexander Pyhalov
95*16d86563SAlexander Pyhalov
96*16d86563SAlexander Pyhalov void
_icv_close(ace_state_t * cd)97*16d86563SAlexander Pyhalov _icv_close(ace_state_t *cd)
98*16d86563SAlexander Pyhalov {
99*16d86563SAlexander Pyhalov if (! cd)
100*16d86563SAlexander Pyhalov errno = EBADF;
101*16d86563SAlexander Pyhalov else {
102*16d86563SAlexander Pyhalov (void) dlclose(cd->libidnkit);
103*16d86563SAlexander Pyhalov free((void *)cd->ib);
104*16d86563SAlexander Pyhalov free((void *)cd->ob);
105*16d86563SAlexander Pyhalov free((void *)cd);
106*16d86563SAlexander Pyhalov }
107*16d86563SAlexander Pyhalov }
108*16d86563SAlexander Pyhalov
109*16d86563SAlexander Pyhalov
110*16d86563SAlexander Pyhalov size_t
_icv_iconv(ace_state_t * cd,char ** inbuf,size_t * inbufleft,char ** outbuf,size_t * outbufleft)111*16d86563SAlexander Pyhalov _icv_iconv(ace_state_t *cd, char **inbuf, size_t *inbufleft, char **outbuf,
112*16d86563SAlexander Pyhalov size_t *outbufleft)
113*16d86563SAlexander Pyhalov {
114*16d86563SAlexander Pyhalov size_t ret_val = 0;
115*16d86563SAlexander Pyhalov uchar_t *ib;
116*16d86563SAlexander Pyhalov uchar_t *ob;
117*16d86563SAlexander Pyhalov uchar_t *ibtail;
118*16d86563SAlexander Pyhalov uchar_t *obtail;
119*16d86563SAlexander Pyhalov uchar_t *tmps;
120*16d86563SAlexander Pyhalov idn_result_t idnres;
121*16d86563SAlexander Pyhalov idn_action_t actions;
122*16d86563SAlexander Pyhalov int i;
123*16d86563SAlexander Pyhalov
124*16d86563SAlexander Pyhalov
125*16d86563SAlexander Pyhalov if (! cd) {
126*16d86563SAlexander Pyhalov errno = EBADF;
127*16d86563SAlexander Pyhalov return((size_t)-1);
128*16d86563SAlexander Pyhalov }
129*16d86563SAlexander Pyhalov
130*16d86563SAlexander Pyhalov /*
131*16d86563SAlexander Pyhalov * We need an output buffer in pretty much anycase and so we check it
132*16d86563SAlexander Pyhalov * here and issue E2BIG if there the output buffer isn't supplied
133*16d86563SAlexander Pyhalov * properly.
134*16d86563SAlexander Pyhalov */
135*16d86563SAlexander Pyhalov if (!outbuf || !(*outbuf)) {
136*16d86563SAlexander Pyhalov errno = E2BIG;
137*16d86563SAlexander Pyhalov return ((size_t)-1);
138*16d86563SAlexander Pyhalov }
139*16d86563SAlexander Pyhalov
140*16d86563SAlexander Pyhalov ob = (uchar_t *)*outbuf;
141*16d86563SAlexander Pyhalov obtail = ob + *outbufleft;
142*16d86563SAlexander Pyhalov
143*16d86563SAlexander Pyhalov /*
144*16d86563SAlexander Pyhalov * Always flush first any previously remaining output buffer at
145*16d86563SAlexander Pyhalov * the conversion descriptor.
146*16d86563SAlexander Pyhalov */
147*16d86563SAlexander Pyhalov for (i = 0; i < cd->oblremaining; i++) {
148*16d86563SAlexander Pyhalov if (ob >= obtail) {
149*16d86563SAlexander Pyhalov errno = E2BIG;
150*16d86563SAlexander Pyhalov cd->oblremaining -= i;
151*16d86563SAlexander Pyhalov (void) memmove((void *)cd->ob,
152*16d86563SAlexander Pyhalov (const void *)(cd->ob + i), cd->oblremaining);
153*16d86563SAlexander Pyhalov ret_val = (size_t)-1;
154*16d86563SAlexander Pyhalov goto ICV_ICONV_RETURN_TWO;
155*16d86563SAlexander Pyhalov }
156*16d86563SAlexander Pyhalov *ob++ = cd->ob[i];
157*16d86563SAlexander Pyhalov }
158*16d86563SAlexander Pyhalov cd->oblremaining = 0;
159*16d86563SAlexander Pyhalov
160*16d86563SAlexander Pyhalov #ifdef IDNKIT_VERSION_LIBIDN
161*16d86563SAlexander Pyhalov
162*16d86563SAlexander Pyhalov /* IDNkit v2 */
163*16d86563SAlexander Pyhalov
164*16d86563SAlexander Pyhalov actions =
165*16d86563SAlexander Pyhalov IDN_RTCONV
166*16d86563SAlexander Pyhalov |IDN_PROHCHECK
167*16d86563SAlexander Pyhalov |IDN_NFCCHECK
168*16d86563SAlexander Pyhalov |IDN_PREFCHECK
169*16d86563SAlexander Pyhalov |IDN_COMBCHECK
170*16d86563SAlexander Pyhalov |IDN_CTXOLITECHECK
171*16d86563SAlexander Pyhalov |IDN_BIDICHECK
172*16d86563SAlexander Pyhalov |IDN_LOCALCHECK
173*16d86563SAlexander Pyhalov |IDN_IDNCONV
174*16d86563SAlexander Pyhalov |IDN_LENCHECK;
175*16d86563SAlexander Pyhalov
176*16d86563SAlexander Pyhalov # if defined(ICV_ACE_TO_UTF8)
177*16d86563SAlexander Pyhalov actions |= IDN_RTCHECK;
178*16d86563SAlexander Pyhalov # else
179*16d86563SAlexander Pyhalov actions |= IDN_MAP;
180*16d86563SAlexander Pyhalov # endif
181*16d86563SAlexander Pyhalov
182*16d86563SAlexander Pyhalov #else
183*16d86563SAlexander Pyhalov
184*16d86563SAlexander Pyhalov /* IDNkit v1 */
185*16d86563SAlexander Pyhalov actions =
186*16d86563SAlexander Pyhalov IDN_DELIMMAP
187*16d86563SAlexander Pyhalov |IDN_NAMEPREP
188*16d86563SAlexander Pyhalov |IDN_IDNCONV
189*16d86563SAlexander Pyhalov |IDN_ASCCHECK;
190*16d86563SAlexander Pyhalov
191*16d86563SAlexander Pyhalov # if defined(ICV_ACE_TO_UTF8)
192*16d86563SAlexander Pyhalov actions |= IDN_RTCHECK;
193*16d86563SAlexander Pyhalov # else
194*16d86563SAlexander Pyhalov actions |= IDN_LOCALMAP;
195*16d86563SAlexander Pyhalov # endif
196*16d86563SAlexander Pyhalov
197*16d86563SAlexander Pyhalov #endif
198*16d86563SAlexander Pyhalov
199*16d86563SAlexander Pyhalov #if !defined(ICV_IDN_ALLOW_UNASSIGNED)
200*16d86563SAlexander Pyhalov actions |= IDN_UNASCHECK;
201*16d86563SAlexander Pyhalov #endif
202*16d86563SAlexander Pyhalov
203*16d86563SAlexander Pyhalov /* Process reset request. */
204*16d86563SAlexander Pyhalov if (!inbuf || !(*inbuf)) {
205*16d86563SAlexander Pyhalov if (cd->iblconsumed > 0) {
206*16d86563SAlexander Pyhalov if (cd->iblconsumed >= cd->ibl) {
207*16d86563SAlexander Pyhalov cd->ibl += _SYS_NMLN;
208*16d86563SAlexander Pyhalov tmps = (uchar_t *)realloc((void *)cd->ib,
209*16d86563SAlexander Pyhalov cd->ibl);
210*16d86563SAlexander Pyhalov if (tmps == (uchar_t *)NULL) {
211*16d86563SAlexander Pyhalov /*
212*16d86563SAlexander Pyhalov * We couldn't allocate any more;
213*16d86563SAlexander Pyhalov * return with realloc()'s errno.
214*16d86563SAlexander Pyhalov */
215*16d86563SAlexander Pyhalov cd->ibl -= _SYS_NMLN;
216*16d86563SAlexander Pyhalov ret_val = (size_t)-1;
217*16d86563SAlexander Pyhalov goto ICV_ICONV_RETURN_TWO;
218*16d86563SAlexander Pyhalov }
219*16d86563SAlexander Pyhalov cd->ib = tmps;
220*16d86563SAlexander Pyhalov }
221*16d86563SAlexander Pyhalov
222*16d86563SAlexander Pyhalov *(cd->ib + cd->iblconsumed++) = '\0';
223*16d86563SAlexander Pyhalov
224*16d86563SAlexander Pyhalov i = 0;
225*16d86563SAlexander Pyhalov ICV_ICONV_LOOP_ONE:
226*16d86563SAlexander Pyhalov idnres = (*(cd->idn_function))(actions,
227*16d86563SAlexander Pyhalov (const char *)cd->ib, (char *)cd->ob,
228*16d86563SAlexander Pyhalov cd->obl);
229*16d86563SAlexander Pyhalov switch (idnres) {
230*16d86563SAlexander Pyhalov case idn_success:
231*16d86563SAlexander Pyhalov break;
232*16d86563SAlexander Pyhalov case idn_buffer_overflow:
233*16d86563SAlexander Pyhalov if (++i >= 2) {
234*16d86563SAlexander Pyhalov errno = EILSEQ;
235*16d86563SAlexander Pyhalov ret_val = (size_t)-1;
236*16d86563SAlexander Pyhalov goto ICV_ICONV_RETURN_TWO;
237*16d86563SAlexander Pyhalov }
238*16d86563SAlexander Pyhalov cd->obl += _SYS_NMLN;
239*16d86563SAlexander Pyhalov tmps = (uchar_t *)realloc((void *)cd->ob,
240*16d86563SAlexander Pyhalov cd->obl);
241*16d86563SAlexander Pyhalov if (tmps == (uchar_t *)NULL) {
242*16d86563SAlexander Pyhalov /*
243*16d86563SAlexander Pyhalov * We couldn't allocate any more;
244*16d86563SAlexander Pyhalov * return with realloc()'s errno.
245*16d86563SAlexander Pyhalov */
246*16d86563SAlexander Pyhalov cd->obl -= _SYS_NMLN;
247*16d86563SAlexander Pyhalov ret_val = (size_t)-1;
248*16d86563SAlexander Pyhalov goto ICV_ICONV_RETURN_TWO;
249*16d86563SAlexander Pyhalov }
250*16d86563SAlexander Pyhalov cd->ob = tmps;
251*16d86563SAlexander Pyhalov goto ICV_ICONV_LOOP_ONE;
252*16d86563SAlexander Pyhalov default:
253*16d86563SAlexander Pyhalov /*
254*16d86563SAlexander Pyhalov * Anything else we just treat
255*16d86563SAlexander Pyhalov * as illegal sequence error.
256*16d86563SAlexander Pyhalov */
257*16d86563SAlexander Pyhalov errno = EILSEQ;
258*16d86563SAlexander Pyhalov ret_val = (size_t)-1;
259*16d86563SAlexander Pyhalov goto ICV_ICONV_RETURN_TWO;
260*16d86563SAlexander Pyhalov }
261*16d86563SAlexander Pyhalov
262*16d86563SAlexander Pyhalov cd->iblconsumed = 0;
263*16d86563SAlexander Pyhalov
264*16d86563SAlexander Pyhalov cd->oblremaining = strlen((const char *)cd->ob);
265*16d86563SAlexander Pyhalov for (i = 0; i < cd->oblremaining; i++) {
266*16d86563SAlexander Pyhalov if (ob >= obtail) {
267*16d86563SAlexander Pyhalov errno = E2BIG;
268*16d86563SAlexander Pyhalov cd->oblremaining -= i;
269*16d86563SAlexander Pyhalov (void) memmove((void *)cd->ob,
270*16d86563SAlexander Pyhalov (const void *)(cd->ob + i),
271*16d86563SAlexander Pyhalov cd->oblremaining);
272*16d86563SAlexander Pyhalov ret_val = (size_t)-1;
273*16d86563SAlexander Pyhalov goto ICV_ICONV_RETURN_TWO;
274*16d86563SAlexander Pyhalov }
275*16d86563SAlexander Pyhalov *ob++ = cd->ob[i];
276*16d86563SAlexander Pyhalov }
277*16d86563SAlexander Pyhalov cd->oblremaining = 0;
278*16d86563SAlexander Pyhalov }
279*16d86563SAlexander Pyhalov
280*16d86563SAlexander Pyhalov ret_val = (size_t)0;
281*16d86563SAlexander Pyhalov goto ICV_ICONV_RETURN_TWO;
282*16d86563SAlexander Pyhalov }
283*16d86563SAlexander Pyhalov
284*16d86563SAlexander Pyhalov ib = (uchar_t *)*inbuf;
285*16d86563SAlexander Pyhalov ibtail = ib + *inbufleft;
286*16d86563SAlexander Pyhalov
287*16d86563SAlexander Pyhalov while (ib < ibtail) {
288*16d86563SAlexander Pyhalov /*
289*16d86563SAlexander Pyhalov * We only use bare minimum single byte space class characters
290*16d86563SAlexander Pyhalov * as delimiters between names.
291*16d86563SAlexander Pyhalov */
292*16d86563SAlexander Pyhalov if (isspace(*ib)) {
293*16d86563SAlexander Pyhalov if (cd->iblconsumed > 0) {
294*16d86563SAlexander Pyhalov if (cd->iblconsumed >= cd->ibl) {
295*16d86563SAlexander Pyhalov cd->ibl += _SYS_NMLN;
296*16d86563SAlexander Pyhalov tmps = (uchar_t *)realloc(
297*16d86563SAlexander Pyhalov (void *)cd->ib, cd->ibl);
298*16d86563SAlexander Pyhalov if (tmps == (uchar_t *)NULL) {
299*16d86563SAlexander Pyhalov /*
300*16d86563SAlexander Pyhalov * We couldn't allocate any
301*16d86563SAlexander Pyhalov * more; return with
302*16d86563SAlexander Pyhalov * realloc()'s errno.
303*16d86563SAlexander Pyhalov */
304*16d86563SAlexander Pyhalov cd->ibl -= _SYS_NMLN;
305*16d86563SAlexander Pyhalov ret_val = (size_t)-1;
306*16d86563SAlexander Pyhalov break;
307*16d86563SAlexander Pyhalov }
308*16d86563SAlexander Pyhalov cd->ib = tmps;
309*16d86563SAlexander Pyhalov }
310*16d86563SAlexander Pyhalov *(cd->ib + cd->iblconsumed) = '\0';
311*16d86563SAlexander Pyhalov i = 0;
312*16d86563SAlexander Pyhalov ICV_ICONV_LOOP:
313*16d86563SAlexander Pyhalov idnres = (*(cd->idn_function))(actions,
314*16d86563SAlexander Pyhalov (const char *)cd->ib, (char *)cd->ob,
315*16d86563SAlexander Pyhalov cd->obl);
316*16d86563SAlexander Pyhalov switch (idnres) {
317*16d86563SAlexander Pyhalov case idn_success:
318*16d86563SAlexander Pyhalov break;
319*16d86563SAlexander Pyhalov case idn_buffer_overflow:
320*16d86563SAlexander Pyhalov if (++i >= 2) {
321*16d86563SAlexander Pyhalov errno = EILSEQ;
322*16d86563SAlexander Pyhalov ret_val = (size_t)-1;
323*16d86563SAlexander Pyhalov goto ICV_ICONV_RETURN;
324*16d86563SAlexander Pyhalov }
325*16d86563SAlexander Pyhalov cd->obl += _SYS_NMLN;
326*16d86563SAlexander Pyhalov tmps = (uchar_t *)realloc(
327*16d86563SAlexander Pyhalov (void *)cd->ob, cd->obl);
328*16d86563SAlexander Pyhalov if (tmps == (uchar_t *)NULL) {
329*16d86563SAlexander Pyhalov /*
330*16d86563SAlexander Pyhalov * We couldn't allocate any
331*16d86563SAlexander Pyhalov * more; return with
332*16d86563SAlexander Pyhalov * realloc()'s errno.
333*16d86563SAlexander Pyhalov */
334*16d86563SAlexander Pyhalov cd->obl -= _SYS_NMLN;
335*16d86563SAlexander Pyhalov ret_val = (size_t)-1;
336*16d86563SAlexander Pyhalov goto ICV_ICONV_RETURN;
337*16d86563SAlexander Pyhalov }
338*16d86563SAlexander Pyhalov cd->ob = tmps;
339*16d86563SAlexander Pyhalov goto ICV_ICONV_LOOP;
340*16d86563SAlexander Pyhalov default:
341*16d86563SAlexander Pyhalov /*
342*16d86563SAlexander Pyhalov * Anything else we just treat
343*16d86563SAlexander Pyhalov * as illegal sequence error.
344*16d86563SAlexander Pyhalov */
345*16d86563SAlexander Pyhalov errno = EILSEQ;
346*16d86563SAlexander Pyhalov ret_val = (size_t)-1;
347*16d86563SAlexander Pyhalov goto ICV_ICONV_RETURN;
348*16d86563SAlexander Pyhalov }
349*16d86563SAlexander Pyhalov
350*16d86563SAlexander Pyhalov cd->iblconsumed = 0;
351*16d86563SAlexander Pyhalov
352*16d86563SAlexander Pyhalov cd->oblremaining = strlen((const char *)cd->ob);
353*16d86563SAlexander Pyhalov for (i = 0; i < cd->oblremaining; i++) {
354*16d86563SAlexander Pyhalov if (ob >= obtail) {
355*16d86563SAlexander Pyhalov errno = E2BIG;
356*16d86563SAlexander Pyhalov ret_val = (size_t)-1;
357*16d86563SAlexander Pyhalov cd->oblremaining -= i;
358*16d86563SAlexander Pyhalov (void) memmove((void *)cd->ob,
359*16d86563SAlexander Pyhalov (const void *)(cd->ob + i),
360*16d86563SAlexander Pyhalov cd->oblremaining);
361*16d86563SAlexander Pyhalov goto ICV_ICONV_RETURN;
362*16d86563SAlexander Pyhalov }
363*16d86563SAlexander Pyhalov *ob++ = cd->ob[i];
364*16d86563SAlexander Pyhalov }
365*16d86563SAlexander Pyhalov cd->oblremaining = 0;
366*16d86563SAlexander Pyhalov }
367*16d86563SAlexander Pyhalov if (ob >= obtail) {
368*16d86563SAlexander Pyhalov errno = E2BIG;
369*16d86563SAlexander Pyhalov ret_val = (size_t)-1;
370*16d86563SAlexander Pyhalov break;
371*16d86563SAlexander Pyhalov }
372*16d86563SAlexander Pyhalov *ob++ = *ib++;
373*16d86563SAlexander Pyhalov } else {
374*16d86563SAlexander Pyhalov if (cd->iblconsumed >= cd->ibl) {
375*16d86563SAlexander Pyhalov cd->ibl += _SYS_NMLN;
376*16d86563SAlexander Pyhalov tmps = (uchar_t *)realloc((void *)cd->ib,
377*16d86563SAlexander Pyhalov cd->ibl);
378*16d86563SAlexander Pyhalov if (tmps == (uchar_t *)NULL) {
379*16d86563SAlexander Pyhalov /*
380*16d86563SAlexander Pyhalov * We couldn't allocate any more;
381*16d86563SAlexander Pyhalov * return with realloc()'s errno.
382*16d86563SAlexander Pyhalov */
383*16d86563SAlexander Pyhalov cd->ibl -= _SYS_NMLN;
384*16d86563SAlexander Pyhalov ret_val = (size_t)-1;
385*16d86563SAlexander Pyhalov break;
386*16d86563SAlexander Pyhalov }
387*16d86563SAlexander Pyhalov cd->ib = tmps;
388*16d86563SAlexander Pyhalov }
389*16d86563SAlexander Pyhalov *(cd->ib + cd->iblconsumed++) = *ib++;
390*16d86563SAlexander Pyhalov }
391*16d86563SAlexander Pyhalov } /* while (ib < ibtail) */
392*16d86563SAlexander Pyhalov
393*16d86563SAlexander Pyhalov ICV_ICONV_RETURN:
394*16d86563SAlexander Pyhalov *inbuf = (char *)ib;
395*16d86563SAlexander Pyhalov *inbufleft = ibtail - ib;
396*16d86563SAlexander Pyhalov ICV_ICONV_RETURN_TWO:
397*16d86563SAlexander Pyhalov *outbuf = (char *)ob;
398*16d86563SAlexander Pyhalov *outbufleft = obtail - ob;
399*16d86563SAlexander Pyhalov
400*16d86563SAlexander Pyhalov return(ret_val);
401*16d86563SAlexander Pyhalov }
402