Mercurial > hg
annotate mcabber/libjabber/expat.c @ 420:04a0b450380b
Display error code/message when receiving a message packet with "error" type
author | Mikael Berthe <mikael@lilotux.net> |
---|---|
date | Fri, 02 Sep 2005 21:47:14 +0200 |
parents | c3ae9251c197 |
children |
rev | line source |
---|---|
25 | 1 /* |
2 * This program is free software; you can redistribute it and/or modify | |
3 * it under the terms of the GNU General Public License as published by | |
4 * the Free Software Foundation; either version 2 of the License, or | |
5 * (at your option) any later version. | |
6 * | |
7 * This program is distributed in the hope that it will be useful, | |
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
10 * GNU General Public License for more details. | |
11 * | |
12 * You should have received a copy of the GNU General Public License | |
13 * along with this program; if not, write to the Free Software | |
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
15 * | |
16 * Jabber | |
17 * Copyright (C) 1998-1999 The Jabber Team http://jabber.org/ | |
18 */ | |
19 | |
20 #include <libxode.h> | |
21 | |
417
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
22 /** |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
23 * callback function used for start elements |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
24 * |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
25 * This function is used internally by expat.c as a callback function |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
26 * given to expat. It will create a new xmlnode and add it to the |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
27 * already created xmlnode tree. |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
28 * |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
29 * @param userdata pointer to the parent xmlnode instance (NULL if this function is called for the root note) |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
30 * @param name name of the starting element |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
31 * @param atts attributes that are contained in the start element |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
32 */ |
25 | 33 void expat_startElement(void* userdata, const char* name, const char** atts) |
34 { | |
35 /* get the xmlnode pointed to by the userdata */ | |
36 xmlnode *x = userdata; | |
37 xmlnode current = *x; | |
38 | |
39 if (current == NULL) | |
40 { | |
41 /* allocate a base node */ | |
42 current = xmlnode_new_tag(name); | |
43 xmlnode_put_expat_attribs(current, atts); | |
44 *x = current; | |
45 } | |
46 else | |
47 { | |
48 *x = xmlnode_insert_tag(current, name); | |
49 xmlnode_put_expat_attribs(*x, atts); | |
50 } | |
51 } | |
52 | |
417
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
53 /** |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
54 * callback function used for end elements |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
55 * |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
56 * This function is used internally by expat.c as a callback function |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
57 * given to expat. It will complete an xmlnode and update the userdata pointer |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
58 * to point to the node that is parent of the next starting element. |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
59 * |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
60 * @param userdata pointer to the current xmlnode |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
61 * @param name name of the ending element (ignored by this function) |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
62 */ |
25 | 63 void expat_endElement(void* userdata, const char* name) |
64 { | |
65 xmlnode *x = userdata; | |
66 xmlnode current = *x; | |
67 | |
68 current->complete = 1; | |
69 current = xmlnode_get_parent(current); | |
70 | |
71 /* if it's NULL we've hit the top folks, otherwise back up a level */ | |
72 if(current != NULL) | |
73 *x = current; | |
74 } | |
75 | |
417
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
76 /** |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
77 * callback function for CDATA nodes |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
78 * |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
79 * This function will insert CDATA in an xmlnode |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
80 * |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
81 * @param userdata pointer to the current xmlnode |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
82 * @param s pointer to the CDATA string (not zero terminated!) |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
83 * @param len length of the CDATA string |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
84 */ |
25 | 85 void expat_charData(void* userdata, const char* s, int len) |
86 { | |
87 xmlnode *x = userdata; | |
88 xmlnode current = *x; | |
89 | |
90 xmlnode_insert_cdata(current, s, len); | |
91 } | |
92 | |
417
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
93 /** |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
94 * create an xmlnode instance (possibly including other xmlnode instances) by parsing a string |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
95 * |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
96 * This function will parse a string containing an XML document and create an xmlnode graph |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
97 * |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
98 * @param str the string containing the XML document (not necessarily zero terminated) |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
99 * @param len the length of the string (without the zero byte, if present) |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
100 * @return the graph of xmlnodes that represent the parsed document, NULL on failure |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
101 */ |
25 | 102 xmlnode xmlnode_str(char *str, int len) |
103 { | |
104 XML_Parser p; | |
105 xmlnode *x, node; /* pointer to an xmlnode */ | |
106 | |
107 if(NULL == str) | |
108 return NULL; | |
109 | |
110 x = malloc(sizeof(void *)); | |
111 | |
112 *x = NULL; /* pointer to NULL */ | |
113 p = XML_ParserCreate(NULL); | |
114 XML_SetUserData(p, x); | |
115 XML_SetElementHandler(p, expat_startElement, expat_endElement); | |
116 XML_SetCharacterDataHandler(p, expat_charData); | |
117 if(!XML_Parse(p, str, len, 1)) | |
118 { | |
119 /* jdebug(ZONE,"xmlnode_str_error: %s",(char *)XML_ErrorString(XML_GetErrorCode(p)));*/ | |
120 xmlnode_free(*x); | |
121 *x = NULL; | |
122 } | |
123 node = *x; | |
124 free(x); | |
125 XML_ParserFree(p); | |
126 return node; /* return the xmlnode x points to */ | |
127 } | |
128 | |
417
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
129 /** |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
130 * create an xmlnode instance (possibly including other xmlnode instances) by parsing a file |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
131 * |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
132 * This function will parse a file containing an XML document and create an xmlnode graph |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
133 * |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
134 * @param file the filename |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
135 * @return the graph of xmlnodes that represent the parsed document, NULL on failure |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
136 */ |
25 | 137 xmlnode xmlnode_file(char *file) |
138 { | |
139 XML_Parser p; | |
140 xmlnode *x, node; /* pointer to an xmlnode */ | |
141 char buf[BUFSIZ]; | |
142 int done, fd, len; | |
143 | |
144 if(NULL == file) | |
145 return NULL; | |
146 | |
147 fd = open(file,O_RDONLY); | |
148 if(fd < 0) | |
149 return NULL; | |
150 | |
151 x = malloc(sizeof(void *)); | |
152 | |
153 *x = NULL; /* pointer to NULL */ | |
154 p = XML_ParserCreate(NULL); | |
155 XML_SetUserData(p, x); | |
156 XML_SetElementHandler(p, expat_startElement, expat_endElement); | |
157 XML_SetCharacterDataHandler(p, expat_charData); | |
158 do{ | |
159 len = read(fd, buf, BUFSIZ); | |
160 done = len < BUFSIZ; | |
161 if(!XML_Parse(p, buf, len, done)) | |
162 { | |
163 /* jdebug(ZONE,"xmlnode_file_parseerror: %s",(char *)XML_ErrorString(XML_GetErrorCode(p)));*/ | |
164 xmlnode_free(*x); | |
165 *x = NULL; | |
166 done = 1; | |
167 } | |
168 }while(!done); | |
169 | |
170 node = *x; | |
171 XML_ParserFree(p); | |
172 free(x); | |
173 close(fd); | |
174 return node; /* return the xmlnode x points to */ | |
175 } | |
176 | |
417
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
177 /** |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
178 * write an xmlnode to a file (without a size limit) |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
179 * |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
180 * @param file the target file |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
181 * @param node the xmlnode that should be written |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
182 * @return 1 on success, -1 on failure |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
183 */ |
25 | 184 int xmlnode2file(char *file, xmlnode node) |
185 { | |
417
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
186 return xmlnode2file_limited(file, node, 0); |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
187 } |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
188 |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
189 /** |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
190 * write an xmlnode to a file, limited by size |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
191 * |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
192 * @param file the target file |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
193 * @param node the xmlnode that should be written |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
194 * @param sizelimit the maximum length of the file to be written |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
195 * @return 1 on success, 0 if failed due to size limit, -1 on failure |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
196 */ |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
197 int xmlnode2file_limited(char *file, xmlnode node, size_t sizelimit) |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
198 { |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
199 char *doc, *ftmp; |
25 | 200 int fd, i; |
417
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
201 size_t doclen; |
25 | 202 |
203 if(file == NULL || node == NULL) | |
204 return -1; | |
205 | |
417
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
206 ftmp = spools(xmlnode_pool(node),file,".t.m.p",xmlnode_pool(node)); |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
207 fd = open(ftmp, O_CREAT | O_WRONLY | O_TRUNC, 0600); |
25 | 208 if(fd < 0) |
209 return -1; | |
210 | |
211 doc = xmlnode2str(node); | |
417
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
212 doclen = strlen(doc); |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
213 |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
214 if (sizelimit > 0 && doclen > sizelimit) |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
215 { |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
216 close(fd); |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
217 return 0; |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
218 } |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
219 |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
220 i = write(fd,doc,doclen); |
25 | 221 if(i < 0) |
222 return -1; | |
223 | |
224 close(fd); | |
417
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
225 |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
226 if(rename(ftmp,file) < 0) |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
227 { |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
228 unlink(ftmp); |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
229 return -1; |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
230 } |
25 | 231 return 1; |
232 } | |
233 | |
417
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
234 /** |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
235 * append attributes in the expat format to an existing xmlnode |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
236 * |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
237 * @param owner where to add the attributes |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
238 * @param atts the attributes in expat format (even indexes are the attribute names, odd indexes the values) |
c3ae9251c197
Sync libjabber with upstream
Mikael Berthe <mikael@lilotux.net>
parents:
25
diff
changeset
|
239 */ |
25 | 240 void xmlnode_put_expat_attribs(xmlnode owner, const char** atts) |
241 { | |
242 int i = 0; | |
243 if (atts == NULL) return; | |
244 while (atts[i] != '\0') | |
245 { | |
246 xmlnode_put_attrib(owner, atts[i], atts[i+1]); | |
247 i += 2; | |
248 } | |
249 } |