xref: /minix3/lib/libc/net/base64.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: base64.c,v 1.16 2014/11/24 15:43:21 christos Exp $	*/
22fe8fb19SBen Gras 
32fe8fb19SBen Gras /*
42fe8fb19SBen Gras  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
52fe8fb19SBen Gras  * Copyright (c) 1996-1999 by Internet Software Consortium.
62fe8fb19SBen Gras  *
72fe8fb19SBen Gras  * Permission to use, copy, modify, and distribute this software for any
82fe8fb19SBen Gras  * purpose with or without fee is hereby granted, provided that the above
92fe8fb19SBen Gras  * copyright notice and this permission notice appear in all copies.
102fe8fb19SBen Gras  *
112fe8fb19SBen Gras  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
122fe8fb19SBen Gras  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
132fe8fb19SBen Gras  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
142fe8fb19SBen Gras  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
152fe8fb19SBen Gras  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
162fe8fb19SBen Gras  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
172fe8fb19SBen Gras  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
182fe8fb19SBen Gras  */
192fe8fb19SBen Gras 
202fe8fb19SBen Gras /*
212fe8fb19SBen Gras  * Portions Copyright (c) 1995 by International Business Machines, Inc.
222fe8fb19SBen Gras  *
232fe8fb19SBen Gras  * International Business Machines, Inc. (hereinafter called IBM) grants
242fe8fb19SBen Gras  * permission under its copyrights to use, copy, modify, and distribute this
252fe8fb19SBen Gras  * Software with or without fee, provided that the above copyright notice and
262fe8fb19SBen Gras  * all paragraphs of this notice appear in all copies, and that the name of IBM
272fe8fb19SBen Gras  * not be used in connection with the marketing of any product incorporating
282fe8fb19SBen Gras  * the Software or modifications thereof, without specific, written prior
292fe8fb19SBen Gras  * permission.
302fe8fb19SBen Gras  *
312fe8fb19SBen Gras  * To the extent it has a right to do so, IBM grants an immunity from suit
322fe8fb19SBen Gras  * under its patents, if any, for the use, sale or manufacture of products to
332fe8fb19SBen Gras  * the extent that such products are used for performing Domain Name System
342fe8fb19SBen Gras  * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
352fe8fb19SBen Gras  * granted for any product per se or for any other function of any product.
362fe8fb19SBen Gras  *
372fe8fb19SBen Gras  * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
382fe8fb19SBen Gras  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
392fe8fb19SBen Gras  * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
402fe8fb19SBen Gras  * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
412fe8fb19SBen Gras  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
422fe8fb19SBen Gras  * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
432fe8fb19SBen Gras  */
442fe8fb19SBen Gras 
452fe8fb19SBen Gras #include <sys/cdefs.h>
462fe8fb19SBen Gras #if defined(LIBC_SCCS) && !defined(lint)
472fe8fb19SBen Gras #if 0
482fe8fb19SBen Gras static const char rcsid[] = "Id: base64.c,v 1.4 2005/04/27 04:56:34 sra Exp";
492fe8fb19SBen Gras #else
50*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: base64.c,v 1.16 2014/11/24 15:43:21 christos Exp $");
512fe8fb19SBen Gras #endif
522fe8fb19SBen Gras #endif /* LIBC_SCCS and not lint */
532fe8fb19SBen Gras 
542fe8fb19SBen Gras #include "port_before.h"
552fe8fb19SBen Gras 
562fe8fb19SBen Gras #include <sys/types.h>
572fe8fb19SBen Gras #include <sys/param.h>
582fe8fb19SBen Gras #include <sys/socket.h>
592fe8fb19SBen Gras 
602fe8fb19SBen Gras #include <netinet/in.h>
612fe8fb19SBen Gras #include <arpa/inet.h>
622fe8fb19SBen Gras #include <arpa/nameser.h>
632fe8fb19SBen Gras 
642fe8fb19SBen Gras #include <assert.h>
652fe8fb19SBen Gras #include <ctype.h>
662fe8fb19SBen Gras #include <resolv.h>
672fe8fb19SBen Gras #include <stdio.h>
682fe8fb19SBen Gras #include <stdlib.h>
692fe8fb19SBen Gras #include <string.h>
702fe8fb19SBen Gras 
712fe8fb19SBen Gras #include "port_after.h"
722fe8fb19SBen Gras 
732fe8fb19SBen Gras #define Assert(Cond) if (!(Cond)) abort()
742fe8fb19SBen Gras 
752fe8fb19SBen Gras static const char Base64[] =
762fe8fb19SBen Gras 	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
772fe8fb19SBen Gras static const char Pad64 = '=';
782fe8fb19SBen Gras 
792fe8fb19SBen Gras /* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
802fe8fb19SBen Gras    The following encoding technique is taken from RFC1521 by Borenstein
812fe8fb19SBen Gras    and Freed.  It is reproduced here in a slightly edited form for
822fe8fb19SBen Gras    convenience.
832fe8fb19SBen Gras 
842fe8fb19SBen Gras    A 65-character subset of US-ASCII is used, enabling 6 bits to be
852fe8fb19SBen Gras    represented per printable character. (The extra 65th character, "=",
862fe8fb19SBen Gras    is used to signify a special processing function.)
872fe8fb19SBen Gras 
882fe8fb19SBen Gras    The encoding process represents 24-bit groups of input bits as output
892fe8fb19SBen Gras    strings of 4 encoded characters. Proceeding from left to right, a
902fe8fb19SBen Gras    24-bit input group is formed by concatenating 3 8-bit input groups.
912fe8fb19SBen Gras    These 24 bits are then treated as 4 concatenated 6-bit groups, each
922fe8fb19SBen Gras    of which is translated into a single digit in the base64 alphabet.
932fe8fb19SBen Gras 
942fe8fb19SBen Gras    Each 6-bit group is used as an index into an array of 64 printable
952fe8fb19SBen Gras    characters. The character referenced by the index is placed in the
962fe8fb19SBen Gras    output string.
972fe8fb19SBen Gras 
982fe8fb19SBen Gras                          Table 1: The Base64 Alphabet
992fe8fb19SBen Gras 
1002fe8fb19SBen Gras       Value Encoding  Value Encoding  Value Encoding  Value Encoding
1012fe8fb19SBen Gras           0 A            17 R            34 i            51 z
1022fe8fb19SBen Gras           1 B            18 S            35 j            52 0
1032fe8fb19SBen Gras           2 C            19 T            36 k            53 1
1042fe8fb19SBen Gras           3 D            20 U            37 l            54 2
1052fe8fb19SBen Gras           4 E            21 V            38 m            55 3
1062fe8fb19SBen Gras           5 F            22 W            39 n            56 4
1072fe8fb19SBen Gras           6 G            23 X            40 o            57 5
1082fe8fb19SBen Gras           7 H            24 Y            41 p            58 6
1092fe8fb19SBen Gras           8 I            25 Z            42 q            59 7
1102fe8fb19SBen Gras           9 J            26 a            43 r            60 8
1112fe8fb19SBen Gras          10 K            27 b            44 s            61 9
1122fe8fb19SBen Gras          11 L            28 c            45 t            62 +
1132fe8fb19SBen Gras          12 M            29 d            46 u            63 /
1142fe8fb19SBen Gras          13 N            30 e            47 v
1152fe8fb19SBen Gras          14 O            31 f            48 w         (pad) =
1162fe8fb19SBen Gras          15 P            32 g            49 x
1172fe8fb19SBen Gras          16 Q            33 h            50 y
1182fe8fb19SBen Gras 
1192fe8fb19SBen Gras    Special processing is performed if fewer than 24 bits are available
1202fe8fb19SBen Gras    at the end of the data being encoded.  A full encoding quantum is
1212fe8fb19SBen Gras    always completed at the end of a quantity.  When fewer than 24 input
1222fe8fb19SBen Gras    bits are available in an input group, zero bits are added (on the
1232fe8fb19SBen Gras    right) to form an integral number of 6-bit groups.  Padding at the
1242fe8fb19SBen Gras    end of the data is performed using the '=' character.
1252fe8fb19SBen Gras 
1262fe8fb19SBen Gras    Since all base64 input is an integral number of octets, only the
1272fe8fb19SBen Gras          -------------------------------------------------
1282fe8fb19SBen Gras    following cases can arise:
1292fe8fb19SBen Gras 
1302fe8fb19SBen Gras        (1) the final quantum of encoding input is an integral
1312fe8fb19SBen Gras            multiple of 24 bits; here, the final unit of encoded
1322fe8fb19SBen Gras 	   output will be an integral multiple of 4 characters
1332fe8fb19SBen Gras 	   with no "=" padding,
1342fe8fb19SBen Gras        (2) the final quantum of encoding input is exactly 8 bits;
1352fe8fb19SBen Gras            here, the final unit of encoded output will be two
1362fe8fb19SBen Gras 	   characters followed by two "=" padding characters, or
1372fe8fb19SBen Gras        (3) the final quantum of encoding input is exactly 16 bits;
1382fe8fb19SBen Gras            here, the final unit of encoded output will be three
1392fe8fb19SBen Gras 	   characters followed by one "=" padding character.
1402fe8fb19SBen Gras    */
1412fe8fb19SBen Gras 
1422fe8fb19SBen Gras int
b64_ntop(u_char const * src,size_t srclength,char * target,size_t targsize)1432fe8fb19SBen Gras b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) {
1442fe8fb19SBen Gras 	size_t datalength = 0;
1452fe8fb19SBen Gras 	u_char input[3];
1462fe8fb19SBen Gras 	u_char output[4];
1472fe8fb19SBen Gras 	size_t i;
1482fe8fb19SBen Gras 
1492fe8fb19SBen Gras 	_DIAGASSERT(src != NULL);
1502fe8fb19SBen Gras 	_DIAGASSERT(target != NULL);
1512fe8fb19SBen Gras 
1522fe8fb19SBen Gras 	while (2U < srclength) {
1532fe8fb19SBen Gras 		input[0] = *src++;
1542fe8fb19SBen Gras 		input[1] = *src++;
1552fe8fb19SBen Gras 		input[2] = *src++;
1562fe8fb19SBen Gras 		srclength -= 3;
1572fe8fb19SBen Gras 
158*0a6a1f1dSLionel Sambuc 		output[0] = (uint32_t)input[0] >> 2;
159*0a6a1f1dSLionel Sambuc 		output[1] = ((uint32_t)(input[0] & 0x03) << 4) +
160*0a6a1f1dSLionel Sambuc 		    ((uint32_t)input[1] >> 4);
161*0a6a1f1dSLionel Sambuc 		output[2] = ((uint32_t)(input[1] & 0x0f) << 2) +
162*0a6a1f1dSLionel Sambuc 		    ((uint32_t)input[2] >> 6);
1632fe8fb19SBen Gras 		output[3] = input[2] & 0x3f;
1642fe8fb19SBen Gras 		Assert(output[0] < 64);
1652fe8fb19SBen Gras 		Assert(output[1] < 64);
1662fe8fb19SBen Gras 		Assert(output[2] < 64);
1672fe8fb19SBen Gras 		Assert(output[3] < 64);
1682fe8fb19SBen Gras 
1692fe8fb19SBen Gras 		if (datalength + 4 > targsize)
170*0a6a1f1dSLionel Sambuc 			return -1;
1712fe8fb19SBen Gras 		target[datalength++] = Base64[output[0]];
1722fe8fb19SBen Gras 		target[datalength++] = Base64[output[1]];
1732fe8fb19SBen Gras 		target[datalength++] = Base64[output[2]];
1742fe8fb19SBen Gras 		target[datalength++] = Base64[output[3]];
1752fe8fb19SBen Gras 	}
1762fe8fb19SBen Gras 
1772fe8fb19SBen Gras 	/* Now we worry about padding. */
1782fe8fb19SBen Gras 	if (0U != srclength) {
1792fe8fb19SBen Gras 		/* Get what's left. */
1802fe8fb19SBen Gras 		input[0] = input[1] = input[2] = '\0';
1812fe8fb19SBen Gras 		for (i = 0; i < srclength; i++)
1822fe8fb19SBen Gras 			input[i] = *src++;
1832fe8fb19SBen Gras 
184*0a6a1f1dSLionel Sambuc 		output[0] = (uint32_t)input[0] >> 2;
185*0a6a1f1dSLionel Sambuc 		output[1] = ((uint32_t)(input[0] & 0x03) << 4) +
186*0a6a1f1dSLionel Sambuc 		    ((uint32_t)input[1] >> 4);
187*0a6a1f1dSLionel Sambuc 		output[2] = ((uint32_t)(input[1] & 0x0f) << 2) +
188*0a6a1f1dSLionel Sambuc 		    ((uint32_t)input[2] >> 6);
1892fe8fb19SBen Gras 		Assert(output[0] < 64);
1902fe8fb19SBen Gras 		Assert(output[1] < 64);
1912fe8fb19SBen Gras 		Assert(output[2] < 64);
1922fe8fb19SBen Gras 
1932fe8fb19SBen Gras 		if (datalength + 4 > targsize)
194*0a6a1f1dSLionel Sambuc 			return -1;
1952fe8fb19SBen Gras 		target[datalength++] = Base64[output[0]];
1962fe8fb19SBen Gras 		target[datalength++] = Base64[output[1]];
1972fe8fb19SBen Gras 		if (srclength == 1U)
1982fe8fb19SBen Gras 			target[datalength++] = Pad64;
1992fe8fb19SBen Gras 		else
2002fe8fb19SBen Gras 			target[datalength++] = Base64[output[2]];
2012fe8fb19SBen Gras 		target[datalength++] = Pad64;
2022fe8fb19SBen Gras 	}
2032fe8fb19SBen Gras 	if (datalength >= targsize)
204*0a6a1f1dSLionel Sambuc 		return -1;
2052fe8fb19SBen Gras 	target[datalength] = '\0';	/*%< Returned value doesn't count \\0. */
206f14fb602SLionel Sambuc 	_DIAGASSERT(__type_fit(int, datalength));
207f14fb602SLionel Sambuc 	return (int)datalength;
2082fe8fb19SBen Gras }
2092fe8fb19SBen Gras 
2102fe8fb19SBen Gras /* skips all whitespace anywhere.
2112fe8fb19SBen Gras    converts characters, four at a time, starting at (or after)
2122fe8fb19SBen Gras    src from base - 64 numbers into three 8 bit bytes in the target area.
2132fe8fb19SBen Gras    it returns the number of data bytes stored at the target, or -1 on error.
2142fe8fb19SBen Gras  */
2152fe8fb19SBen Gras 
2162fe8fb19SBen Gras int
b64_pton(char const * src,u_char * target,size_t targsize)217f14fb602SLionel Sambuc b64_pton(char const *src, u_char *target, size_t targsize)
2182fe8fb19SBen Gras {
2192fe8fb19SBen Gras 	size_t tarindex;
2202fe8fb19SBen Gras 	int state, ch;
221*0a6a1f1dSLionel Sambuc 	u_char nextbyte;
2222fe8fb19SBen Gras 	char *pos;
2232fe8fb19SBen Gras 
2242fe8fb19SBen Gras 	_DIAGASSERT(src != NULL);
2252fe8fb19SBen Gras 	_DIAGASSERT(target != NULL);
2262fe8fb19SBen Gras 
2272fe8fb19SBen Gras 	state = 0;
2282fe8fb19SBen Gras 	tarindex = 0;
2292fe8fb19SBen Gras 
2302fe8fb19SBen Gras 	while ((ch = (u_char) *src++) != '\0') {
2312fe8fb19SBen Gras 		if (isspace(ch))	/*%< Skip whitespace anywhere. */
2322fe8fb19SBen Gras 			continue;
2332fe8fb19SBen Gras 
2342fe8fb19SBen Gras 		if (ch == Pad64)
2352fe8fb19SBen Gras 			break;
2362fe8fb19SBen Gras 
2372fe8fb19SBen Gras 		pos = strchr(Base64, ch);
238*0a6a1f1dSLionel Sambuc 		if (pos == NULL) 	/*%< A non-base64 character. */
239*0a6a1f1dSLionel Sambuc 			return -1;
2402fe8fb19SBen Gras 
2412fe8fb19SBen Gras 		switch (state) {
2422fe8fb19SBen Gras 		case 0:
2432fe8fb19SBen Gras 			if (target) {
244*0a6a1f1dSLionel Sambuc 				if (tarindex >= targsize)
245*0a6a1f1dSLionel Sambuc 					return -1;
246*0a6a1f1dSLionel Sambuc 				target[tarindex] = (u_char)(pos - Base64) << 2;
2472fe8fb19SBen Gras 			}
2482fe8fb19SBen Gras 			state = 1;
2492fe8fb19SBen Gras 			break;
2502fe8fb19SBen Gras 		case 1:
2512fe8fb19SBen Gras 			if (target) {
252*0a6a1f1dSLionel Sambuc 				if (tarindex >= targsize)
253*0a6a1f1dSLionel Sambuc 					return -1;
2542fe8fb19SBen Gras 				target[tarindex] |=
255*0a6a1f1dSLionel Sambuc 				    (uint32_t)(pos - Base64) >> 4;
256*0a6a1f1dSLionel Sambuc 				nextbyte = (u_char)((pos - Base64) & 0x0f) << 4;
257*0a6a1f1dSLionel Sambuc 				if (tarindex + 1 < targsize)
258*0a6a1f1dSLionel Sambuc 					target[tarindex + 1] = nextbyte;
259*0a6a1f1dSLionel Sambuc 				else if (nextbyte)
260*0a6a1f1dSLionel Sambuc 					return -1;
2612fe8fb19SBen Gras 			}
2622fe8fb19SBen Gras 			tarindex++;
2632fe8fb19SBen Gras 			state = 2;
2642fe8fb19SBen Gras 			break;
2652fe8fb19SBen Gras 		case 2:
2662fe8fb19SBen Gras 			if (target) {
267*0a6a1f1dSLionel Sambuc 				if (tarindex >= targsize)
268*0a6a1f1dSLionel Sambuc 					return -1;
2692fe8fb19SBen Gras 				target[tarindex] |=
270*0a6a1f1dSLionel Sambuc 					(uint32_t)(pos - Base64) >> 2;
271*0a6a1f1dSLionel Sambuc 				nextbyte = (u_char)((pos - Base64) & 0x03) << 6;
272*0a6a1f1dSLionel Sambuc 				if (tarindex + 1 < targsize)
273*0a6a1f1dSLionel Sambuc 					target[tarindex + 1] = nextbyte;
274*0a6a1f1dSLionel Sambuc 				else if (nextbyte)
275*0a6a1f1dSLionel Sambuc 					return -1;
2762fe8fb19SBen Gras 			}
2772fe8fb19SBen Gras 			tarindex++;
2782fe8fb19SBen Gras 			state = 3;
2792fe8fb19SBen Gras 			break;
2802fe8fb19SBen Gras 		case 3:
2812fe8fb19SBen Gras 			if (target) {
2822fe8fb19SBen Gras 				if ((size_t)tarindex >= targsize)
283*0a6a1f1dSLionel Sambuc 					return -1;
284*0a6a1f1dSLionel Sambuc 				target[tarindex] |= (u_char)(pos - Base64);
2852fe8fb19SBen Gras 			}
2862fe8fb19SBen Gras 			tarindex++;
2872fe8fb19SBen Gras 			state = 0;
2882fe8fb19SBen Gras 			break;
2892fe8fb19SBen Gras 		default:
2902fe8fb19SBen Gras 			abort();
2912fe8fb19SBen Gras 		}
2922fe8fb19SBen Gras 	}
2932fe8fb19SBen Gras 
2942fe8fb19SBen Gras 	/*
2952fe8fb19SBen Gras 	 * We are done decoding Base-64 chars.  Let's see if we ended
2962fe8fb19SBen Gras 	 * on a byte boundary, and/or with erroneous trailing characters.
2972fe8fb19SBen Gras 	 */
2982fe8fb19SBen Gras 
2992fe8fb19SBen Gras 	if (ch == Pad64) {		/*%< We got a pad char. */
3002fe8fb19SBen Gras 		ch = *src++;		/*%< Skip it, get next. */
3012fe8fb19SBen Gras 		switch (state) {
3022fe8fb19SBen Gras 		case 0:		/*%< Invalid = in first position */
3032fe8fb19SBen Gras 		case 1:		/*%< Invalid = in second position */
304*0a6a1f1dSLionel Sambuc 			return -1;
3052fe8fb19SBen Gras 
3062fe8fb19SBen Gras 		case 2:		/*%< Valid, means one byte of info */
3072fe8fb19SBen Gras 			/* Skip any number of spaces. */
3082fe8fb19SBen Gras 			for (; ch != '\0'; ch = (u_char) *src++)
3092fe8fb19SBen Gras 				if (!isspace(ch))
3102fe8fb19SBen Gras 					break;
3112fe8fb19SBen Gras 			/* Make sure there is another trailing = sign. */
3122fe8fb19SBen Gras 			if (ch != Pad64)
313*0a6a1f1dSLionel Sambuc 				return -1;
3142fe8fb19SBen Gras 			ch = *src++;		/*%< Skip the = */
3152fe8fb19SBen Gras 			/* Fall through to "single trailing =" case. */
3162fe8fb19SBen Gras 			/* FALLTHROUGH */
3172fe8fb19SBen Gras 
3182fe8fb19SBen Gras 		case 3:		/*%< Valid, means two bytes of info */
3192fe8fb19SBen Gras 			/*
3202fe8fb19SBen Gras 			 * We know this char is an =.  Is there anything but
3212fe8fb19SBen Gras 			 * whitespace after it?
3222fe8fb19SBen Gras 			 */
3232fe8fb19SBen Gras 			for (; ch != '\0'; ch = (u_char) *src++)
3242fe8fb19SBen Gras 				if (!isspace(ch))
325*0a6a1f1dSLionel Sambuc 					return -1;
3262fe8fb19SBen Gras 
3272fe8fb19SBen Gras 			/*
3282fe8fb19SBen Gras 			 * Now make sure for cases 2 and 3 that the "extra"
3292fe8fb19SBen Gras 			 * bits that slopped past the last full byte were
3302fe8fb19SBen Gras 			 * zeros.  If we don't check them, they become a
3312fe8fb19SBen Gras 			 * subliminal channel.
3322fe8fb19SBen Gras 			 */
333*0a6a1f1dSLionel Sambuc 			if (target && tarindex < targsize &&
334*0a6a1f1dSLionel Sambuc 			    target[tarindex] != 0)
335*0a6a1f1dSLionel Sambuc 				return -1;
3362fe8fb19SBen Gras 		}
3372fe8fb19SBen Gras 	} else {
3382fe8fb19SBen Gras 		/*
3392fe8fb19SBen Gras 		 * We ended by seeing the end of the string.  Make sure we
3402fe8fb19SBen Gras 		 * have no partial bytes lying around.
3412fe8fb19SBen Gras 		 */
3422fe8fb19SBen Gras 		if (state != 0)
343*0a6a1f1dSLionel Sambuc 			return -1;
3442fe8fb19SBen Gras 	}
3452fe8fb19SBen Gras 
346f14fb602SLionel Sambuc 	_DIAGASSERT(__type_fit(int, tarindex));
347f14fb602SLionel Sambuc 	return (int)tarindex;
3482fe8fb19SBen Gras }
3492fe8fb19SBen Gras 
3502fe8fb19SBen Gras /*! \file */
351