stropheruby 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/ext/md5.c ADDED
@@ -0,0 +1,289 @@
1
+ /* md5.c
2
+ ** MD5 hash function implemention, adapted for local use
3
+ **
4
+ ** This code is in the Public Domain
5
+ */
6
+
7
+ /*
8
+ * This code implements the MD5 message-digest algorithm.
9
+ * The algorithm is due to Ron Rivest. This code was
10
+ * written by Colin Plumb in 1993, no copyright is claimed.
11
+ * This code is in the public domain; do with it what you wish.
12
+ *
13
+ * Equivalent code is available from RSA Data Security, Inc.
14
+ * This code has been tested against that, and is equivalent,
15
+ * except that you don't need to include two pages of legalese
16
+ * with every copy.
17
+ *
18
+ * To compute the message digest of a chunk of bytes, declare an
19
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
20
+ * needed on buffers full of bytes, and then call MD5Final, which
21
+ * will fill a supplied 16-byte array with the digest.
22
+ */
23
+
24
+ /** @file
25
+ * MD5 hash.
26
+ */
27
+
28
+ #include <string.h> /* memcpy(), memset() */
29
+ #include "md5.h"
30
+
31
+ /* little-endian word access macros */
32
+ #define GET_32BIT_LSB_FIRST(cp) \
33
+ (((uint32_t)(unsigned char)(cp)[0]) | \
34
+ ((uint32_t)(unsigned char)(cp)[1] << 8 ) | \
35
+ ((uint32_t)(unsigned char)(cp)[2] << 16) | \
36
+ ((uint32_t)(unsigned char)(cp)[3] << 24))
37
+
38
+ #define PUT_32BIT_LSB_FIRST(cp, value) \
39
+ do { \
40
+ (cp)[0] = (value) & 0xFF; \
41
+ (cp)[1] = ((value) >> 8) & 0xFF; \
42
+ (cp)[2] = ((value) >> 16) & 0xFF; \
43
+ (cp)[3] = ((value) >> 24) & 0xFF; \
44
+ } while(0)
45
+
46
+ /*
47
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
48
+ * initialization constants.
49
+ */
50
+ void MD5Init(struct MD5Context *ctx)
51
+ {
52
+ ctx->buf[0] = 0x67452301;
53
+ ctx->buf[1] = 0xefcdab89;
54
+ ctx->buf[2] = 0x98badcfe;
55
+ ctx->buf[3] = 0x10325476;
56
+
57
+ ctx->bits[0] = 0;
58
+ ctx->bits[1] = 0;
59
+
60
+ memset(ctx->in, 0, 64);
61
+ }
62
+
63
+ /*
64
+ * Update context to reflect the concatenation of another buffer full
65
+ * of bytes.
66
+ */
67
+ void MD5Update(struct MD5Context *ctx, unsigned char const *buf, uint32_t len)
68
+ {
69
+ uint32_t t;
70
+
71
+ /* Update bitcount */
72
+
73
+ t = ctx->bits[0];
74
+ if ((ctx->bits[0] = (t + ((uint32_t)len << 3)) & 0xffffffff) < t)
75
+ ctx->bits[1]++; /* Carry from low to high */
76
+ ctx->bits[1] += len >> 29;
77
+
78
+ t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
79
+
80
+ /* Handle any leading odd-sized chunks */
81
+
82
+ if (t) {
83
+ unsigned char *p = ctx->in + t;
84
+
85
+ t = 64 - t;
86
+ if (len < t) {
87
+ memcpy(p, buf, len);
88
+ return;
89
+ }
90
+ memcpy(p, buf, t);
91
+ MD5Transform(ctx->buf, ctx->in, ctx);
92
+ buf += t;
93
+ len -= t;
94
+ }
95
+ /* Process data in 64-byte chunks */
96
+
97
+ while (len >= 64) {
98
+ memcpy(ctx->in, buf, 64);
99
+ MD5Transform(ctx->buf, ctx->in, ctx);
100
+ buf += 64;
101
+ len -= 64;
102
+ }
103
+
104
+ /* Handle any remaining bytes of data. */
105
+
106
+ memcpy(ctx->in, buf, len);
107
+ }
108
+
109
+ /*
110
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
111
+ * 1 0* (64-bit count of bits processed, MSB-first)
112
+ */
113
+ void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
114
+ {
115
+ unsigned count;
116
+ unsigned char *p;
117
+
118
+ /* Compute number of bytes mod 64 */
119
+ count = (ctx->bits[0] >> 3) & 0x3F;
120
+
121
+ /* Set the first char of padding to 0x80. This is safe since there is
122
+ always at least one byte free */
123
+ p = ctx->in + count;
124
+ *p++ = 0x80;
125
+
126
+ /* Bytes of padding needed to make 64 bytes */
127
+ count = 64 - 1 - count;
128
+
129
+ /* Pad out to 56 mod 64 */
130
+ if (count < 8) {
131
+ /* Two lots of padding: Pad the first block to 64 bytes */
132
+ memset(p, 0, count);
133
+ MD5Transform(ctx->buf, ctx->in, ctx);
134
+
135
+ /* Now fill the next block with 56 bytes */
136
+ memset(ctx->in, 0, 56);
137
+ } else {
138
+ /* Pad block to 56 bytes */
139
+ memset(p, 0, count - 8);
140
+ }
141
+
142
+ /* Append length in bits and transform */
143
+ PUT_32BIT_LSB_FIRST(ctx->in + 56, ctx->bits[0]);
144
+ PUT_32BIT_LSB_FIRST(ctx->in + 60, ctx->bits[1]);
145
+
146
+ MD5Transform(ctx->buf, ctx->in, ctx);
147
+ PUT_32BIT_LSB_FIRST(digest, ctx->buf[0]);
148
+ PUT_32BIT_LSB_FIRST(digest + 4, ctx->buf[1]);
149
+ PUT_32BIT_LSB_FIRST(digest + 8, ctx->buf[2]);
150
+ PUT_32BIT_LSB_FIRST(digest + 12, ctx->buf[3]);
151
+ memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
152
+ }
153
+
154
+ #ifndef ASM_MD5
155
+
156
+ /* The four core functions - F1 is optimized somewhat */
157
+
158
+ /* #define F1(x, y, z) (x & y | ~x & z) */
159
+ #define F1(x, y, z) (z ^ (x & (y ^ z)))
160
+ #define F2(x, y, z) F1(z, x, y)
161
+ #define F3(x, y, z) (x ^ y ^ z)
162
+ #define F4(x, y, z) (y ^ (x | ~z))
163
+
164
+ /* This is the central step in the MD5 algorithm. */
165
+ /* debugging version: */
166
+ /*
167
+ #define MD5STEP(f, w, x, y, z, data, s) \
168
+ printf("MD5STEP: w: %x x: %x y: %x z: %x data: %x s: %x\n", \
169
+ w, x, y, z, data, s); \
170
+ printf("f(x,y,z) = %x\n", f(x,y,z)+data); \
171
+ ( w += f(x, y, z) + data, printf(" - w: %x ", w), \
172
+ w = w<<s | w>>(32-s), printf(" - w: %x\n", w), w += x )
173
+ */
174
+ #define MD5STEP(f, w, x, y, z, data, s) \
175
+ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
176
+
177
+ /*
178
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
179
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
180
+ * the data and converts bytes into longwords for this routine.
181
+ */
182
+ void MD5Transform(uint32_t buf[4], const unsigned char inext[64],
183
+ struct MD5Context *ctx)
184
+ {
185
+ register uint32_t a, b, c, d, i;
186
+ uint32_t in[16];
187
+
188
+ for (i = 0; i < 16; i++)
189
+ in[i] = GET_32BIT_LSB_FIRST(inext + 4 * i);
190
+
191
+ a = buf[0];
192
+ b = buf[1];
193
+ c = buf[2];
194
+ d = buf[3];
195
+
196
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
197
+
198
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
199
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
200
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
201
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
202
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
203
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
204
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
205
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
206
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
207
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
208
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
209
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
210
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
211
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
212
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
213
+
214
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
215
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
216
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
217
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
218
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
219
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
220
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
221
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
222
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
223
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
224
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
225
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
226
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
227
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
228
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
229
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
230
+
231
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
232
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
233
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
234
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
235
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
236
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
237
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
238
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
239
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
240
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
241
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
242
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
243
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
244
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
245
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
246
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
247
+
248
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
249
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
250
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
251
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
252
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
253
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
254
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
255
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
256
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
257
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
258
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
259
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
260
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
261
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
262
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
263
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
264
+
265
+ buf[0] += a;
266
+ buf[1] += b;
267
+ buf[2] += c;
268
+ buf[3] += d;
269
+ }
270
+
271
+ #ifdef DEBUG_MD5
272
+
273
+ #include <stdio.h>
274
+
275
+ void MD5DumpBytes(unsigned char *b, int len)
276
+ {
277
+ int i;
278
+ for (i=0; i<len; i++) {
279
+ if (i%32==0 && i!=0) {
280
+ printf("\n");
281
+ }
282
+ printf("%02x", b[i]&0xff);
283
+ }
284
+ printf("\n");
285
+ }
286
+
287
+ #endif /* DEBUG_MD5 */
288
+
289
+ #endif /* !MD5_ASM */
data/ext/md5.h ADDED
@@ -0,0 +1,41 @@
1
+ /* md5.h
2
+ ** interface to MD5 hash function
3
+ **
4
+ ** This code is in the Public Domain.
5
+ */
6
+
7
+ /** @file
8
+ * MD5 hash API.
9
+ */
10
+
11
+ #ifndef MD5_H
12
+ #define MD5_H
13
+
14
+ /* we use the uint32_t type from stdint.h
15
+ * if it is not available, add a typedef here:
16
+ */
17
+ /* make sure the stdint.h types are available */
18
+ #if defined(_MSC_VER) /* Microsoft Visual C++ */
19
+ typedef unsigned int uint32_t;
20
+ #else
21
+ #include <stdint.h>
22
+ #endif
23
+
24
+ struct MD5Context {
25
+ uint32_t buf[4];
26
+ uint32_t bits[2];
27
+ unsigned char in[64];
28
+ };
29
+
30
+ void MD5Init(struct MD5Context *context);
31
+ void MD5Update(struct MD5Context *context, unsigned char const *buf,
32
+ uint32_t len);
33
+ void MD5Final(unsigned char digest[16], struct MD5Context *context);
34
+ void MD5Transform(uint32_t buf[4], const unsigned char in[64],
35
+ struct MD5Context *ctx);
36
+
37
+ #ifdef DEBUG_MD5
38
+ void MD5DumpBytes(unsigned char *b, int len);
39
+ #endif
40
+
41
+ #endif /* !MD5_H */
data/ext/ostypes.h ADDED
@@ -0,0 +1,27 @@
1
+ /* ostypes.h
2
+ ** strophe XMPP client library -- type definitions for platforms
3
+ ** without stdint.h
4
+ **
5
+ ** Copyright (C) 2005-2008 OGG, LLC. All rights reserved.
6
+ **
7
+ ** This software is provided AS-IS with no warranty, either express
8
+ ** or implied.
9
+ **
10
+ ** This software is distributed under license and may not be copied,
11
+ ** modified or distributed except as expressly authorized under the
12
+ ** terms of the license contained in the file LICENSE.txt in this
13
+ ** distribution.
14
+ */
15
+
16
+ /** @file
17
+ * Type definitions for platforms without stdint.h.
18
+ */
19
+
20
+ #ifndef __LIBSTROPHE_OSTYPES_H__
21
+ #define __LIBSTROPHE_OSTYPES_H__
22
+
23
+ #ifdef _WIN32
24
+ typedef unsigned __int64 uint64_t;
25
+ #endif
26
+
27
+ #endif /* __LIBSTROPHE_OSTYPES_H__ */
data/ext/parser.c ADDED
@@ -0,0 +1,208 @@
1
+ /* parser.c
2
+ ** strophe XMPP client library -- xml parser handlers and utility functions
3
+ **
4
+ ** Copyright (C) 2005-2008 OGG, LLC. All rights reserved.
5
+ **
6
+ ** This software is provided AS-IS with no warranty, either express
7
+ ** or implied.
8
+ **
9
+ ** This software is distributed under license and may not be copied,
10
+ ** modified or distributed except as expressly authorized under the
11
+ ** terms of the license contained in the file LICENSE.txt in this
12
+ ** distribution.
13
+ */
14
+
15
+ /** @file
16
+ * XML parser handlers.
17
+ */
18
+
19
+ #include <stdio.h>
20
+ #include <stdlib.h>
21
+ #include <string.h>
22
+
23
+ #include "expat.h"
24
+
25
+ #include "strophe.h"
26
+ #include "common.h"
27
+
28
+ static void _log_open_tag(xmpp_conn_t * const conn,
29
+ const XML_Char **attr)
30
+ {
31
+ char buf[4096];
32
+ size_t len, pos;
33
+ int i;
34
+
35
+ pos = 0;
36
+ len = xmpp_snprintf(buf, 4096, "<stream:stream");
37
+ if (len < 0) return;
38
+
39
+ pos += len;
40
+
41
+ for (i = 0; attr[i]; i += 2) {
42
+ len = xmpp_snprintf(&buf[pos], 4096 - pos, " %s=\"%s\"",
43
+ attr[i], attr[i+1]);
44
+ if (len < 0) return;
45
+
46
+ pos += len;
47
+ }
48
+
49
+ len = xmpp_snprintf(&buf[pos], 4096 - pos, ">");
50
+ if (len < 0) return;
51
+
52
+ xmpp_debug(conn->ctx, "xmpp", "RECV: %s", buf);
53
+ }
54
+
55
+ void parser_handle_start(void *userdata,
56
+ const XML_Char *name,
57
+ const XML_Char **attr)
58
+ {
59
+ xmpp_conn_t *conn = (xmpp_conn_t *)userdata;
60
+ xmpp_stanza_t *child;
61
+
62
+ if (conn->depth == 0) {
63
+ /* we're expecting a stream:stream tag. */
64
+ if (strcmp(name, "stream:stream") != 0) {
65
+ xmpp_error(conn->ctx, "xmpp",
66
+ "Server did not open valid stream.");
67
+ conn->error = -3;
68
+ conn_disconnect(conn);
69
+ } else {
70
+ _log_open_tag(conn, attr);
71
+
72
+ if (conn->stream_id) xmpp_free(conn->ctx, conn->stream_id);
73
+ conn->stream_id = xmpp_strdup(conn->ctx, "foo");
74
+ if (!conn->stream_id) {
75
+ xmpp_error(conn->ctx, "xmpp",
76
+ "Memory allocation failure.");
77
+ conn->error = -2;
78
+ conn_disconnect(conn);
79
+ }
80
+
81
+ /* call stream open handler */
82
+ conn->open_handler(conn);
83
+ }
84
+ } else {
85
+ /* build stanzas at depth 1 */
86
+ if (!conn->stanza && conn->depth != 1) {
87
+ /* something terrible happened */
88
+ /* FIXME: shutdown disconnect */
89
+ xmpp_debug(conn->ctx, "xmpp", "oops, where did our stanza go?");
90
+ } else if (!conn->stanza) {
91
+ /* starting a new toplevel stanza */
92
+ conn->stanza = xmpp_stanza_new(conn->ctx);
93
+ if (!conn->stanza) {
94
+ /* FIXME: can't allocate, disconnect */
95
+ }
96
+ xmpp_stanza_set_name(conn->stanza, name);
97
+ xmpp_stanza_set_attributes(conn->stanza, attr);
98
+ } else {
99
+ /* starting a child of conn->stanza */
100
+ child = xmpp_stanza_new(conn->ctx);
101
+ if (!child) {
102
+ /* FIXME: can't allocate, disconnect */
103
+ }
104
+ xmpp_stanza_set_name(child, name);
105
+ xmpp_stanza_set_attributes(child, attr);
106
+
107
+ /* add child to parent */
108
+ xmpp_stanza_add_child(conn->stanza, child);
109
+
110
+ /* the child is owned by the toplevel stanza now */
111
+ xmpp_stanza_release(child);
112
+
113
+ /* make child the current stanza */
114
+ conn->stanza = child;
115
+ }
116
+ }
117
+
118
+ conn->depth++;
119
+ }
120
+
121
+ void parser_handle_end(void *userdata, const XML_Char *name)
122
+ {
123
+ xmpp_conn_t *conn = (xmpp_conn_t *)userdata;
124
+ char *buf;
125
+ size_t len;
126
+ xmpp_stanza_t *stanza;
127
+
128
+ conn->depth--;
129
+
130
+ if (conn->depth == 0) {
131
+ /* got a closing stream tag */
132
+ xmpp_debug(conn->ctx, "xmpp", "RECV: </stream:stream>");
133
+ conn_disconnect_clean(conn);
134
+ } else {
135
+ if (conn->stanza->parent) {
136
+ /* we're finishing a child stanza, so set current to the parent */
137
+ conn->stanza = conn->stanza->parent;
138
+ } else {
139
+ /* we're finishing a toplevel stanza, so fire off handler */
140
+ if (xmpp_stanza_to_text(conn->stanza, &buf, &len) == 0) {
141
+ xmpp_debug(conn->ctx, "xmpp", "RECV: %s", buf);
142
+ xmpp_free(conn->ctx, buf);
143
+ }
144
+
145
+ stanza = xmpp_stanza_clone(conn->stanza);
146
+ xmpp_stanza_release(conn->stanza);
147
+ conn->stanza = NULL;
148
+
149
+ /* fire handlers */
150
+ handler_fire_stanza(conn, stanza);
151
+
152
+ xmpp_stanza_release(stanza);
153
+ }
154
+ }
155
+ }
156
+
157
+ void parser_handle_character(void *userdata, const XML_Char *s, int len)
158
+ {
159
+ xmpp_conn_t *conn = (xmpp_conn_t *)userdata;
160
+ xmpp_stanza_t *stanza;
161
+
162
+ if (conn->depth < 2) return;
163
+
164
+ /* create and populate stanza */
165
+ stanza = xmpp_stanza_new(conn->ctx);
166
+ if (!stanza) {
167
+ /* FIXME: allocation error, disconnect */
168
+ return;
169
+ }
170
+ xmpp_stanza_set_text_with_size(stanza, s, len);
171
+
172
+ xmpp_stanza_add_child(conn->stanza, stanza);
173
+ xmpp_stanza_release(stanza);
174
+ }
175
+
176
+ /* prepares a parser reset. this is called from handlers. we can't
177
+ * reset the parser immediately as it is not reentrant. */
178
+ void parser_prepare_reset(xmpp_conn_t * const conn,
179
+ xmpp_open_handler handler)
180
+ {
181
+ conn->reset_parser = 1;
182
+ conn->open_handler = handler;
183
+ }
184
+
185
+ /* shuts down and restarts XML parser. true on success */
186
+ int parser_reset(xmpp_conn_t * const conn)
187
+ {
188
+ conn->reset_parser = 0;
189
+
190
+ if (conn->parser)
191
+ XML_ParserFree(conn->parser);
192
+
193
+ if (conn->stanza)
194
+ xmpp_stanza_release(conn->stanza);
195
+
196
+ conn->parser = XML_ParserCreate(NULL);
197
+ if (!conn->parser) return 0;
198
+
199
+ conn->depth = 0;
200
+ conn->stanza = NULL;
201
+ XML_SetUserData(conn->parser, conn);
202
+ XML_SetElementHandler(conn->parser, parser_handle_start,
203
+ parser_handle_end);
204
+ XML_SetCharacterDataHandler(conn->parser, parser_handle_character);
205
+
206
+ return 1;
207
+ }
208
+