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