1 /*
2  * jabberd - Jabber Open Source Server
3  * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
4  *                    Ryan Eatmon, Robert Norris
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
19  */
20 
21 #include "sx.h"
22 
23 /** primary expat callbacks */
_sx_element_start(void * arg,const char * name,const char ** atts)24 void _sx_element_start(void *arg, const char *name, const char **atts) {
25     sx_t s = (sx_t) arg;
26     char buf[1024];
27     char *uri, *elem, *prefix;
28     const char **attr;
29     int ns;
30     int el;
31 
32     if(s->fail) return;
33 
34     /* starting a new nad */
35     if(s->nad == NULL)
36         s->nad = nad_new();
37 
38     /* make a copy */
39     strncpy(buf, name, 1024);
40     buf[1023] = '\0';
41 
42     /* expat gives us:
43          prefixed namespaced elem: uri|elem|prefix
44           default namespaced elem: uri|elem
45                un-namespaced elem: elem
46      */
47 
48     /* extract all the bits */
49     uri = buf;
50     elem = strchr(uri, '|');
51     if(elem != NULL) {
52         *elem = '\0';
53         elem++;
54         prefix = strchr(elem, '|');
55         if(prefix != NULL) {
56             *prefix = '\0';
57             prefix++;
58         }
59         ns = nad_add_namespace(s->nad, uri, prefix);
60     } else {
61         /* un-namespaced, just take it as-is */
62         uri = NULL;
63         elem = buf;
64         prefix = NULL;
65         ns = -1;
66     }
67 
68     /* add it */
69     el = nad_append_elem(s->nad, ns, elem, s->depth - 1);
70 
71     /* now the attributes, one at a time */
72     attr = atts;
73     while(attr[0] != NULL) {
74 
75         /* make a copy */
76         strncpy(buf, attr[0], 1024);
77         buf[1023] = '\0';
78 
79         /* extract all the bits */
80         uri = buf;
81         elem = strchr(uri, '|');
82         if(elem != NULL) {
83             *elem = '\0';
84             elem++;
85             prefix = strchr(elem, '|');
86             if(prefix != NULL) {
87                 *prefix = '\0';
88                 prefix++;
89             }
90             ns = nad_append_namespace(s->nad, el, uri, prefix);
91         } else {
92             /* un-namespaced, just take it as-is */
93             uri = NULL;
94             elem = buf;
95             prefix = NULL;
96             ns = -1;
97         }
98 
99         /* add it */
100         nad_append_attr(s->nad, ns, elem, (char *) attr[1]);
101 
102         attr += 2;
103     }
104 
105     s->depth++;
106 }
107 
_sx_element_end(void * arg,const char * name)108 void _sx_element_end(void *arg, const char *name) {
109     sx_t s = (sx_t) arg;
110 
111     if(s->fail) return;
112 
113     s->depth--;
114 
115     if(s->depth == 1) {
116         /* completed nad, save it for later processing */
117         jqueue_push(s->rnadq, s->nad, 0);
118         s->nad = NULL;
119 
120         /* and reset bytes counters */
121         s->rbytes = 0;
122         s->pbytes = 0;
123     }
124 
125     /* close received */
126     else if(s->depth == 0)
127         s->depth = -1;
128 }
129 
_sx_cdata(void * arg,const char * str,int len)130 void _sx_cdata(void *arg, const char *str, int len) {
131     sx_t s = (sx_t) arg;
132 
133     if(s->fail) return;
134 
135     /* no nad? no cdata */
136     if(s->nad == NULL)
137         return;
138 
139     /* go */
140     nad_append_cdata(s->nad, (char *) str, len, s->depth - 1);
141 }
142 
_sx_namespace_start(void * arg,const char * prefix,const char * uri)143 void _sx_namespace_start(void *arg, const char *prefix, const char *uri) {
144     sx_t s = (sx_t) arg;
145     int ns;
146 
147     if(s->fail) return;
148 
149     /* some versions of MSXML send xmlns='' occassionaally. it seems safe to ignore it */
150     if(uri == NULL) return;
151 
152     /* starting a new nad */
153     if(s->nad == NULL)
154         s->nad = nad_new();
155 
156     ns = nad_add_namespace(s->nad, (char *) uri, (char *) prefix);
157 
158     /* Always set the namespace (to catch cases where nad_add_namespace doesn't add it) */
159     s->nad->scope = ns;
160 }
161 
162 #ifdef HAVE_XML_STOPPARSER
163 /* Stop the parser if an entity declaration is hit. */
_sx_entity_declaration(void * arg,const char * entityName,int is_parameter_entity,const char * value,int value_length,const char * base,const char * systemId,const char * publicId,const char * notationName)164 void _sx_entity_declaration(void *arg, const char *entityName,
165                             int is_parameter_entity, const char *value,
166                             int value_length, const char *base,
167                             const char *systemId, const char *publicId,
168                             const char *notationName)
169 {
170     sx_t s = (sx_t) arg;
171 
172     XML_StopParser(s->expat, XML_FALSE);
173 }
174 #endif
175 
176