equal
deleted
inserted
replaced
28 |
28 |
29 typedef struct { |
29 typedef struct { |
30 char *category; |
30 char *category; |
31 char *type; |
31 char *type; |
32 char *name; |
32 char *name; |
33 } identity; |
33 } identity_t; |
34 |
34 |
35 typedef struct { |
35 typedef struct { |
36 GHashTable *fields; |
36 GHashTable *fields; |
37 } dataform; |
37 } dataform_t; |
38 |
38 |
39 typedef struct { |
39 typedef struct { |
40 GHashTable *identities; |
40 GHashTable *identities; |
41 GHashTable *features; |
41 GHashTable *features; |
42 GHashTable *forms; |
42 GHashTable *forms; |
43 } caps; |
43 } caps_t; |
44 |
44 |
45 static GHashTable *caps_cache = NULL; |
45 static GHashTable *caps_cache = NULL; |
46 |
46 |
47 void caps_destroy(gpointer data) |
47 void caps_destroy(gpointer data) |
48 { |
48 { |
49 caps *c = data; |
49 caps_t *c = data; |
50 g_hash_table_destroy(c->identities); |
50 g_hash_table_destroy(c->identities); |
51 g_hash_table_destroy(c->features); |
51 g_hash_table_destroy(c->features); |
52 g_hash_table_destroy(c->forms); |
52 g_hash_table_destroy(c->forms); |
53 g_free(c); |
53 g_free(c); |
54 } |
54 } |
55 |
55 |
56 void identity_destroy(gpointer data) |
56 void identity_destroy(gpointer data) |
57 { |
57 { |
58 identity *i = data; |
58 identity_t *i = data; |
59 g_free(i->category); |
59 g_free(i->category); |
60 g_free(i->type); |
60 g_free(i->type); |
61 g_free(i->name); |
61 g_free(i->name); |
62 g_free(i); |
62 g_free(i); |
63 } |
63 } |
64 |
64 |
65 void form_destroy(gpointer data) |
65 void form_destroy(gpointer data) |
66 { |
66 { |
67 dataform *f = data; |
67 dataform_t *f = data; |
68 g_hash_table_destroy(f->fields); |
68 g_hash_table_destroy(f->fields); |
69 g_free(f); |
69 g_free(f); |
70 } |
70 } |
71 |
71 |
72 void field_destroy(gpointer data) |
72 void field_destroy(gpointer data) |
93 |
93 |
94 void caps_add(const char *hash) |
94 void caps_add(const char *hash) |
95 { |
95 { |
96 if (!hash) |
96 if (!hash) |
97 return; |
97 return; |
98 caps *c = g_new0(caps, 1); |
98 caps_t *c = g_new0(caps_t, 1); |
99 c->features = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); |
99 c->features = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); |
100 c->identities = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, identity_destroy); |
100 c->identities = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, identity_destroy); |
101 c->forms = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, form_destroy); |
101 c->forms = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, form_destroy); |
102 g_hash_table_replace(caps_cache, g_strdup(hash), c); |
102 g_hash_table_replace(caps_cache, g_strdup(hash), c); |
103 } |
103 } |
111 |
111 |
112 /* if hash is not verified, this will bind capabilities set only with bare jid */ |
112 /* if hash is not verified, this will bind capabilities set only with bare jid */ |
113 void caps_move_to_local(char *hash, char *bjid) |
113 void caps_move_to_local(char *hash, char *bjid) |
114 { |
114 { |
115 char *orig_hash; |
115 char *orig_hash; |
116 caps *c = NULL; |
116 caps_t *c = NULL; |
117 if (!hash || !bjid) |
117 if (!hash || !bjid) |
118 return; |
118 return; |
119 g_hash_table_lookup_extended(caps_cache, hash, (gpointer*)&orig_hash, (gpointer*)&c); |
119 g_hash_table_lookup_extended(caps_cache, hash, (gpointer*)&orig_hash, (gpointer*)&c); |
120 if (c) { |
120 if (c) { |
121 g_hash_table_steal(caps_cache, hash); |
121 g_hash_table_steal(caps_cache, hash); |
128 } |
128 } |
129 |
129 |
130 /*if bjid is NULL, it will check only verified hashes */ |
130 /*if bjid is NULL, it will check only verified hashes */ |
131 int caps_has_hash(const char *hash, const char *bjid) |
131 int caps_has_hash(const char *hash, const char *bjid) |
132 { |
132 { |
133 caps *c = NULL; |
133 caps_t *c = NULL; |
134 if (!hash) |
134 if (!hash) |
135 return 0; |
135 return 0; |
136 c = g_hash_table_lookup(caps_cache, hash); |
136 c = g_hash_table_lookup(caps_cache, hash); |
137 if (!c && bjid) { |
137 if (!c && bjid) { |
138 char *key = g_strdup_printf("%s/#%s", bjid, hash); |
138 char *key = g_strdup_printf("%s/#%s", bjid, hash); |
146 const char *category, |
146 const char *category, |
147 const char *name, |
147 const char *name, |
148 const char *type, |
148 const char *type, |
149 const char *lang) |
149 const char *lang) |
150 { |
150 { |
151 caps *c; |
151 caps_t *c; |
152 if (!hash || !category || !type) |
152 if (!hash || !category || !type) |
153 return; |
153 return; |
154 if (!lang) |
154 if (!lang) |
155 lang = ""; |
155 lang = ""; |
156 |
156 |
157 c = g_hash_table_lookup(caps_cache, hash); |
157 c = g_hash_table_lookup(caps_cache, hash); |
158 if (c) { |
158 if (c) { |
159 identity *i = g_new0(identity, 1); |
159 identity_t *i = g_new0(identity_t, 1); |
160 |
160 |
161 i->category = g_strdup(category); |
161 i->category = g_strdup(category); |
162 i->name = g_strdup(name); |
162 i->name = g_strdup(name); |
163 i->type = g_strdup(type); |
163 i->type = g_strdup(type); |
164 g_hash_table_replace(c->identities, g_strdup(lang), i); |
164 g_hash_table_replace(c->identities, g_strdup(lang), i); |
173 caps_add_identity(hash, category, name, type, NULL); |
173 caps_add_identity(hash, category, name, type, NULL); |
174 } |
174 } |
175 |
175 |
176 void caps_add_dataform(const char *hash, const char *formtype) |
176 void caps_add_dataform(const char *hash, const char *formtype) |
177 { |
177 { |
178 caps *c; |
178 caps_t *c; |
179 if (!formtype) |
179 if (!formtype) |
180 return; |
180 return; |
181 c = g_hash_table_lookup(caps_cache, hash); |
181 c = g_hash_table_lookup(caps_cache, hash); |
182 if (c) { |
182 if (c) { |
183 dataform *d = g_new0(dataform, 1); |
183 dataform_t *d = g_new0(dataform_t, 1); |
184 char *f = g_strdup(formtype); |
184 char *f = g_strdup(formtype); |
185 |
185 |
186 d->fields = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, field_destroy); |
186 d->fields = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, field_destroy); |
187 g_hash_table_replace(c->forms, f, d); |
187 g_hash_table_replace(c->forms, f, d); |
188 } |
188 } |
194 } |
194 } |
195 |
195 |
196 void caps_add_dataform_field(const char *hash, const char *formtype, |
196 void caps_add_dataform_field(const char *hash, const char *formtype, |
197 const char *field, const char *value) |
197 const char *field, const char *value) |
198 { |
198 { |
199 caps *c; |
199 caps_t *c; |
200 if (!formtype || !field || !value) |
200 if (!formtype || !field || !value) |
201 return; |
201 return; |
202 c = g_hash_table_lookup(caps_cache, hash); |
202 c = g_hash_table_lookup(caps_cache, hash); |
203 if (c) { |
203 if (c) { |
204 dataform *d; |
204 dataform_t *d; |
205 d = g_hash_table_lookup(c->forms, formtype); |
205 d = g_hash_table_lookup(c->forms, formtype); |
206 if (d) { |
206 if (d) { |
207 gpointer key, val; |
207 gpointer key, val; |
208 char *f; |
208 char *f; |
209 GList *v = NULL; |
209 GList *v = NULL; |
219 } |
219 } |
220 } |
220 } |
221 |
221 |
222 void caps_add_feature(const char *hash, const char *feature) |
222 void caps_add_feature(const char *hash, const char *feature) |
223 { |
223 { |
224 caps *c; |
224 caps_t *c; |
225 if (!hash || !feature) |
225 if (!hash || !feature) |
226 return; |
226 return; |
227 c = g_hash_table_lookup(caps_cache, hash); |
227 c = g_hash_table_lookup(caps_cache, hash); |
228 if (c) { |
228 if (c) { |
229 char *f = g_strdup(feature); |
229 char *f = g_strdup(feature); |
234 /* If hash is verified, then bare jid is ignored. |
234 /* If hash is verified, then bare jid is ignored. |
235 * If there is no globally verified hash, and bare jid is not null, |
235 * If there is no globally verified hash, and bare jid is not null, |
236 * then local storage for that jid will be checked */ |
236 * then local storage for that jid will be checked */ |
237 int caps_has_feature(const char *hash, char *feature, char *bjid) |
237 int caps_has_feature(const char *hash, char *feature, char *bjid) |
238 { |
238 { |
239 caps *c = NULL; |
239 caps_t *c = NULL; |
240 if (!hash || !feature) |
240 if (!hash || !feature) |
241 return 0; |
241 return 0; |
242 c = g_hash_table_lookup(caps_cache, hash); |
242 c = g_hash_table_lookup(caps_cache, hash); |
243 if (!c && bjid) { |
243 if (!c && bjid) { |
244 char *key = g_strdup_printf("%s/#%s", bjid, hash); |
244 char *key = g_strdup_printf("%s/#%s", bjid, hash); |
258 _foreach_function(value, user_data); |
258 _foreach_function(value, user_data); |
259 } |
259 } |
260 |
260 |
261 void caps_foreach_feature(const char *hash, GFunc func, gpointer user_data) |
261 void caps_foreach_feature(const char *hash, GFunc func, gpointer user_data) |
262 { |
262 { |
263 caps *c; |
263 caps_t *c; |
264 if (!hash) |
264 if (!hash) |
265 return; |
265 return; |
266 c = g_hash_table_lookup(caps_cache, hash); |
266 c = g_hash_table_lookup(caps_cache, hash); |
267 if (!c) |
267 if (!c) |
268 return; |
268 return; |
276 GList *features, *langs; |
276 GList *features, *langs; |
277 GChecksum *sha1; |
277 GChecksum *sha1; |
278 guint8 digest[20]; |
278 guint8 digest[20]; |
279 gsize digest_size = 20; |
279 gsize digest_size = 20; |
280 gchar *hash, *old_hash = NULL; |
280 gchar *hash, *old_hash = NULL; |
281 caps *old_caps, *c; |
281 caps_t *old_caps, *c; |
282 gpointer key; |
282 gpointer key; |
283 |
283 |
284 if (!g_hash_table_lookup_extended(caps_cache, "", &key, (gpointer *)&c)) |
284 if (!g_hash_table_lookup_extended(caps_cache, "", &key, (gpointer *)&c)) |
285 return NULL; |
285 return NULL; |
286 |
286 |
290 sha1 = g_checksum_new(G_CHECKSUM_SHA1); |
290 sha1 = g_checksum_new(G_CHECKSUM_SHA1); |
291 |
291 |
292 langs = g_hash_table_get_keys(c->identities); |
292 langs = g_hash_table_get_keys(c->identities); |
293 langs = g_list_sort(langs, _strcmp_sort); |
293 langs = g_list_sort(langs, _strcmp_sort); |
294 { |
294 { |
295 identity *i; |
295 identity_t *i; |
296 GList *lang; |
296 GList *lang; |
297 char *identity_S; |
297 char *identity_S; |
298 for (lang=langs; lang; lang=lang->next) { |
298 for (lang=langs; lang; lang=lang->next) { |
299 i = g_hash_table_lookup(c->identities, lang->data); |
299 i = g_hash_table_lookup(c->identities, lang->data); |
300 identity_S = g_strdup_printf("%s/%s/%s/%s<", i->category, i->type, |
300 identity_S = g_strdup_printf("%s/%s/%s/%s<", i->category, i->type, |
334 GChecksum *checksum; |
334 GChecksum *checksum; |
335 guint8 digest[20]; |
335 guint8 digest[20]; |
336 gsize digest_size = 20; |
336 gsize digest_size = 20; |
337 gchar *local_hash; |
337 gchar *local_hash; |
338 gboolean match = FALSE; |
338 gboolean match = FALSE; |
339 caps *c = g_hash_table_lookup(caps_cache, hash); |
339 caps_t *c = g_hash_table_lookup(caps_cache, hash); |
340 |
340 |
341 if (!g_strcmp0(function, "sha-1")) { |
341 if (!g_strcmp0(function, "sha-1")) { |
342 checksum = g_checksum_new(G_CHECKSUM_SHA1); |
342 checksum = g_checksum_new(G_CHECKSUM_SHA1); |
343 } else if (!g_strcmp0(function, "md5")) { |
343 } else if (!g_strcmp0(function, "md5")) { |
344 checksum = g_checksum_new(G_CHECKSUM_MD5); |
344 checksum = g_checksum_new(G_CHECKSUM_MD5); |
347 return FALSE; |
347 return FALSE; |
348 |
348 |
349 langs = g_hash_table_get_keys(c->identities); |
349 langs = g_hash_table_get_keys(c->identities); |
350 langs = g_list_sort(langs, _strcmp_sort); |
350 langs = g_list_sort(langs, _strcmp_sort); |
351 { |
351 { |
352 identity *i; |
352 identity_t *i; |
353 GList *lang; |
353 GList *lang; |
354 char *identity_S; |
354 char *identity_S; |
355 for (lang=langs; lang; lang=lang->next) { |
355 for (lang=langs; lang; lang=lang->next) { |
356 i = g_hash_table_lookup(c->identities, lang->data); |
356 i = g_hash_table_lookup(c->identities, lang->data); |
357 identity_S = g_strdup_printf("%s/%s/%s/%s<", i->category, i->type, |
357 identity_S = g_strdup_printf("%s/%s/%s/%s<", i->category, i->type, |
374 g_list_free(features); |
374 g_list_free(features); |
375 |
375 |
376 forms = g_hash_table_get_keys(c->forms); |
376 forms = g_hash_table_get_keys(c->forms); |
377 forms = g_list_sort(forms, _strcmp_sort); |
377 forms = g_list_sort(forms, _strcmp_sort); |
378 { |
378 { |
379 dataform *d; |
379 dataform_t *d; |
380 GList *form, *fields; |
380 GList *form, *fields; |
381 for (form=forms; form; form=form->next) { |
381 for (form=forms; form; form=form->next) { |
382 d = g_hash_table_lookup(c->forms, form->data); |
382 d = g_hash_table_lookup(c->forms, form->data); |
383 g_checksum_update(checksum, form->data, -1); |
383 g_checksum_update(checksum, form->data, -1); |
384 g_checksum_update(checksum, (guchar *)"<", -1); |
384 g_checksum_update(checksum, (guchar *)"<", -1); |
444 void caps_copy_to_persistent(const char* hash, char* xml) |
444 void caps_copy_to_persistent(const char* hash, char* xml) |
445 { |
445 { |
446 gchar *file; |
446 gchar *file; |
447 GList *features, *langs, *forms; |
447 GList *features, *langs, *forms; |
448 GKeyFile *key_file; |
448 GKeyFile *key_file; |
449 caps *c; |
449 caps_t *c; |
450 int fd; |
450 int fd; |
451 |
451 |
452 g_free (xml); |
452 g_free (xml); |
453 |
453 |
454 c = g_hash_table_lookup (caps_cache, hash); |
454 c = g_hash_table_lookup (caps_cache, hash); |
468 "This is autogenerated file. Please do not modify.", |
468 "This is autogenerated file. Please do not modify.", |
469 NULL); |
469 NULL); |
470 |
470 |
471 langs = g_hash_table_get_keys (c->identities); |
471 langs = g_hash_table_get_keys (c->identities); |
472 { |
472 { |
473 identity *i; |
473 identity_t *i; |
474 GList *lang; |
474 GList *lang; |
475 gchar *group; |
475 gchar *group; |
476 for (lang=langs; lang; lang=lang->next) { |
476 for (lang=langs; lang; lang=lang->next) { |
477 i = g_hash_table_lookup (c->identities, lang->data); |
477 i = g_hash_table_lookup (c->identities, lang->data); |
478 group = g_strdup_printf("identity_%s", (gchar *)lang->data); |
478 group = g_strdup_printf("identity_%s", (gchar *)lang->data); |
505 } |
505 } |
506 g_list_free (features); |
506 g_list_free (features); |
507 |
507 |
508 forms = g_hash_table_get_keys(c->forms); |
508 forms = g_hash_table_get_keys(c->forms); |
509 { |
509 { |
510 dataform *d; |
510 dataform_t *d; |
511 GList *form, *fields; |
511 GList *form, *fields; |
512 gchar *group; |
512 gchar *group; |
513 for (form=forms; form; form=form->next) { |
513 for (form=forms; form; form=form->next) { |
514 d = g_hash_table_lookup (c->forms, form->data); |
514 d = g_hash_table_lookup (c->forms, form->data); |
515 group = g_strdup_printf ("form_%s", (gchar *)form->data); |
515 group = g_strdup_printf ("form_%s", (gchar *)form->data); |