yong-stropheruby 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,206 @@
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_disconnect(conn);
68
+ } else {
69
+ _log_open_tag(conn, attr);
70
+
71
+ if (conn->stream_id) xmpp_free(conn->ctx, conn->stream_id);
72
+ conn->stream_id = xmpp_strdup(conn->ctx, "foo");
73
+ if (!conn->stream_id) {
74
+ xmpp_error(conn->ctx, "xmpp",
75
+ "Memory allocation failure.");
76
+ conn_disconnect(conn);
77
+ }
78
+
79
+ /* call stream open handler */
80
+ conn->open_handler(conn);
81
+ }
82
+ } else {
83
+ /* build stanzas at depth 1 */
84
+ if (!conn->stanza && conn->depth != 1) {
85
+ /* something terrible happened */
86
+ /* FIXME: shutdown disconnect */
87
+ xmpp_debug(conn->ctx, "xmpp", "oops, where did our stanza go?");
88
+ } else if (!conn->stanza) {
89
+ /* starting a new toplevel stanza */
90
+ conn->stanza = xmpp_stanza_new(conn->ctx);
91
+ if (!conn->stanza) {
92
+ /* FIXME: can't allocate, disconnect */
93
+ }
94
+ xmpp_stanza_set_name(conn->stanza, name);
95
+ xmpp_stanza_set_attributes(conn->stanza, attr);
96
+ } else {
97
+ /* starting a child of conn->stanza */
98
+ child = xmpp_stanza_new(conn->ctx);
99
+ if (!child) {
100
+ /* FIXME: can't allocate, disconnect */
101
+ }
102
+ xmpp_stanza_set_name(child, name);
103
+ xmpp_stanza_set_attributes(child, attr);
104
+
105
+ /* add child to parent */
106
+ xmpp_stanza_add_child(conn->stanza, child);
107
+
108
+ /* the child is owned by the toplevel stanza now */
109
+ xmpp_stanza_release(child);
110
+
111
+ /* make child the current stanza */
112
+ conn->stanza = child;
113
+ }
114
+ }
115
+
116
+ conn->depth++;
117
+ }
118
+
119
+ void parser_handle_end(void *userdata, const XML_Char *name)
120
+ {
121
+ xmpp_conn_t *conn = (xmpp_conn_t *)userdata;
122
+ char *buf;
123
+ size_t len;
124
+ xmpp_stanza_t *stanza;
125
+
126
+ conn->depth--;
127
+
128
+ if (conn->depth == 0) {
129
+ /* got a closing stream tag */
130
+ xmpp_debug(conn->ctx, "xmpp", "RECV: </stream:stream>");
131
+ conn_disconnect_clean(conn);
132
+ } else {
133
+ if (conn->stanza->parent) {
134
+ /* we're finishing a child stanza, so set current to the parent */
135
+ conn->stanza = conn->stanza->parent;
136
+ } else {
137
+ /* we're finishing a toplevel stanza, so fire off handler */
138
+ if (xmpp_stanza_to_text(conn->stanza, &buf, &len) == 0) {
139
+ xmpp_debug(conn->ctx, "xmpp", "RECV: %s", buf);
140
+ xmpp_free(conn->ctx, buf);
141
+ }
142
+
143
+ stanza = xmpp_stanza_clone(conn->stanza);
144
+ xmpp_stanza_release(conn->stanza);
145
+ conn->stanza = NULL;
146
+
147
+ /* fire handlers */
148
+ handler_fire_stanza(conn, stanza);
149
+
150
+ xmpp_stanza_release(stanza);
151
+ }
152
+ }
153
+ }
154
+
155
+ void parser_handle_character(void *userdata, const XML_Char *s, int len)
156
+ {
157
+ xmpp_conn_t *conn = (xmpp_conn_t *)userdata;
158
+ xmpp_stanza_t *stanza;
159
+
160
+ if (conn->depth < 2) return;
161
+
162
+ /* create and populate stanza */
163
+ stanza = xmpp_stanza_new(conn->ctx);
164
+ if (!stanza) {
165
+ /* FIXME: allocation error, disconnect */
166
+ return;
167
+ }
168
+ xmpp_stanza_set_text_with_size(stanza, s, len);
169
+
170
+ xmpp_stanza_add_child(conn->stanza, stanza);
171
+ xmpp_stanza_release(stanza);
172
+ }
173
+
174
+ /* prepares a parser reset. this is called from handlers. we can't
175
+ * reset the parser immediately as it is not reentrant. */
176
+ void parser_prepare_reset(xmpp_conn_t * const conn,
177
+ xmpp_open_handler handler)
178
+ {
179
+ conn->reset_parser = 1;
180
+ conn->open_handler = handler;
181
+ }
182
+
183
+ /* shuts down and restarts XML parser. true on success */
184
+ int parser_reset(xmpp_conn_t * const conn)
185
+ {
186
+ conn->reset_parser = 0;
187
+
188
+ if (conn->parser)
189
+ XML_ParserFree(conn->parser);
190
+
191
+ if (conn->stanza)
192
+ xmpp_stanza_release(conn->stanza);
193
+
194
+ conn->parser = XML_ParserCreate(NULL);
195
+ if (!conn->parser) return 0;
196
+
197
+ conn->depth = 0;
198
+ conn->stanza = NULL;
199
+ XML_SetUserData(conn->parser, conn);
200
+ XML_SetElementHandler(conn->parser, parser_handle_start,
201
+ parser_handle_end);
202
+ XML_SetCharacterDataHandler(conn->parser, parser_handle_character);
203
+
204
+ return 1;
205
+ }
206
+