stropheruby 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +9 -0
- data/History.txt +4 -0
- data/Manifest.txt +40 -0
- data/PostInstall.txt +4 -0
- data/README.txt +28 -0
- data/Rakefile +21 -0
- data/examples/xmpp_client.rb +77 -0
- data/ext/auth.c +990 -0
- data/ext/common.h +287 -0
- data/ext/conn.c +611 -0
- data/ext/ctx.c +416 -0
- data/ext/event.c +351 -0
- data/ext/extconf.rb +8 -0
- data/ext/handler.c +592 -0
- data/ext/hash.c +278 -0
- data/ext/hash.h +64 -0
- data/ext/jid.c +177 -0
- data/ext/md5.c +289 -0
- data/ext/md5.h +41 -0
- data/ext/ostypes.h +27 -0
- data/ext/parser.c +208 -0
- data/ext/sasl.c +614 -0
- data/ext/sasl.h +44 -0
- data/ext/sha1.c +389 -0
- data/ext/sha1.h +31 -0
- data/ext/snprintf.c +839 -0
- data/ext/sock.c +911 -0
- data/ext/sock.h +51 -0
- data/ext/stanza.c +908 -0
- data/ext/strophe.h +372 -0
- data/ext/strophe_ruby.c +721 -0
- data/ext/thread.c +119 -0
- data/ext/thread.h +43 -0
- data/ext/tls.h +46 -0
- data/ext/tls_dummy.c +89 -0
- data/ext/util.c +107 -0
- data/ext/util.h +32 -0
- data/lib/strophe_ruby.rb +6 -0
- data/test/test_helper.rb +3 -0
- data/test/test_strophe_ruby.rb +11 -0
- data/test/test_strophe_ruby_extn.rb +9 -0
- metadata +111 -0
data/ext/hash.c
ADDED
@@ -0,0 +1,278 @@
|
|
1
|
+
/* hash.c
|
2
|
+
** strophe XMPP client library -- hash table implementation
|
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
|
+
* Hash tables.
|
17
|
+
*/
|
18
|
+
|
19
|
+
#include <stdlib.h>
|
20
|
+
#include <string.h>
|
21
|
+
|
22
|
+
#include "strophe.h"
|
23
|
+
#include "common.h"
|
24
|
+
#include "hash.h"
|
25
|
+
|
26
|
+
/* private types */
|
27
|
+
typedef struct _hashentry_t hashentry_t;
|
28
|
+
|
29
|
+
struct _hashentry_t {
|
30
|
+
hashentry_t *next;
|
31
|
+
char *key;
|
32
|
+
void *value;
|
33
|
+
};
|
34
|
+
|
35
|
+
struct _hash_t {
|
36
|
+
unsigned int ref;
|
37
|
+
xmpp_ctx_t *ctx;
|
38
|
+
hash_free_func free;
|
39
|
+
int length;
|
40
|
+
int num_keys;
|
41
|
+
hashentry_t **entries;
|
42
|
+
};
|
43
|
+
|
44
|
+
struct _hash_iterator_t {
|
45
|
+
unsigned int ref;
|
46
|
+
hash_t *table;
|
47
|
+
hashentry_t *entry;
|
48
|
+
int index;
|
49
|
+
};
|
50
|
+
|
51
|
+
/** allocate and initialize a new hash table */
|
52
|
+
hash_t *hash_new(xmpp_ctx_t * const ctx, const int size,
|
53
|
+
hash_free_func free)
|
54
|
+
{
|
55
|
+
hash_t *result = NULL;
|
56
|
+
|
57
|
+
result = xmpp_alloc(ctx, sizeof(hash_t));
|
58
|
+
if (result != NULL) {
|
59
|
+
result->entries = xmpp_alloc(ctx, size * sizeof(hashentry_t *));
|
60
|
+
if (result->entries == NULL) {
|
61
|
+
xmpp_free(ctx, result);
|
62
|
+
return NULL;
|
63
|
+
}
|
64
|
+
memset(result->entries, 0, size * sizeof(hashentry_t *));
|
65
|
+
result->length = size;
|
66
|
+
|
67
|
+
result->ctx = ctx;
|
68
|
+
result->free = free;
|
69
|
+
result->num_keys = 0;
|
70
|
+
/* give the caller a reference */
|
71
|
+
result->ref = 1;
|
72
|
+
}
|
73
|
+
|
74
|
+
return result;
|
75
|
+
}
|
76
|
+
|
77
|
+
/** obtain a new reference to an existing hash table */
|
78
|
+
hash_t *hash_clone(hash_t * const table)
|
79
|
+
{
|
80
|
+
table->ref++;
|
81
|
+
return table;
|
82
|
+
}
|
83
|
+
|
84
|
+
/** release a hash table that is no longer needed */
|
85
|
+
void hash_release(hash_t * const table)
|
86
|
+
{
|
87
|
+
xmpp_ctx_t *ctx = table->ctx;
|
88
|
+
hashentry_t *entry, *next;
|
89
|
+
int i;
|
90
|
+
|
91
|
+
if (table->ref > 1)
|
92
|
+
table->ref--;
|
93
|
+
else {
|
94
|
+
for (i = 0; i < table->length; i++) {
|
95
|
+
entry = table->entries[i];
|
96
|
+
while (entry != NULL) {
|
97
|
+
next = entry->next;
|
98
|
+
xmpp_free(ctx, entry->key);
|
99
|
+
if (table->free) table->free(ctx, entry->value);
|
100
|
+
xmpp_free(ctx, entry);
|
101
|
+
entry = next;
|
102
|
+
}
|
103
|
+
}
|
104
|
+
xmpp_free(ctx, table->entries);
|
105
|
+
xmpp_free(ctx, table);
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
/** hash a key for our table lookup */
|
110
|
+
static int _hash_key(hash_t *table, const char *key)
|
111
|
+
{
|
112
|
+
int hash = 0;
|
113
|
+
int shift = 0;
|
114
|
+
const char *c = key;
|
115
|
+
|
116
|
+
while (*c != '\0') {
|
117
|
+
/* assume 32 bit ints */
|
118
|
+
hash ^= ((int)*c++ << shift);
|
119
|
+
shift += 8;
|
120
|
+
if (shift > 24) shift = 0;
|
121
|
+
}
|
122
|
+
|
123
|
+
return hash % table->length;
|
124
|
+
}
|
125
|
+
|
126
|
+
/** add a key, value pair to a hash table.
|
127
|
+
* each key can appear only once; the value of any
|
128
|
+
* identical key will be replaced
|
129
|
+
*/
|
130
|
+
int hash_add(hash_t *table, const char * const key, void *data)
|
131
|
+
{
|
132
|
+
xmpp_ctx_t *ctx = table->ctx;
|
133
|
+
hashentry_t *entry = NULL;
|
134
|
+
int index = _hash_key(table, key);
|
135
|
+
|
136
|
+
/* drop existing entry, if any */
|
137
|
+
hash_drop(table, key);
|
138
|
+
|
139
|
+
/* allocate and fill a new entry */
|
140
|
+
entry = xmpp_alloc(ctx, sizeof(hashentry_t));
|
141
|
+
if (!entry) return -1;
|
142
|
+
entry->key = xmpp_strdup(ctx, key);
|
143
|
+
if (!entry->key) {
|
144
|
+
xmpp_free(ctx, entry);
|
145
|
+
return -1;
|
146
|
+
}
|
147
|
+
entry->value = data;
|
148
|
+
/* insert ourselves in the linked list */
|
149
|
+
/* TODO: this leaks duplicate keys */
|
150
|
+
entry->next = table->entries[index];
|
151
|
+
table->entries[index] = entry;
|
152
|
+
table->num_keys++;
|
153
|
+
|
154
|
+
return 0;
|
155
|
+
}
|
156
|
+
|
157
|
+
/** look up a key in a hash table */
|
158
|
+
void *hash_get(hash_t *table, const char *key)
|
159
|
+
{
|
160
|
+
hashentry_t *entry;
|
161
|
+
int index = _hash_key(table, key);
|
162
|
+
void *result = NULL;
|
163
|
+
|
164
|
+
/* look up the hash entry */
|
165
|
+
entry = table->entries[index];
|
166
|
+
while (entry != NULL) {
|
167
|
+
/* traverse the linked list looking for the key */
|
168
|
+
if (!strcmp(key, entry->key)) {
|
169
|
+
/* match */
|
170
|
+
result = entry->value;
|
171
|
+
return result;
|
172
|
+
}
|
173
|
+
entry = entry->next;
|
174
|
+
}
|
175
|
+
/* no match */
|
176
|
+
return result;
|
177
|
+
}
|
178
|
+
|
179
|
+
/** delete a key from a hash table */
|
180
|
+
int hash_drop(hash_t *table, const char *key)
|
181
|
+
{
|
182
|
+
xmpp_ctx_t *ctx = table->ctx;
|
183
|
+
hashentry_t *entry, *prev;
|
184
|
+
int index = _hash_key(table, key);
|
185
|
+
|
186
|
+
/* look up the hash entry */
|
187
|
+
entry = table->entries[index];
|
188
|
+
prev = NULL;
|
189
|
+
while (entry != NULL) {
|
190
|
+
/* traverse the linked list looking for the key */
|
191
|
+
if (!strcmp(key, entry->key)) {
|
192
|
+
/* match, remove the entry */
|
193
|
+
xmpp_free(ctx, entry->key);
|
194
|
+
if (table->free) table->free(ctx, entry->value);
|
195
|
+
if (prev == NULL) {
|
196
|
+
table->entries[index] = entry->next;
|
197
|
+
} else {
|
198
|
+
prev->next = entry->next;
|
199
|
+
}
|
200
|
+
xmpp_free(ctx, entry);
|
201
|
+
table->num_keys--;
|
202
|
+
return 0;
|
203
|
+
}
|
204
|
+
prev = entry;
|
205
|
+
entry = entry->next;
|
206
|
+
}
|
207
|
+
/* no match */
|
208
|
+
return -1;
|
209
|
+
}
|
210
|
+
|
211
|
+
int hash_num_keys(hash_t *table)
|
212
|
+
{
|
213
|
+
return table->num_keys;
|
214
|
+
}
|
215
|
+
|
216
|
+
/** allocate and initialize a new iterator */
|
217
|
+
hash_iterator_t *hash_iter_new(hash_t *table)
|
218
|
+
{
|
219
|
+
xmpp_ctx_t *ctx = table->ctx;
|
220
|
+
hash_iterator_t *iter;
|
221
|
+
|
222
|
+
iter = xmpp_alloc(ctx, sizeof(*iter));
|
223
|
+
if (iter != NULL) {
|
224
|
+
iter->ref = 1;
|
225
|
+
iter->table = hash_clone(table);
|
226
|
+
iter->entry = NULL;
|
227
|
+
iter->index = -1;
|
228
|
+
}
|
229
|
+
|
230
|
+
return iter;
|
231
|
+
}
|
232
|
+
|
233
|
+
|
234
|
+
/** release an iterator that is no longer needed */
|
235
|
+
void hash_iter_release(hash_iterator_t *iter)
|
236
|
+
{
|
237
|
+
xmpp_ctx_t *ctx = iter->table->ctx;
|
238
|
+
|
239
|
+
iter->ref--;
|
240
|
+
|
241
|
+
if (iter->ref <= 0) {
|
242
|
+
hash_release(iter->table);
|
243
|
+
xmpp_free(ctx, iter);
|
244
|
+
}
|
245
|
+
}
|
246
|
+
|
247
|
+
/** return the next hash table key from the iterator.
|
248
|
+
the returned key should not be freed */
|
249
|
+
const char * hash_iter_next(hash_iterator_t *iter)
|
250
|
+
{
|
251
|
+
hash_t *table = iter->table;
|
252
|
+
hashentry_t *entry = iter->entry;
|
253
|
+
int i = iter->index + 1;
|
254
|
+
|
255
|
+
/* advance until we find the next entry */
|
256
|
+
if (entry != NULL) entry = entry->next;
|
257
|
+
if (entry == NULL) {
|
258
|
+
/* we're off the end of list, search for a new entry */
|
259
|
+
while (i < iter->table->length) {
|
260
|
+
entry = table->entries[i];
|
261
|
+
if (entry != NULL) {
|
262
|
+
iter->index = i;
|
263
|
+
break;
|
264
|
+
}
|
265
|
+
i++;
|
266
|
+
}
|
267
|
+
}
|
268
|
+
|
269
|
+
if ((entry == NULL) || (i >= table->length)) {
|
270
|
+
/* no more keys! */
|
271
|
+
return NULL;
|
272
|
+
}
|
273
|
+
|
274
|
+
/* remember our current match */
|
275
|
+
iter->entry = entry;
|
276
|
+
return entry->key;
|
277
|
+
}
|
278
|
+
|
data/ext/hash.h
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
/* hash.h
|
2
|
+
** strophe XMPP client library -- hash table interface
|
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
|
+
* Hash table API.
|
17
|
+
*/
|
18
|
+
|
19
|
+
#ifndef __LIBSTROPHE_HASH_H__
|
20
|
+
#define __LIBSTROPHE_HASH_H__
|
21
|
+
|
22
|
+
typedef struct _hash_t hash_t;
|
23
|
+
|
24
|
+
typedef void (*hash_free_func)(const xmpp_ctx_t * const ctx, void *p);
|
25
|
+
|
26
|
+
/** allocate and initialize a new hash table */
|
27
|
+
hash_t *hash_new(xmpp_ctx_t * const ctx, const int size,
|
28
|
+
hash_free_func free);
|
29
|
+
|
30
|
+
/** allocate a new reference to an existing hash table */
|
31
|
+
hash_t *hash_clone(hash_t * const table);
|
32
|
+
|
33
|
+
/** release a hash table when no longer needed */
|
34
|
+
void hash_release(hash_t * const table);
|
35
|
+
|
36
|
+
/** add a key, value pair to a hash table.
|
37
|
+
* each key can appear only once; the value of any
|
38
|
+
* identical key will be replaced
|
39
|
+
*/
|
40
|
+
int hash_add(hash_t *table, const char * const key, void *data);
|
41
|
+
|
42
|
+
/** look up a key in a hash table */
|
43
|
+
void *hash_get(hash_t *table, const char *key);
|
44
|
+
|
45
|
+
/** delete a key from a hash table */
|
46
|
+
int hash_drop(hash_t *table, const char *key);
|
47
|
+
|
48
|
+
/** return the number of keys in a hash */
|
49
|
+
int hash_num_keys(hash_t *table);
|
50
|
+
|
51
|
+
/** hash key iterator functions */
|
52
|
+
typedef struct _hash_iterator_t hash_iterator_t;
|
53
|
+
|
54
|
+
/** allocate and initialize a new iterator */
|
55
|
+
hash_iterator_t *hash_iter_new(hash_t *table);
|
56
|
+
|
57
|
+
/** release an iterator that is no longer needed */
|
58
|
+
void hash_iter_release(hash_iterator_t *iter);
|
59
|
+
|
60
|
+
/** return the next hash table key from the iterator.
|
61
|
+
the returned key should not be freed */
|
62
|
+
const char * hash_iter_next(hash_iterator_t *iter);
|
63
|
+
|
64
|
+
#endif /* __LIBXMPPP_HASH_H__ */
|
data/ext/jid.c
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
/* jid.c
|
2
|
+
** strophe XMPP client library -- helper functions for parsing JIDs
|
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
|
+
* JID creation and parsing.
|
17
|
+
*/
|
18
|
+
|
19
|
+
#include <string.h>
|
20
|
+
|
21
|
+
#include "strophe.h"
|
22
|
+
#include "common.h"
|
23
|
+
|
24
|
+
/** Create a JID string from component parts node, domain, and resource.
|
25
|
+
*
|
26
|
+
* @param ctx the Strophe context object
|
27
|
+
* @param node a string representing the node
|
28
|
+
* @param domain a string representing the domain. Required.
|
29
|
+
* @param resource a string representing the resource
|
30
|
+
*
|
31
|
+
* @return an allocated string with the full JID or NULL if no domain
|
32
|
+
* is specified
|
33
|
+
*/
|
34
|
+
char *xmpp_jid_new(xmpp_ctx_t *ctx, const char *node,
|
35
|
+
const char *domain,
|
36
|
+
const char *resource)
|
37
|
+
{
|
38
|
+
char *result;
|
39
|
+
int len,nlen,dlen,rlen;
|
40
|
+
|
41
|
+
/* jid must at least have a domain */
|
42
|
+
if (domain == NULL) return NULL;
|
43
|
+
|
44
|
+
/* accumulate lengths */
|
45
|
+
dlen = strlen(domain);
|
46
|
+
nlen = (node) ? strlen(node) + 1 : 0;
|
47
|
+
rlen = (resource) ? strlen(resource) + 1 : 0;
|
48
|
+
len = nlen + dlen + rlen;
|
49
|
+
|
50
|
+
/* concat components */
|
51
|
+
result = xmpp_alloc(ctx, len + 1);
|
52
|
+
if (result != NULL) {
|
53
|
+
if (node != NULL) {
|
54
|
+
memcpy(result, node, nlen - 1);
|
55
|
+
result[nlen-1] = '@';
|
56
|
+
}
|
57
|
+
memcpy(result + nlen, domain, dlen);
|
58
|
+
if (resource != NULL) {
|
59
|
+
result[nlen+dlen] = '/';
|
60
|
+
memcpy(result+nlen+dlen+1, resource, rlen - 1);
|
61
|
+
}
|
62
|
+
result[nlen+dlen+rlen] = '\0';
|
63
|
+
}
|
64
|
+
|
65
|
+
return result;
|
66
|
+
}
|
67
|
+
|
68
|
+
/** Create a bare JID from a JID.
|
69
|
+
*
|
70
|
+
* @param ctx the Strophe context object
|
71
|
+
* @param jid the JID
|
72
|
+
*
|
73
|
+
* @return an allocated string with the bare JID or NULL on an error
|
74
|
+
*/
|
75
|
+
char *xmpp_jid_bare(xmpp_ctx_t *ctx, const char *jid)
|
76
|
+
{
|
77
|
+
char *result;
|
78
|
+
const char *c;
|
79
|
+
|
80
|
+
c = strchr(jid, '/');
|
81
|
+
if (c == NULL) return xmpp_strdup(ctx, jid);
|
82
|
+
|
83
|
+
result = xmpp_alloc(ctx, c-jid+1);
|
84
|
+
if (result != NULL) {
|
85
|
+
memcpy(result, jid, c-jid);
|
86
|
+
result[c-jid] = '\0';
|
87
|
+
}
|
88
|
+
|
89
|
+
return result;
|
90
|
+
}
|
91
|
+
|
92
|
+
/** Create a node string from a JID.
|
93
|
+
*
|
94
|
+
* @param ctx a Strophe context object
|
95
|
+
* @param jid the JID
|
96
|
+
*
|
97
|
+
* @return an allocated string with the node or NULL if no node is found
|
98
|
+
* or an error occurs
|
99
|
+
*/
|
100
|
+
char *xmpp_jid_node(xmpp_ctx_t *ctx, const char *jid)
|
101
|
+
{
|
102
|
+
char *result = NULL;
|
103
|
+
const char *c;
|
104
|
+
|
105
|
+
c = strchr(jid, '@');
|
106
|
+
if (c != NULL) {
|
107
|
+
result = xmpp_alloc(ctx, (c-jid) + 1);
|
108
|
+
if (result != NULL) {
|
109
|
+
memcpy(result, jid, (c-jid));
|
110
|
+
result[c-jid] = '\0';
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
return result;
|
115
|
+
}
|
116
|
+
|
117
|
+
/** Create a domain string from a JID.
|
118
|
+
*
|
119
|
+
* @param ctx the Strophe context object
|
120
|
+
* @param jid the JID
|
121
|
+
*
|
122
|
+
* @return an allocated string with the domain or NULL on an error
|
123
|
+
*/
|
124
|
+
char *xmpp_jid_domain(xmpp_ctx_t *ctx, const char *jid)
|
125
|
+
{
|
126
|
+
char *result = NULL;
|
127
|
+
const char *c,*s;
|
128
|
+
|
129
|
+
c = strchr(jid, '@');
|
130
|
+
if (c == NULL) {
|
131
|
+
/* no node, assume domain */
|
132
|
+
c = jid;
|
133
|
+
} else {
|
134
|
+
/* advance past the separator */
|
135
|
+
c++;
|
136
|
+
}
|
137
|
+
s = strchr(c, '/');
|
138
|
+
if (s == NULL) {
|
139
|
+
/* no resource */
|
140
|
+
s = c + strlen(c);
|
141
|
+
}
|
142
|
+
result = xmpp_alloc(ctx, (s-c) + 1);
|
143
|
+
if (result != NULL) {
|
144
|
+
memcpy(result, c, (s-c));
|
145
|
+
result[s-c] = '\0';
|
146
|
+
}
|
147
|
+
|
148
|
+
return result;
|
149
|
+
}
|
150
|
+
|
151
|
+
/** Create a resource string from a JID.
|
152
|
+
*
|
153
|
+
* @param ctx a Strophe context object
|
154
|
+
* @param jid the JID
|
155
|
+
*
|
156
|
+
* @return an allocated string with the resource or NULL if no resource
|
157
|
+
* is found or an error occurs
|
158
|
+
*/
|
159
|
+
char *xmpp_jid_resource(xmpp_ctx_t *ctx, const char *jid)
|
160
|
+
{
|
161
|
+
char *result = NULL;
|
162
|
+
const char *c;
|
163
|
+
int len;
|
164
|
+
|
165
|
+
c = strchr(jid, '/');
|
166
|
+
if (c != NULL) {
|
167
|
+
c++;
|
168
|
+
len = strlen(c);
|
169
|
+
result = xmpp_alloc(ctx, len + 1);
|
170
|
+
if (result != NULL) {
|
171
|
+
memcpy(result, c, len);
|
172
|
+
result[len] = '\0';
|
173
|
+
}
|
174
|
+
}
|
175
|
+
|
176
|
+
return result;
|
177
|
+
}
|