Annotation of embedaddon/miniupnpc/src/portlistingparse.c, revision 1.1.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>