2 MiddleMan filtering proxy server
3 Copyright (C) 2002 Jason McLaughlin
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 load an XML-ish file into a linked list
29 note: this is only a partial xml implementation, just enough to suit the needs of this program
31 XML_LIST *xml_load(XML_LIST * xml_list, char *filename)
33 int i, line = 0, inside = FALSE, label = FALSE;
34 char buf[8096], tag[64], value[8096] = "", *bufpos, *vpos = value;
37 XML_LIST *new_list = xml_list;
39 if ((fptr = fopen(filename, "r")) == NULL)
42 while (fgets(buf, sizeof(buf), fptr) != NULL) {
47 if (!strncmp(bufpos, "<!--", 4))
49 else if (!strncmp(bufpos, "-->", 3))
52 if (!label && *bufpos == '<') {
54 s_strncpy(tag, bufpos, sizeof(tag));
55 for (i = 0; tag[i] != '>' && tag[i]; i++);
67 if (stack == NULL || strcasecmp(&tag[2], &stack->data[1]))
70 if (!strcasecmp(stack->data, "<include>")) {
72 if (!strcasecmp(value, filename))
75 new_list = xml_load(new_list, value);
87 new_list = xml_list_add(new_list, value, XML_VALUE);
97 if (strcasecmp(tag, "<include>") && strcasecmp(tag, "</include>"))
98 new_list = xml_list_add(new_list, tag, XML_TAG);
100 if (!label && inside) {
101 if (*bufpos == '\\' && (bufpos[1] == '\\' || bufpos[1] == '<' || bufpos[1] == '>'))
104 if (vpos - value < sizeof(value))
112 if (xml_list == NULL)
127 putlog(MMLOG_ERROR, "Parse error in %s on line %d", filename, line);
129 while (stack != NULL) {
130 /* close off all open tags */
131 s_strncpy(tag, stack->data, sizeof(tag) - 1);
132 memmove(&tag[2], &tag[1], strlen(&tag[1]) + 1);
134 xml_list_add(new_list, tag, XML_TAG);
142 insert an XML tag or item at the end of a linked list
144 XML_LIST *xml_list_add(XML_LIST * list, char *item, int type)
147 list = xmalloc(sizeof(XML_LIST));
150 while (list->next != NULL)
152 list->next = xmalloc(sizeof(XML_LIST));
153 list->next->prev = list;
157 list->item = xstrdup(item);
165 free memory used by an XML linked list
167 void xml_list_free(XML_LIST * xml_list)
169 XML_LIST *xml_list_temp;
171 while (xml_list != NULL) {
172 xml_list_temp = xml_list->next;
173 xfree(xml_list->item);
175 xml_list = xml_list_temp;
180 return pointer where section begins
182 XML_LIST *xml_section(XML_LIST * xml_list, char *section)
186 while (xml_list != NULL) {
187 if (xml_list->type == XML_TAG) {
188 if (!i && !strcasecmp(xml_list->item, section))
190 if (xml_list->item[1] == '/')
196 xml_list = xml_list->next;
203 save formatted xml-ish file from XML_LIST struct
205 int xml_save(XML_LIST * xml_list, char *filename)
211 file = fopen(filename, "w");
215 for (; xml_list; xml_list = xml_list->next) {
216 for (i = 0; i < ind; i++)
220 if (ind == 0 && xml_list->prev != NULL) fprintf(file, "\n");
222 if (xml_list->next != NULL && xml_list->next->type == XML_VALUE) {
223 /* put the value on the same line as the opening and closing tags.. i.e. <foo>bar</foo> */
224 snprintf(&buf[ind], sizeof(buf) - ind, "%s%s%s", xml_list->item, xml_list->next->item, xml_list->next->next->item);
225 xml_list = xml_list->next->next;
228 if (xml_list->type == XML_TAG) {
229 if (xml_list->item[1] == '/') {
231 snprintf(&buf[ind], sizeof(buf) - ind, "%s", xml_list->item);
233 snprintf(&buf[ind], sizeof(buf) - ind, "%s", xml_list->item);
237 snprintf(&buf[ind], sizeof(buf) - ind, "%s", xml_list->item);
241 fprintf(file, "%s\n", buf);