Annotation of embedaddon/ntp/lib/isc/hex.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2004, 2005, 2007, 2008  Internet Systems Consortium, Inc. ("ISC")
        !             3:  * Copyright (C) 2000-2003  Internet Software Consortium.
        !             4:  *
        !             5:  * Permission to use, copy, modify, and/or distribute this software for any
        !             6:  * purpose with or without fee is hereby granted, provided that the above
        !             7:  * copyright notice and this permission notice appear in all copies.
        !             8:  *
        !             9:  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
        !            10:  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
        !            11:  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
        !            12:  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
        !            13:  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
        !            14:  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
        !            15:  * PERFORMANCE OF THIS SOFTWARE.
        !            16:  */
        !            17: 
        !            18: /* $Id: hex.c,v 1.20 2008/09/25 04:02:39 tbox Exp $ */
        !            19: 
        !            20: /*! \file */
        !            21: 
        !            22: #include <config.h>
        !            23: 
        !            24: #include <ctype.h>
        !            25: 
        !            26: #include <isc/buffer.h>
        !            27: #include <isc/hex.h>
        !            28: #include <isc/lex.h>
        !            29: #include <isc/string.h>
        !            30: #include <isc/util.h>
        !            31: 
        !            32: #define RETERR(x) do { \
        !            33:        isc_result_t _r = (x); \
        !            34:        if (_r != ISC_R_SUCCESS) \
        !            35:                return (_r); \
        !            36:        } while (0)
        !            37: 
        !            38: 
        !            39: /*
        !            40:  * BEW: These static functions are copied from lib/dns/rdata.c.
        !            41:  */
        !            42: static isc_result_t
        !            43: str_totext(const char *source, isc_buffer_t *target);
        !            44: 
        !            45: static isc_result_t
        !            46: mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length);
        !            47: 
        !            48: static const char hex[] = "0123456789ABCDEF";
        !            49: 
        !            50: isc_result_t
        !            51: isc_hex_totext(isc_region_t *source, int wordlength,
        !            52:               const char *wordbreak, isc_buffer_t *target)
        !            53: {
        !            54:        char buf[3];
        !            55:        unsigned int loops = 0;
        !            56: 
        !            57:        if (wordlength < 2)
        !            58:                wordlength = 2;
        !            59: 
        !            60:        memset(buf, 0, sizeof(buf));
        !            61:        while (source->length > 0) {
        !            62:                buf[0] = hex[(source->base[0] >> 4) & 0xf];
        !            63:                buf[1] = hex[(source->base[0]) & 0xf];
        !            64:                RETERR(str_totext(buf, target));
        !            65:                isc_region_consume(source, 1);
        !            66: 
        !            67:                loops++;
        !            68:                if (source->length != 0 &&
        !            69:                    (int)((loops + 1) * 2) >= wordlength)
        !            70:                {
        !            71:                        loops = 0;
        !            72:                        RETERR(str_totext(wordbreak, target));
        !            73:                }
        !            74:        }
        !            75:        return (ISC_R_SUCCESS);
        !            76: }
        !            77: 
        !            78: /*%
        !            79:  * State of a hex decoding process in progress.
        !            80:  */
        !            81: typedef struct {
        !            82:        int length;             /*%< Desired length of binary data or -1 */
        !            83:        isc_buffer_t *target;   /*%< Buffer for resulting binary data */
        !            84:        int digits;             /*%< Number of buffered hex digits */
        !            85:        int val[2];
        !            86: } hex_decode_ctx_t;
        !            87: 
        !            88: static inline void
        !            89: hex_decode_init(hex_decode_ctx_t *ctx, int length, isc_buffer_t *target)
        !            90: {
        !            91:        ctx->digits = 0;
        !            92:        ctx->length = length;
        !            93:        ctx->target = target;
        !            94: }
        !            95: 
        !            96: static inline isc_result_t
        !            97: hex_decode_char(hex_decode_ctx_t *ctx, int c) {
        !            98:        char *s;
        !            99: 
        !           100:        if ((s = strchr(hex, toupper(c))) == NULL)
        !           101:                return (ISC_R_BADHEX);
        !           102:        ctx->val[ctx->digits++] = s - hex;
        !           103:        if (ctx->digits == 2) {
        !           104:                unsigned char num;
        !           105: 
        !           106:                num = (ctx->val[0] << 4) + (ctx->val[1]);
        !           107:                RETERR(mem_tobuffer(ctx->target, &num, 1));
        !           108:                if (ctx->length >= 0) {
        !           109:                        if (ctx->length == 0)
        !           110:                                return (ISC_R_BADHEX);
        !           111:                        else
        !           112:                                ctx->length -= 1;
        !           113:                }
        !           114:                ctx->digits = 0;
        !           115:        }
        !           116:        return (ISC_R_SUCCESS);
        !           117: }
        !           118: 
        !           119: static inline isc_result_t
        !           120: hex_decode_finish(hex_decode_ctx_t *ctx) {
        !           121:        if (ctx->length > 0)
        !           122:                return (ISC_R_UNEXPECTEDEND);
        !           123:        if (ctx->digits != 0)
        !           124:                return (ISC_R_BADHEX);
        !           125:        return (ISC_R_SUCCESS);
        !           126: }
        !           127: 
        !           128: isc_result_t
        !           129: isc_hex_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) {
        !           130:        hex_decode_ctx_t ctx;
        !           131:        isc_textregion_t *tr;
        !           132:        isc_token_t token;
        !           133:        isc_boolean_t eol;
        !           134: 
        !           135:        hex_decode_init(&ctx, length, target);
        !           136: 
        !           137:        while (ctx.length != 0) {
        !           138:                unsigned int i;
        !           139: 
        !           140:                if (length > 0)
        !           141:                        eol = ISC_FALSE;
        !           142:                else
        !           143:                        eol = ISC_TRUE;
        !           144:                RETERR(isc_lex_getmastertoken(lexer, &token,
        !           145:                                              isc_tokentype_string, eol));
        !           146:                if (token.type != isc_tokentype_string)
        !           147:                        break;
        !           148:                tr = &token.value.as_textregion;
        !           149:                for (i = 0; i < tr->length; i++)
        !           150:                        RETERR(hex_decode_char(&ctx, tr->base[i]));
        !           151:        }
        !           152:        if (ctx.length < 0)
        !           153:                isc_lex_ungettoken(lexer, &token);
        !           154:        RETERR(hex_decode_finish(&ctx));
        !           155:        return (ISC_R_SUCCESS);
        !           156: }
        !           157: 
        !           158: isc_result_t
        !           159: isc_hex_decodestring(const char *cstr, isc_buffer_t *target) {
        !           160:        hex_decode_ctx_t ctx;
        !           161: 
        !           162:        hex_decode_init(&ctx, -1, target);
        !           163:        for (;;) {
        !           164:                int c = *cstr++;
        !           165:                if (c == '\0')
        !           166:                        break;
        !           167:                if (c == ' ' || c == '\t' || c == '\n' || c== '\r')
        !           168:                        continue;
        !           169:                RETERR(hex_decode_char(&ctx, c));
        !           170:        }
        !           171:        RETERR(hex_decode_finish(&ctx));
        !           172:        return (ISC_R_SUCCESS);
        !           173: }
        !           174: 
        !           175: static isc_result_t
        !           176: str_totext(const char *source, isc_buffer_t *target) {
        !           177:        unsigned int l;
        !           178:        isc_region_t region;
        !           179: 
        !           180:        isc_buffer_availableregion(target, &region);
        !           181:        l = strlen(source);
        !           182: 
        !           183:        if (l > region.length)
        !           184:                return (ISC_R_NOSPACE);
        !           185: 
        !           186:        memcpy(region.base, source, l);
        !           187:        isc_buffer_add(target, l);
        !           188:        return (ISC_R_SUCCESS);
        !           189: }
        !           190: 
        !           191: static isc_result_t
        !           192: mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) {
        !           193:        isc_region_t tr;
        !           194: 
        !           195:        isc_buffer_availableregion(target, &tr);
        !           196:        if (length > tr.length)
        !           197:                return (ISC_R_NOSPACE);
        !           198:        memcpy(tr.base, base, length);
        !           199:        isc_buffer_add(target, length);
        !           200:        return (ISC_R_SUCCESS);
        !           201: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>