Annotation of embedaddon/miniupnpc/src/portlistingparse.c, revision 1.1

1.1     ! misho       1: /* $Id: portlistingparse.c,v 1.11 2020/03/22 22:43:44 nanard Exp $ */
        !             2: /* MiniUPnP project
        !             3:  * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
        !             4:  * (c) 2011-2020 Thomas Bernard
        !             5:  * This software is subject to the conditions detailed
        !             6:  * in the LICENCE file provided within the distribution */
        !             7: #include <string.h>
        !             8: #include <stdlib.h>
        !             9: #ifdef DEBUG
        !            10: #include <stdio.h>
        !            11: #endif /* DEBUG */
        !            12: #include "portlistingparse.h"
        !            13: #include "minixml.h"
        !            14: 
        !            15: #if defined(__HAIKU__)
        !            16: /* rename our private function because Haiku already defines a atoui() function */
        !            17: #define atoui atoui2
        !            18: #endif 
        !            19: 
        !            20: /* list of the elements */
        !            21: static const struct {
        !            22:        const portMappingElt code;
        !            23:        const char * const str;
        !            24: } elements[] = {
        !            25:        { PortMappingEntry, "PortMappingEntry"},
        !            26:        { NewRemoteHost, "NewRemoteHost"},
        !            27:        { NewExternalPort, "NewExternalPort"},
        !            28:        { NewProtocol, "NewProtocol"},
        !            29:        { NewInternalPort, "NewInternalPort"},
        !            30:        { NewInternalClient, "NewInternalClient"},
        !            31:        { NewEnabled, "NewEnabled"},
        !            32:        { NewDescription, "NewDescription"},
        !            33:        { NewLeaseTime, "NewLeaseTime"},
        !            34:        { PortMappingEltNone, NULL}
        !            35: };
        !            36: 
        !            37: /* Helper function */
        !            38: static UNSIGNED_INTEGER
        !            39: atoui(const char * p, int l)
        !            40: {
        !            41:        UNSIGNED_INTEGER r = 0;
        !            42:        while(l > 0 && *p)
        !            43:        {
        !            44:                if(*p >= '0' && *p <= '9')
        !            45:                        r = r*10 + (*p - '0');
        !            46:                else
        !            47:                        break;
        !            48:                p++;
        !            49:                l--;
        !            50:        }
        !            51:        return r;
        !            52: }
        !            53: 
        !            54: /* Start element handler */
        !            55: static void
        !            56: startelt(void * d, const char * name, int l)
        !            57: {
        !            58:        int i;
        !            59:        struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
        !            60:        pdata->curelt = PortMappingEltNone;
        !            61:        for(i = 0; elements[i].str; i++)
        !            62:        {
        !            63:                if(strlen(elements[i].str) == (size_t)l && memcmp(name, elements[i].str, l) == 0)
        !            64:                {
        !            65:                        pdata->curelt = elements[i].code;
        !            66:                        break;
        !            67:                }
        !            68:        }
        !            69:        if(pdata->curelt == PortMappingEntry)
        !            70:        {
        !            71:                struct PortMapping * pm;
        !            72:                pm = calloc(1, sizeof(struct PortMapping));
        !            73:                if(pm == NULL)
        !            74:                {
        !            75:                        /* malloc error */
        !            76: #ifdef DEBUG
        !            77:                        fprintf(stderr, "%s: error allocating memory",
        !            78:                                "startelt");
        !            79: #endif /* DEBUG */
        !            80:                        return;
        !            81:                }
        !            82:                pm->l_next = pdata->l_head;     /* insert in list */
        !            83:                pdata->l_head = pm;
        !            84:        }
        !            85: }
        !            86: 
        !            87: /* End element handler */
        !            88: static void
        !            89: endelt(void * d, const char * name, int l)
        !            90: {
        !            91:        struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
        !            92:        (void)name;
        !            93:        (void)l;
        !            94:        pdata->curelt = PortMappingEltNone;
        !            95: }
        !            96: 
        !            97: /* Data handler */
        !            98: static void
        !            99: data(void * d, const char * data, int l)
        !           100: {
        !           101:        struct PortMapping * pm;
        !           102:        struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
        !           103:        pm = pdata->l_head;
        !           104:        if(!pm)
        !           105:                return;
        !           106:        if(l > 63)
        !           107:                l = 63;
        !           108:        switch(pdata->curelt)
        !           109:        {
        !           110:        case NewRemoteHost:
        !           111:                memcpy(pm->remoteHost, data, l);
        !           112:                pm->remoteHost[l] = '\0';
        !           113:                break;
        !           114:        case NewExternalPort:
        !           115:                pm->externalPort = (unsigned short)atoui(data, l);
        !           116:                break;
        !           117:        case NewProtocol:
        !           118:                if(l > 3)
        !           119:                        l = 3;
        !           120:                memcpy(pm->protocol, data, l);
        !           121:                pm->protocol[l] = '\0';
        !           122:                break;
        !           123:        case NewInternalPort:
        !           124:                pm->internalPort = (unsigned short)atoui(data, l);
        !           125:                break;
        !           126:        case NewInternalClient:
        !           127:                memcpy(pm->internalClient, data, l);
        !           128:                pm->internalClient[l] = '\0';
        !           129:                break;
        !           130:        case NewEnabled:
        !           131:                pm->enabled = (unsigned char)atoui(data, l);
        !           132:                break;
        !           133:        case NewDescription:
        !           134:                memcpy(pm->description, data, l);
        !           135:                pm->description[l] = '\0';
        !           136:                break;
        !           137:        case NewLeaseTime:
        !           138:                pm->leaseTime = atoui(data, l);
        !           139:                break;
        !           140:        default:
        !           141:                break;
        !           142:        }
        !           143: }
        !           144: 
        !           145: 
        !           146: /* Parse the PortMappingList XML document for IGD version 2
        !           147:  */
        !           148: void
        !           149: ParsePortListing(const char * buffer, int bufsize,
        !           150:                  struct PortMappingParserData * pdata)
        !           151: {
        !           152:        struct xmlparser parser;
        !           153: 
        !           154:        memset(pdata, 0, sizeof(struct PortMappingParserData));
        !           155:        /* init xmlparser */
        !           156:        parser.xmlstart = buffer;
        !           157:        parser.xmlsize = bufsize;
        !           158:        parser.data = pdata;
        !           159:        parser.starteltfunc = startelt;
        !           160:        parser.endeltfunc = endelt;
        !           161:        parser.datafunc = data;
        !           162:        parser.attfunc = 0;
        !           163:        parsexml(&parser);
        !           164: }
        !           165: 
        !           166: void
        !           167: FreePortListing(struct PortMappingParserData * pdata)
        !           168: {
        !           169:        struct PortMapping * pm;
        !           170:        while((pm = pdata->l_head) != NULL)
        !           171:        {
        !           172:                /* remove from list */
        !           173:                pdata->l_head = pm->l_next;
        !           174:                free(pm);
        !           175:        }
        !           176: }
        !           177: 

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