soc.2008.xmpp: 9cf6d941: * some code style adjustments in caps.c
tfar at soc.pidgin.im
tfar at soc.pidgin.im
Sun Aug 3 14:10:48 EDT 2008
-----------------------------------------------------------------
Revision: 9cf6d941dfaf222f10ca387fcbaffb5ae64ffc51
Ancestor: e110ccc4a43fd871f68f054c25c4f4420c5114d7
Author: tfar at soc.pidgin.im
Date: 2008-08-01T12:34:33
Branch: im.pidgin.soc.2008.xmpp
URL: http://d.pidgin.im/viewmtn/revision/info/9cf6d941dfaf222f10ca387fcbaffb5ae64ffc51
Modified files:
libpurple/dnssrv.c libpurple/dnssrv.h
libpurple/protocols/jabber/caps.c
libpurple/protocols/jabber/jabber.c
ChangeLog:
* some code style adjustments in caps.c
* some DNS API changes to prepare TXT record resolving support
-------------- next part --------------
============================================================
--- libpurple/dnssrv.c b27bf5a97d652bb86861f274528bba2a355f3384
+++ libpurple/dnssrv.c 66f5ce2fd2d38264183207efe5cf5a0102a1b61a
@@ -33,13 +33,19 @@
#ifndef T_SRV
#define T_SRV 33
#endif
+#ifndef T_TXT
+#define T_TXT 16
+#endif
#else
#include <windns.h>
/* Missing from the mingw headers */
#ifndef DNS_TYPE_SRV
# define DNS_TYPE_SRV 33
#endif
+#ifndef DNS_TYPE_TXT
+# define DNS_TYPE_TXT 16
#endif
+#endif
#include "dnssrv.h"
#include "eventloop.h"
@@ -60,9 +66,11 @@ struct _PurpleSrvQueryData {
#endif
struct _PurpleSrvQueryData {
- PurpleSrvCallback cb;
+ PurpleSrvCallback srv_cb;
+ PurpleTxtCallback txt_cb;
gpointer extradata;
guint handle;
+ int type;
#ifdef _WIN32
GThread *resolver;
char *query;
@@ -74,6 +82,11 @@ struct _PurpleSrvQueryData {
#endif
};
+typedef struct _PurpleSrvInternalQuery {
+ int type;
+ char query[256];
+} PurpleSrvInternalQuery;
+
static gint
responsecompare(gconstpointer ar, gconstpointer br)
{
@@ -99,6 +112,7 @@ resolve(int in, int out)
{
GList *ret = NULL;
PurpleSrvResponse *srvres;
+ PurpleTxtResponse *txtres;
queryans answer;
int size;
int qdcount;
@@ -107,19 +121,19 @@ resolve(int in, int out)
guchar *cp;
gchar name[256];
guint16 type, dlen, pref, weight, port;
- gchar query[256];
+ PurpleSrvInternalQuery query;
#ifdef HAVE_SIGNAL_H
purple_restore_default_signal_handlers();
#endif
- if (read(in, query, 256) <= 0) {
+ if (read(in, &query, sizeof(query)) <= 0) {
close(out);
close(in);
_exit(0);
}
- size = res_query( query, C_IN, T_SRV, (u_char*)&answer, sizeof( answer));
+ size = res_query( query.query, C_IN, query.type, (u_char*)&answer, sizeof( answer));
qdcount = ntohs(answer.hdr.qdcount);
ancount = ntohs(answer.hdr.ancount);
@@ -148,7 +162,7 @@ resolve(int in, int out)
GETSHORT(dlen,cp);
- if (type == T_SRV) {
+ if (query.type == T_SRV) {
GETSHORT(pref,cp);
GETSHORT(weight,cp);
@@ -168,6 +182,14 @@ resolve(int in, int out)
srvres->weight = weight;
ret = g_list_insert_sorted(ret, srvres, responsecompare);
+ } else if (query.type == T_TXT) {
+ size = dn_expand( (unsigned char*)&answer, end, cp, name, 256);
+ if(size < 0 )
+ goto end;
+ txtres = g_new0(PurpleTxtResponse, 1);
+ strcpy(txtres->content, name);
+
+ ret = g_list_append(ret, txtres);
} else {
cp += dlen;
}
@@ -175,10 +197,12 @@ end:
end:
size = g_list_length(ret);
+ write(out, &(query.type), sizeof(query.type));
write(out, &size, sizeof(int));
while (ret != NULL)
{
- write(out, ret->data, sizeof(PurpleSrvResponse));
+ if (query.type == T_SRV) write(out, ret->data, sizeof(PurpleSrvResponse));
+ if (query.type == T_TXT) write(out, ret->data, sizeof(PurpleTxtResponse));
g_free(ret->data);
ret = g_list_remove(ret, ret->data);
}
@@ -193,39 +217,67 @@ resolved(gpointer data, gint source, Pur
resolved(gpointer data, gint source, PurpleInputCondition cond)
{
int size;
+ int type;
PurpleSrvQueryData *query_data = (PurpleSrvQueryData*)data;
- PurpleSrvResponse *res;
- PurpleSrvResponse *tmp;
int i;
- PurpleSrvCallback cb = query_data->cb;
int status;
-
- if (read(source, &size, sizeof(int)) == sizeof(int))
- {
- ssize_t red;
- purple_debug_info("dnssrv","found %d SRV entries\n", size);
- tmp = res = g_new0(PurpleSrvResponse, size);
- for (i = 0; i < size; i++) {
- red = read(source, tmp++, sizeof(PurpleSrvResponse));
- if (red != sizeof(PurpleSrvResponse)) {
- purple_debug_error("dnssrv","unable to read srv "
- "response: %s\n", g_strerror(errno));
+
+ if (read(source, &type, sizeof(type)) == sizeof(type)) {
+ purple_debug_info("dnssrv","type: %d\n", type);
+ if (type == T_SRV) {
+ PurpleSrvResponse *res;
+ PurpleSrvResponse *tmp;
+ PurpleSrvCallback cb = query_data->srv_cb;
+ if (read(source, &size, sizeof(int)) == sizeof(int)) {
+ ssize_t red;
+ purple_debug_info("dnssrv","found %d SRV entries\n", size);
+ tmp = res = g_new0(PurpleSrvResponse, size);
+ for (i = 0; i < size; i++) {
+ red = read(source, tmp++, sizeof(PurpleSrvResponse));
+ if (red != sizeof(PurpleSrvResponse)) {
+ purple_debug_error("dnssrv","unable to read srv "
+ "response: %s\n", g_strerror(errno));
+ size = 0;
+ g_free(res);
+ res = NULL;
+ }
+ }
+ } else {
+ purple_debug_info("dnssrv","found 0 SRV entries; errno is %i\n", errno);
size = 0;
- g_free(res);
res = NULL;
}
+ cb(res, size, query_data->extradata);
+ } else if (type == T_TXT) {
+ PurpleTxtResponse *res;
+ PurpleTxtResponse *tmp;
+ PurpleTxtCallback cb = query_data->txt_cb;
+ if (read(source, &size, sizeof(int)) == sizeof(int)) {
+ ssize_t red;
+ purple_debug_info("dnssrv","found %d TXT entries\n", size);
+ tmp = res = g_new0(PurpleTxtResponse, size);
+ for (i = 0; i < size; i++) {
+ red = read(source, tmp++, sizeof(PurpleTxtResponse));
+ if (red != sizeof(PurpleTxtResponse)) {
+ purple_debug_error("dnssrv","unable to read txt "
+ "response: %s\n", g_strerror(errno));
+ size = 0;
+ g_free(res);
+ res = NULL;
+ }
+ }
+ } else {
+ purple_debug_info("dnssrv","found 0 SRV entries; errno is %i\n", errno);
+ size = 0;
+ res = NULL;
+ }
+ cb(res, size, query_data->extradata);
+ } else {
+ purple_debug_info("dnssrv","type unknown of DNS result entry; errno is %i\n", errno);
}
}
- else
- {
- purple_debug_info("dnssrv","found 0 SRV entries; errno is %i\n", errno);
- size = 0;
- res = NULL;
- }
- cb(res, size, query_data->extradata);
waitpid(query_data->pid, &status, 0);
-
purple_srv_cancel(query_data);
}
@@ -237,34 +289,57 @@ res_main_thread_cb(gpointer data)
res_main_thread_cb(gpointer data)
{
PurpleSrvResponse *srvres = NULL;
+ PurpleTxtResponse *txtres = NULL;
int size = 0;
PurpleSrvQueryData *query_data = data;
-
if(query_data->error_message != NULL)
purple_debug_error("dnssrv", query_data->error_message);
else {
- PurpleSrvResponse *srvres_tmp = NULL;
- GSList *lst = query_data->results;
+ if (query_data->type == T_SRV) {
+ PurpleSrvResponse *srvres_tmp = NULL;
+ GSList *lst = query_data->results;
- size = g_slist_length(lst);
+ size = g_slist_length(lst);
- if(query_data->cb && size > 0)
- srvres_tmp = srvres = g_new0(PurpleSrvResponse, size);
- while (lst) {
- if(query_data->cb)
- memcpy(srvres_tmp++, lst->data, sizeof(PurpleSrvResponse));
- g_free(lst->data);
- lst = g_slist_remove(lst, lst->data);
- }
+ if(query_data->srv_cb && size > 0)
+ srvres_tmp = srvres = g_new0(PurpleSrvResponse, size);
+ while (lst) {
+ if(query_data->cb)
+ memcpy(srvres_tmp++, lst->data, sizeof(PurpleSrvResponse));
+ g_free(lst->data);
+ lst = g_slist_remove(lst, lst->data);
+ }
- query_data->results = NULL;
+ query_data->results = NULL;
- purple_debug_info("dnssrv", "found %d SRV entries\n", size);
- }
+ purple_debug_info("dnssrv", "found %d SRV entries\n", size);
+
+ if(query_data->srv_cb) query_data->srv_cb(srvres, size, query_data->extradata);
+ } else if (query_data->type == T_TXT) {
+ PurpleTxtResponse *txtres_tmp = NULL;
+ GSList *lst = query_data->results;
- if(query_data->cb)
- query_data->cb(srvres, size, query_data->extradata);
+ size = g_slist_length(lst);
+ if(query_data->txt_cb && size > 0)
+ txtres_tmp = txtres = g_new0(PurpleTxtResponse, size);
+ while (lst) {
+ if(query_data->txt_cb)
+ memcpy(txtres_tmp++, lst->data, sizeof(PurpleTxtResponse));
+ g_free(lst->data);
+ lst = g_slist_remove(lst, lst->data);
+ }
+
+ query_data->results = NULL;
+
+ purple_debug_info("dnssrv", "found %d TXT entries\n", size);
+
+ if(query_data->txt_cb) query_data->txt_cb(txtres, size, query_data->extradata);
+ } else {
+ purple_debug_error("dnssrv", "unknown query type");
+ }
+ }
+
query_data->resolver = NULL;
query_data->handle = 0;
@@ -277,40 +352,50 @@ res_thread(gpointer data)
res_thread(gpointer data)
{
PDNS_RECORD dr = NULL;
- int type = DNS_TYPE_SRV;
+ int type;
DNS_STATUS ds;
PurpleSrvQueryData *query_data = data;
-
+ type = query_data->type;
ds = MyDnsQuery_UTF8(query_data->query, type, DNS_QUERY_STANDARD, NULL, &dr, NULL);
if (ds != ERROR_SUCCESS) {
gchar *msg = g_win32_error_message(ds);
- query_data->error_message = g_strdup_printf("Couldn't look up SRV record. %s (%lu).\n", msg, ds);
+ if (type == T_SRV) {
+ query_data->error_message = g_strdup_printf("Couldn't look up SRV record. %s (%lu).\n", msg, ds);
+ } else if (type == T_TXT) {
+ query_data->error_message = g_strdup_printf("Couldn't look up TXT record. %s (%lu).\n", msg, ds);
+ }
g_free(msg);
} else {
- PDNS_RECORD dr_tmp;
- GSList *lst = NULL;
- DNS_SRV_DATA *srv_data;
- PurpleSrvResponse *srvres;
+ if (type == T_SRV) {
+ PDNS_RECORD dr_tmp;
+ GSList *lst = NULL;
+ DNS_SRV_DATA *srv_data;
+ PurpleSrvResponse *srvres;
+
+ for (dr_tmp = dr; dr_tmp != NULL; dr_tmp = dr_tmp->pNext) {
+ /* Discard any incorrect entries. I'm not sure if this is necessary */
+ if (dr_tmp->wType != type || strcmp(dr_tmp->pName, query_data->query) != 0) {
+ continue;
+ }
- for (dr_tmp = dr; dr_tmp != NULL; dr_tmp = dr_tmp->pNext) {
- /* Discard any incorrect entries. I'm not sure if this is necessary */
- if (dr_tmp->wType != type || strcmp(dr_tmp->pName, query_data->query) != 0) {
- continue;
+ srv_data = &dr_tmp->Data.SRV;
+ srvres = g_new0(PurpleSrvResponse, 1);
+ strncpy(srvres->hostname, srv_data->pNameTarget, 255);
+ srvres->hostname[255] = '\0';
+ srvres->pref = srv_data->wPriority;
+ srvres->port = srv_data->wPort;
+ srvres->weight = srv_data->wWeight;
+
+ lst = g_slist_insert_sorted(lst, srvres, responsecompare);
}
- srv_data = &dr_tmp->Data.SRV;
- srvres = g_new0(PurpleSrvResponse, 1);
- strncpy(srvres->hostname, srv_data->pNameTarget, 255);
- srvres->hostname[255] = '\0';
- srvres->pref = srv_data->wPriority;
- srvres->port = srv_data->wPort;
- srvres->weight = srv_data->wWeight;
-
- lst = g_slist_insert_sorted(lst, srvres, responsecompare);
+ MyDnsRecordListFree(dr, DnsFreeRecordList);
+ query_data->results = lst;
+ } else if (type == T_TXT) {
+ #error IMPLEMENTATION MISSING
+ } else {
+
}
-
- MyDnsRecordListFree(dr, DnsFreeRecordList);
- query_data->results = lst;
}
/* back to main thread */
@@ -328,6 +413,7 @@ purple_srv_resolve(const char *protocol,
{
char *query;
PurpleSrvQueryData *query_data;
+ PurpleSrvInternalQuery internal_query;
#ifndef _WIN32
int in[2], out[2];
int pid;
@@ -369,11 +455,16 @@ purple_srv_resolve(const char *protocol,
close(out[1]);
close(in[0]);
- if (write(in[1], query, strlen(query)+1) < 0)
+ internal_query.type = T_SRV;
+ strncpy(internal_query.query, query, 255);
+
+ if (write(in[1], &internal_query, sizeof(internal_query)) < 0)
purple_debug_error("dnssrv", "Could not write to SRV resolver\n");
+
query_data = g_new0(PurpleSrvQueryData, 1);
- query_data->cb = cb;
+ query_data->type = T_SRV;
+ query_data->srv_cb = cb;
query_data->extradata = extradata;
query_data->pid = pid;
query_data->fd_out = out[0];
@@ -392,7 +483,7 @@ purple_srv_resolve(const char *protocol,
}
query_data = g_new0(PurpleSrvQueryData, 1);
- query_data->cb = cb;
+ query_data->srv_cb = cb;
query_data->query = query;
query_data->extradata = extradata;
@@ -416,6 +507,99 @@ purple_srv_resolve(const char *protocol,
#endif
}
+PurpleSrvQueryData *purple_txt_resolve(const char *owner, const char *domain, PurpleTxtCallback cb, gpointer extradata)
+{
+ char *query;
+ PurpleSrvQueryData *query_data;
+#ifndef _WIN32
+ int in[2], out[2];
+ int pid;
+#else
+ GError* err = NULL;
+ static gboolean initialized = FALSE;
+#endif
+
+ query = g_strdup_printf("%s.%s", owner, domain);
+ purple_debug_info("dnssrv","querying TXT record for %s\n", query);
+
+#ifndef _WIN32
+ if(pipe(in) || pipe(out)) {
+ purple_debug_error("dnssrv", "Could not create pipe\n");
+ g_free(query);
+ cb(NULL, 0, extradata);
+ return NULL;
+ }
+
+ pid = fork();
+ if (pid == -1) {
+ purple_debug_error("dnssrv", "Could not create process!\n");
+ cb(NULL, 0, extradata);
+ g_free(query);
+ return NULL;
+ }
+
+ /* Child */
+ if (pid == 0)
+ {
+ g_free(query);
+
+ close(out[0]);
+ close(in[1]);
+ resolve(in[0], out[1]);
+ /* resolve() does not return */
+ }
+
+ close(out[1]);
+ close(in[0]);
+
+ if (write(in[1], query, strlen(query)+1) < 0)
+ purple_debug_error("dnssrv", "Could not write to TXT resolver\n");
+
+ query_data = g_new0(PurpleSrvQueryData, 1);
+ query_data->type = T_TXT;
+ query_data->txt_cb = cb;
+ query_data->extradata = extradata;
+ query_data->pid = pid;
+ query_data->fd_out = out[0];
+ query_data->fd_in = in[1];
+ query_data->handle = purple_input_add(out[0], PURPLE_INPUT_READ, resolved, query_data);
+
+ g_free(query);
+
+ return query_data;
+#else
+ if (!initialized) {
+ MyDnsQuery_UTF8 = (void*) wpurple_find_and_loadproc("dnsapi.dll", "DnsQuery_UTF8");
+ MyDnsRecordListFree = (void*) wpurple_find_and_loadproc(
+ "dnsapi.dll", "DnsRecordListFree");
+ initialized = TRUE;
+ }
+
+ query_data = g_new0(PurpleSrvQueryData, 1);
+ query_data->txt_cb = cb;
+ query_data->query = query;
+ query_data->extradata = extradata;
+
+ if (!MyDnsQuery_UTF8 || !MyDnsRecordListFree)
+ query_data->error_message = g_strdup("System missing DNS API (Requires W2K+)\n");
+ else {
+ query_data->resolver = g_thread_create(res_thread, query_data, FALSE, &err);
+ if (query_data->resolver == NULL) {
+ query_data->error_message = g_strdup_printf("SRV thread create failure: %s\n", (err && err->message) ? err->message : "");
+ g_error_free(err);
+ }
+ }
+
+ /* The query isn't going to happen, so finish the SRV lookup now.
+ * Asynchronously call the callback since stuff may not expect
+ * the callback to be called before this returns */
+ if (query_data->error_message != NULL)
+ query_data->handle = purple_timeout_add(0, res_main_thread_cb, query_data);
+
+ return query_data;
+#endif
+}
+
void
purple_srv_cancel(PurpleSrvQueryData *query_data)
{
@@ -440,3 +624,9 @@ purple_srv_cancel(PurpleSrvQueryData *qu
#endif
g_free(query_data);
}
+
+void
+purple_txt_cancel(PurpleSrvQueryData *query_data)
+{
+ purple_srv_cancel(query_data);
+}
============================================================
--- libpurple/dnssrv.h db1daad5e39d9d283d15c9ea5ac72a457d75d594
+++ libpurple/dnssrv.h 56f31b291960894348165acfcc7731bfe4c24204
@@ -28,8 +28,9 @@ extern "C" {
extern "C" {
#endif
+typedef struct _PurpleSrvQueryData PurpleSrvQueryData;
typedef struct _PurpleSrvResponse PurpleSrvResponse;
-typedef struct _PurpleSrvQueryData PurpleSrvQueryData;
+typedef struct _PurpleTxtResponse PurpleTxtResponse;
struct _PurpleSrvResponse {
char hostname[256];
@@ -38,7 +39,12 @@ struct _PurpleSrvResponse {
int pref;
};
+struct _PurpleTxtResponse {
+ char content[256];
+};
+
typedef void (*PurpleSrvCallback)(PurpleSrvResponse *resp, int results, gpointer data);
+typedef void (*PurpleTxtCallback)(PurpleTxtResponse *resp, int results, gpointer data);
/**
* Queries an SRV record.
@@ -58,6 +64,23 @@ void purple_srv_cancel(PurpleSrvQueryDat
*/
void purple_srv_cancel(PurpleSrvQueryData *query_data);
+/**
+ * Queries an TXT record.
+ *
+ * @param owner Name of the protocol (e.g. "_xmppconnect")
+ * @param domain Domain name to query (e.g. "blubb.com")
+ * @param cb A callback which will be called with the results
+ * @param extradata Extra data to be passed to the callback
+ */
+PurpleSrvQueryData *purple_txt_resolve(const char *owner, const char *domain, PurpleTxtCallback cb, gpointer extradata);
+
+/**
+ * Cancel an TXT DNS query.
+ *
+ * @param query_data The request to cancel.
+ */
+void purple_txt_cancel(PurpleSrvQueryData *query_data);
+
#ifdef __cplusplus
}
#endif
============================================================
--- libpurple/protocols/jabber/caps.c 716500081f1b5e436b8ed4ed09f0da2150e2122c
+++ libpurple/protocols/jabber/caps.c 1134826a8a0ce95c432f253e34f8597264c76532
@@ -198,12 +198,12 @@ static void jabber_caps_store_client(gpo
JabberCapsKey *clientinfo = key;
JabberCapsValue *props = value;
xmlnode *root = user_data;
- xmlnode *client = xmlnode_new_child(root,"client");
+ xmlnode *client = xmlnode_new_child(root, "client");
GList *iter;
- xmlnode_set_attrib(client,"node", clientinfo->node);
- xmlnode_set_attrib(client,"ver", clientinfo->ver);
- xmlnode_set_attrib(client,"hash", clientinfo->hash);
+ xmlnode_set_attrib(client, "node", clientinfo->node);
+ xmlnode_set_attrib(client, "ver", clientinfo->ver);
+ xmlnode_set_attrib(client, "hash", clientinfo->hash);
for(iter = props->identities; iter; iter = g_list_next(iter)) {
JabberCapsIdentity *id = iter->data;
xmlnode *identity = xmlnode_new_child(client, "identity");
============================================================
--- libpurple/protocols/jabber/jabber.c 5fc20633d49f500a587342d9b0d35d660fa8424b
+++ libpurple/protocols/jabber/jabber.c 86c936d715c654d7c1c61889d4754111a7c3ed86
@@ -683,7 +683,7 @@ jabber_login(PurpleAccount *account)
/* no old-ssl, so if they've specified a connect server, we'll use that, otherwise we'll
* invoke the magic of SRV lookups, to figure out host and port */
if(!js->gsc) {
- if(connect_server[0]) {
+ if(connect_server[0]) {
jabber_login_connect(js, js->user->domain, connect_server, purple_account_get_int(account, "port", 5222));
} else {
js->srv_query_data = purple_srv_resolve("xmpp-client",
More information about the Commits
mailing list