fixing segv
[oweals/gnunet.git] / src / nat / upnp-reply-parse.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009, 2010 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /*
22  * Code in this file is originally inspired by the miniupnp library.
23  * Copyright (c) 2006, Thomas BERNARD. All rights reserved.
24  *
25  * Original licence:
26  * 
27  * Redistribution and use in source and binary forms, with or without
28  * modification, are permitted provided that the following conditions are met:
29  * 
30  *   * Redistributions of source code must retain the above copyright notice,
31  *     this list of conditions and the following disclaimer.
32  *   * Redistributions in binary form must reproduce the above copyright notice,
33  *     this list of conditions and the following disclaimer in the documentation
34  *     and/or other materials provided with the distribution.
35  *   * The name of the author may not be used to endorse or promote products
36  *         derived from this software without specific prior written permission.
37  * 
38  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
39  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
42  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
43  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
44  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
45  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
46  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
47  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
48  * POSSIBILITY OF SUCH DAMAGE.
49  */
50
51 /**
52  * @file nat/upnp-reply-parse.c
53  * @brief Parser for XML replies to UPnP commands
54  *
55  * @author Milan Bouchet-Valat
56  */
57
58 #include <stdlib.h>
59 #include <string.h>
60 #include <stdio.h>
61
62 #include "platform.h"
63 #include "gnunet_util_lib.h"
64 #include "upnp-minixml.h"
65 #include "upnp-reply-parse.h"
66
67 static void
68 start_elt (void *d, const char *name, int l)
69 {
70   struct UPNP_REPLY_NameValueList_ *data =
71     (struct UPNP_REPLY_NameValueList_ *) d;
72
73   if (l > 63)
74     l = 63;
75
76   memcpy (data->curelt, name, l);
77   data->curelt[l] = '\0';
78 }
79
80 static void
81 get_data (void *d, const char *datas, int l)
82 {
83   struct UPNP_REPLY_NameValueList_ *data =
84     (struct UPNP_REPLY_NameValueList_ *) d;
85   struct UPNP_REPLY_NameValue_ *nv;
86
87   nv = malloc (sizeof (struct UPNP_REPLY_NameValue_));
88
89   if (l > 63)
90     l = 63;
91
92   strncpy (nv->name, data->curelt, 64);
93   nv->name[63] = '\0';
94   memcpy (nv->value, datas, l);
95   nv->value[l] = '\0';
96
97   LIST_INSERT_HEAD (&(data->head), nv, entries);
98 }
99
100 void
101 UPNP_REPLY_parse_ (const char *buffer, int buf_size,
102                    struct UPNP_REPLY_NameValueList_ *data)
103 {
104   struct UPNP_xml_parser_ parser;
105
106   LIST_INIT (&(data->head));
107
108   /* Init xml_parser object */
109   parser.xml_start = buffer;
110   parser.xml_size = buf_size;
111   parser.cls = data;
112   parser.start_elt_func = start_elt;
113   parser.end_elt_func = 0;
114   parser.data_func = get_data;
115   parser.att_func = 0;
116
117   UPNP_parse_xml_ (&parser);
118 }
119
120 void
121 UPNP_REPLY_free_ (struct UPNP_REPLY_NameValueList_ *pdata)
122 {
123   struct UPNP_REPLY_NameValue_ *nv;
124
125   while ((nv = pdata->head.lh_first) != NULL)
126     {
127       LIST_REMOVE (nv, entries);
128       GNUNET_free (nv);
129     }
130 }
131
132 char *
133 UPNP_REPLY_get_value_ (struct UPNP_REPLY_NameValueList_ *pdata,
134                        const char *Name)
135 {
136   struct UPNP_REPLY_NameValue_ *nv;
137   char *p = NULL;
138
139   for (nv = pdata->head.lh_first;
140        (nv != NULL) && (p == NULL); nv = nv->entries.le_next)
141     {
142       if (strcmp (nv->name, Name) == 0)
143         p = nv->value;
144     }
145
146   return p;
147 }
148
149 #if DEBUG_UPNP
150 void
151 UPNP_REPLY_print_ (char *buffer, int buf_size)
152 {
153   struct UPNP_REPLY_NameValueList_ pdata;
154   struct UPNP_REPLY_NameValue_ *nv;
155
156   UPNP_REPLY_parse_ (buffer, buf_size, &pdata);
157
158   for (nv = pdata.head.lh_first; nv != NULL; nv = nv->entries.le_next)
159     {
160       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "UPnP",
161                        "%s = %s", nv->name, nv->value);
162     }
163
164   UPNP_REPLY_free_ (&pdata);
165 }
166 #endif