Mercurial > pidgin.yaz
comparison libpurple/protocols/jabber/caps.c @ 25575:26eabe8e739b
Removing short-names for features and calculating own caps hash.
author | Tobias Markmann <tfar@soc.pidgin.im> |
---|---|
date | Mon, 16 Jun 2008 13:52:45 +0000 |
parents | 6f4ffdc65230 |
children | 2a6a37c7970b |
comparison
equal
deleted
inserted
replaced
23353:adda955a8db6 | 25575:26eabe8e739b |
---|---|
19 * | 19 * |
20 */ | 20 */ |
21 | 21 |
22 #include "internal.h" | 22 #include "internal.h" |
23 | 23 |
24 #include <glib.h> | |
24 #include "caps.h" | 25 #include "caps.h" |
26 #include "cipher.h" | |
25 #include <string.h> | 27 #include <string.h> |
26 #include "internal.h" | 28 #include "internal.h" |
27 #include "util.h" | 29 #include "util.h" |
28 #include "iq.h" | 30 #include "iq.h" |
29 | 31 |
30 #define JABBER_CAPS_FILENAME "xmpp-caps.xml" | 32 #define JABBER_CAPS_FILENAME "xmpp-caps.xml" |
31 | 33 |
32 static GHashTable *capstable = NULL; /* JabberCapsKey -> JabberCapsValue */ | 34 static GHashTable *capstable = NULL; /* JabberCapsKey -> JabberCapsValue */ |
35 static gchar *caps_hash = NULL; | |
33 | 36 |
34 typedef struct _JabberCapsKey { | 37 typedef struct _JabberCapsKey { |
35 char *node; | 38 char *node; |
36 char *ver; | 39 char *ver; |
37 } JabberCapsKey; | 40 } JabberCapsKey; |
109 static void jabber_caps_load(void); | 112 static void jabber_caps_load(void); |
110 | 113 |
111 void jabber_caps_init(void) { | 114 void jabber_caps_init(void) { |
112 capstable = g_hash_table_new_full(jabber_caps_hash, jabber_caps_compare, jabber_caps_destroy_key, jabber_caps_destroy_value); | 115 capstable = g_hash_table_new_full(jabber_caps_hash, jabber_caps_compare, jabber_caps_destroy_key, jabber_caps_destroy_value); |
113 jabber_caps_load(); | 116 jabber_caps_load(); |
117 jabber_caps_calculate_hash(); | |
114 } | 118 } |
115 | 119 |
116 static void jabber_caps_load(void) { | 120 static void jabber_caps_load(void) { |
117 xmlnode *capsdata = purple_util_read_xml_from_file(JABBER_CAPS_FILENAME, "XMPP capabilities cache"); | 121 xmlnode *capsdata = purple_util_read_xml_from_file(JABBER_CAPS_FILENAME, "XMPP capabilities cache"); |
118 xmlnode *client; | 122 xmlnode *client; |
497 } | 501 } |
498 | 502 |
499 void jabber_caps_get_info(JabberStream *js, const char *who, const char *node, const char *ver, const char *ext, jabber_caps_get_info_cb cb, gpointer user_data) { | 503 void jabber_caps_get_info(JabberStream *js, const char *who, const char *node, const char *ver, const char *ext, jabber_caps_get_info_cb cb, gpointer user_data) { |
500 JabberCapsValue *client; | 504 JabberCapsValue *client; |
501 JabberCapsKey *key = g_new0(JabberCapsKey, 1); | 505 JabberCapsKey *key = g_new0(JabberCapsKey, 1); |
502 char *originalext = g_strdup(ext); | |
503 jabber_caps_cbplususerdata *userdata = g_new0(jabber_caps_cbplususerdata, 1); | 506 jabber_caps_cbplususerdata *userdata = g_new0(jabber_caps_cbplususerdata, 1); |
504 userdata->cb = cb; | 507 userdata->cb = cb; |
505 userdata->user_data = user_data; | 508 userdata->user_data = user_data; |
506 userdata->who = g_strdup(who); | 509 userdata->who = g_strdup(who); |
507 userdata->node = g_strdup(node); | 510 userdata->node = g_strdup(node); |
508 userdata->ver = g_strdup(ver); | 511 userdata->ver = g_strdup(ver); |
509 | |
510 if(originalext) { | |
511 int i; | |
512 gchar **splat = g_strsplit(originalext, " ", 0); | |
513 for(i =0; splat[i]; i++) { | |
514 userdata->ext = g_list_append(userdata->ext, splat[i]); | |
515 ++userdata->extOutstanding; | |
516 } | |
517 g_free(splat); | |
518 } | |
519 g_free(originalext); | |
520 | 512 |
521 key->node = (char *)node; | 513 key->node = (char *)node; |
522 key->ver = (char *)ver; | 514 key->ver = (char *)ver; |
523 | 515 |
524 client = g_hash_table_lookup(capstable, key); | 516 client = g_hash_table_lookup(capstable, key); |
568 /* maybe we have all data available anyways? This is the ideal case where no network traffic is necessary */ | 560 /* maybe we have all data available anyways? This is the ideal case where no network traffic is necessary */ |
569 jabber_caps_get_info_check_completion(userdata); | 561 jabber_caps_get_info_check_completion(userdata); |
570 } | 562 } |
571 } | 563 } |
572 | 564 |
565 static gint jabber_caps_jabber_identity_compare(gconstpointer a, gconstpointer b) { | |
566 const JabberIdentity *ac; | |
567 const JabberIdentity *bc; | |
568 gint cat_cmp; | |
569 | |
570 ac = a; | |
571 bc = b; | |
572 | |
573 if ((cat_cmp = strcmp(ac->category, bc->category)) == 0) { | |
574 return strcmp(ac->type, bc->type); | |
575 } else { | |
576 return cat_cmp; | |
577 } | |
578 } | |
579 | |
580 static gint jabber_caps_jabber_feature_compare(gconstpointer a, gconstpointer b) { | |
581 const JabberFeature *ac; | |
582 const JabberFeature *bc; | |
583 | |
584 ac = a; | |
585 bc = b; | |
586 | |
587 return strcmp(ac->namespace, bc->namespace); | |
588 } | |
589 | |
590 | |
591 void jabber_caps_calculate_hash() { | |
592 gchar *verification = 0; | |
593 gchar *free_verification; | |
594 gchar *identity_string, *feature_string; | |
595 GList *identities, *features; | |
596 PurpleCipherContext *context; | |
597 guint8 checksum[20]; | |
598 gsize checksum_size = 20; | |
599 | |
600 /* sort identities */ | |
601 jabber_identities = g_list_sort(jabber_identities, jabber_caps_jabber_identity_compare); | |
602 | |
603 /* concat identities to the verification string */ | |
604 for(identities = jabber_identities; identities; identities = identities->next) { | |
605 JabberIdentity *ident = (JabberIdentity*)identities->data; | |
606 identity_string = g_strdup_printf("%s/%s//%s<", ident->category, ident->type, ident->name); | |
607 free_verification = verification; | |
608 if(verification == 0) verification = g_strdup(identity_string); | |
609 else verification = g_strconcat(verification, identity_string, NULL); | |
610 g_free(identity_string); | |
611 if(free_verification) g_free(free_verification); | |
612 } | |
613 | |
614 /* sort features */ | |
615 jabber_features = g_list_sort(jabber_features, jabber_caps_jabber_feature_compare); | |
616 | |
617 /* concat features to the verification string */ | |
618 for(features = jabber_features; features; features = features->next) { | |
619 JabberFeature *feat = (JabberFeature*)features->data; | |
620 feature_string = g_strdup_printf("%s<", feat->namespace); | |
621 free_verification = verification; | |
622 if(verification == 0) g_strdup(feature_string); | |
623 else verification = g_strconcat(verification, feature_string, NULL); | |
624 g_free(feature_string); | |
625 if(free_verification) g_free(free_verification); | |
626 } | |
627 printf("\n%s", verification); | |
628 | |
629 | |
630 /* generate SHA-1 hash */ | |
631 context = purple_cipher_context_new_by_name("sha1", NULL); | |
632 if (context == NULL) { | |
633 purple_debug_error("jabber", "Could not find sha1 cipher\n"); | |
634 return; | |
635 } | |
636 purple_cipher_context_append(context, verification, strlen(verification)); | |
637 | |
638 if (!purple_cipher_context_digest(context, strlen(verification), checksum, &checksum_size)) { | |
639 purple_debug_error("util", "Failed to get SHA-1 digest.\n"); | |
640 } | |
641 purple_cipher_context_destroy(context); | |
642 | |
643 /* apply Base64 on hash */ | |
644 | |
645 g_free(verification); | |
646 verification = purple_base64_encode(checksum, checksum_size); // for 2.0 compability | |
647 printf("\n%s", verification); | |
648 | |
649 if (caps_hash != 0) g_free(caps_hash); | |
650 caps_hash = verification; | |
651 } | |
652 | |
653 const gchar* jabber_caps_get_hash() { | |
654 return caps_hash; | |
655 } | |
656 |