--- a/mcabber/src/commands.c Tue Nov 07 22:21:39 2006 +0100
+++ b/mcabber/src/commands.c Tue Nov 07 22:43:17 2006 +0100
@@ -212,6 +212,7 @@
// Request (query) category
compl_add_category_word(COMPL_REQUEST, "time");
+ compl_add_category_word(COMPL_REQUEST, "vcard");
compl_add_category_word(COMPL_REQUEST, "version");
// Events category
@@ -2217,6 +2218,8 @@
numtype = iqreq_version;
else if (!strcasecmp(type, "time"))
numtype = iqreq_time;
+ else if (!strcasecmp(type, "vcard"))
+ numtype = iqreq_vcard;
else if (!strcasecmp(type, "show_list")) {
// Undocumented command, for debugging purposes only
jb_iqs_display_list();
@@ -2260,6 +2263,7 @@
switch (numtype) {
case iqreq_version:
case iqreq_time:
+ case iqreq_vcard:
jb_request(jid, numtype);
break;
default:
--- a/mcabber/src/jab_iq.c Tue Nov 07 22:21:39 2006 +0100
+++ b/mcabber/src/jab_iq.c Tue Nov 07 22:43:17 2006 +0100
@@ -355,6 +355,132 @@
jab_send(jc, iqn->xmldata);
}
+static void handle_vcard_node(const char *barejid, xmlnode vcardnode)
+{
+ xmlnode x;
+ const char *p;
+ char *buf;
+
+ x = xmlnode_get_firstchild(vcardnode);
+ for ( ; x; x = xmlnode_get_nextsibling(x)) {
+ const char *title, *data;
+ p = xmlnode_get_name(x);
+ data = xmlnode_get_data(x);
+ if (p && data) {
+ title = NULL;
+ if (!strcmp(p, "FN"))
+ title = "Name";
+ else if (!strcmp(p, "NICKNAME"))
+ title = "Nickname";
+ else if (!strcmp(p, "URL"))
+ title = "URL";
+ else if (!strcmp(p, "BDAY"))
+ title = "Birthday";
+ else if (!strcmp(p, "TZ"))
+ title = "Timezone";
+ else if (!strcmp(p, "TITLE"))
+ title = "Title";
+ else if (!strcmp(p, "ROLE"))
+ title = "Role";
+ else if (!strcmp(p, "DESC"))
+ title = "Comment";
+ else if (!strcmp(p, "N")) {
+ data = xmlnode_get_tag_data(x, "FAMILY");
+ if (data) {
+ buf = g_strdup_printf("Family Name: %s", data);
+ scr_WriteIncomingMessage(barejid, buf, 0, HBB_PREFIX_NONE);
+ g_free(buf);
+ }
+ data = xmlnode_get_tag_data(x, "GIVEN");
+ if (data) {
+ buf = g_strdup_printf("Given Name: %s", data);
+ scr_WriteIncomingMessage(barejid, buf, 0, HBB_PREFIX_NONE);
+ g_free(buf);
+ }
+ data = xmlnode_get_tag_data(x, "MIDDLE");
+ if (data) {
+ buf = g_strdup_printf("Middle Name: %s", data);
+ scr_WriteIncomingMessage(barejid, buf, 0, HBB_PREFIX_NONE);
+ g_free(buf);
+ }
+ } else if (!strcmp(p, "ADR")) { // TODO
+ } else if (!strcmp(p, "TEL")) { // TODO
+ } else if (!strcmp(p, "EMAIL")) {
+ data = xmlnode_get_tag_data(x, "USERID");
+ if (data)
+ title = "Email"; // XXX
+ } else if (!strcmp(p, "ORG")) { // TODO
+ }
+
+ if (title) {
+ buf = g_strdup_printf("%s: %s", title, data);
+ scr_WriteIncomingMessage(barejid, buf, 0, HBB_PREFIX_NONE);
+ g_free(buf);
+ }
+ }
+ }
+}
+
+static void iqscallback_vcard(eviqs *iqp, xmlnode xml_result, guint iqcontext)
+{
+ xmlnode ansqry;
+ char *p;
+ char *bjid;
+ char *buf;
+
+ // Leave now if we cannot process xml_result
+ if (!xml_result || iqcontext) return;
+
+ // Display IQ result sender...
+ p = xmlnode_get_attrib(xml_result, "from");
+ if (!p) {
+ scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:vCard result (no sender name).");
+ return;
+ }
+ bjid = p;
+
+ buf = g_strdup_printf("Received IQ:vCard result from <%s>", bjid);
+ scr_LogPrint(LPRINT_LOGNORM, "%s", buf);
+
+ // Get the vCard node
+ ansqry = xmlnode_get_tag(xml_result, "vCard");
+ if (!ansqry) {
+ scr_LogPrint(LPRINT_LOGNORM, "Empty IQ:vCard result!");
+ return;
+ }
+
+ // bjid should really be the "bare JID", let's strip the resource
+ p = strchr(bjid, JID_RESOURCE_SEPARATOR);
+ if (p) *p = '\0';
+
+ scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO);
+ g_free(buf);
+
+ // Get result data...
+ handle_vcard_node(bjid, ansqry);
+}
+
+void request_vcard(const char *jid)
+{
+ eviqs *iqn;
+ char *barejid;
+
+ barejid = jidtodisp(jid);
+
+ // Create a new IQ structure. We use NULL for the namespace because
+ // we'll have to use a special tag, not the usual "query" one.
+ iqn = iqs_new(JPACKET__GET, NULL, "vcard", IQS_DEFAULT_TIMEOUT);
+ xmlnode_put_attrib(iqn->xmldata, "to", barejid);
+ // Remove the useless <query/> tag, and insert a vCard one.
+ xmlnode_hide(xmlnode_get_tag(iqn->xmldata, "query"));
+ xmlnode_put_attrib(xmlnode_insert_tag(iqn->xmldata, "vCard"),
+ "xmlns", NS_VCARD);
+ iqn->callback = &iqscallback_vcard;
+ jab_send(jc, iqn->xmldata);
+
+ g_free(barejid);
+}
+
void iqscallback_auth(eviqs *iqp, xmlnode xml_result)
{
if (jstate == STATE_GETAUTH) {
@@ -392,19 +518,6 @@
if (!iqs_callback(id, xmldata, IQS_CONTEXT_RESULT))
return;
- /*
- if (!strcmp(id, "VCARDreq")) {
- x = xmlnode_get_firstchild(xmldata);
- if (!x) x = xmldata;
-
- scr_LogPrint(LPRINT_LOGNORM, "Got VCARD"); // TODO
- return;
- } else if (!strcmp(id, "versionreq")) {
- scr_LogPrint(LPRINT_LOGNORM, "Got version"); // TODO
- return;
- }
- */
-
x = xmlnode_get_tag(xmldata, "query");
if (!x) return;
--- a/mcabber/src/jab_priv.h Tue Nov 07 22:21:39 2006 +0100
+++ b/mcabber/src/jab_priv.h Tue Nov 07 22:43:17 2006 +0100
@@ -43,6 +43,7 @@
void iqscallback_auth(eviqs *iqp, xmlnode xml_result);
void request_version(const char *fulljid);
void request_time(const char *fulljid);
+void request_vcard(const char *barejid);
#endif /* __JAB_PRIV_H__ */
--- a/mcabber/src/jabglue.c Tue Nov 07 22:21:39 2006 +0100
+++ b/mcabber/src/jabglue.c Tue Nov 07 22:43:17 2006 +0100
@@ -925,9 +925,20 @@
} else if (reqtype == iqreq_time) {
request_fn = &request_time;
strreqtype = "time";
+ } else if (reqtype == iqreq_vcard) {
+ // Special case
} else
return;
+ // vCard request
+ if (reqtype == iqreq_vcard) {
+ char *bjid = jidtodisp(jid);
+ request_vcard(bjid);
+ scr_LogPrint(LPRINT_NORMAL, "Sent vCard request to <%s>", bjid);
+ g_free(bjid);
+ return;
+ }
+
if (strchr(jid, JID_RESOURCE_SEPARATOR)) {
// This is a full JID
(*request_fn)(jid);
--- a/mcabber/src/jabglue.h Tue Nov 07 22:21:39 2006 +0100
+++ b/mcabber/src/jabglue.h Tue Nov 07 22:43:17 2006 +0100
@@ -29,7 +29,8 @@
enum iqreq_type {
iqreq_none,
iqreq_version,
- iqreq_time
+ iqreq_time,
+ iqreq_vcard
};
char *compose_jid(const char *username, const char *servername,