stropheruby 0.1.3
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/.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
|
+
}
|