#include #include #include #include #include #include #include #include #include #include #include "XMPPThread/internal.h" /* Generates a SHA-256 hash of the ver field. */ char * XMPPGenerateVer(void) { char *S = NULL; unsigned char *Sha = NULL; Array *identities = ArrayCreate(); Array *features = ArrayCreate(); size_t i; /* Initialise identity table, to be sorted */ #define IdentitySimple(cat, Type, Name) { \ XMPPIdentity *id = Malloc(sizeof(*id)); \ id->category = cat; \ id->lang = NULL; \ id->type = Type; \ id->name = Name; \ ArrayAdd(identities, id); } IQ_IDENTITY #undef IdentitySimple #define AdvertiseSimple(feature) ArrayAdd(features, feature); IQ_ADVERT #undef AdvertiseSimple ArraySort(identities, IdentitySort); for (i = 0; i < ArraySize(identities); i++) { XMPPIdentity *identity = ArrayGet(identities, i); char *id_chunk = StrConcat(7, identity->category, "/", identity->type, "/", identity->lang, "/", identity->name); char *tmp = S; S = StrConcat(3, S, id_chunk, "<"); Free(tmp); Free(id_chunk); } ArraySort(features, ((int (*) (void *, void *)) ICollate)); for (i = 0; i < ArraySize(features); i++) { char *feature = ArrayGet(features, i); char *tmp = S; S = StrConcat(3, S, feature, "<"); Free(tmp); } Sha = Sha1(S); Free(S); S = Base64Encode((const char *) Sha, 20); Free(Sha); ArrayFree(features); for (i = 0; i < ArraySize(identities); i++) { XMPPIdentity *identity = ArrayGet(identities, i); /* We don't have to do anything here. */ Free(identity); } ArrayFree(identities); return S; }