aboutsummaryrefslogtreecommitdiffstats
path: root/protocols/jabber/iq.c
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/jabber/iq.c')
-rw-r--r--protocols/jabber/iq.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/protocols/jabber/iq.c b/protocols/jabber/iq.c
index 33889d32..327cc859 100644
--- a/protocols/jabber/iq.c
+++ b/protocols/jabber/iq.c
@@ -26,6 +26,7 @@
static xt_status jabber_parse_roster(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
static xt_status jabber_iq_display_vcard(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
+static xt_status jabber_gmail_handle_new(struct im_connection *ic, struct xt_node *node);
xt_status jabber_pkt_iq(struct xt_node *node, gpointer data)
{
@@ -140,6 +141,10 @@ xt_status jabber_pkt_iq(struct xt_node *node, gpointer data)
(s = xt_find_attr(c, "xmlns")) &&
(strcmp(s, XMLNS_SI) == 0)) {
return jabber_si_handle_request(ic, node, c);
+ } else if ((c = xt_find_node(node->children, "new-mail")) &&
+ (s = xt_find_attr(c, "xmlns")) &&
+ (strcmp(s, XMLNS_GMAILNOTIFY) == 0)) {
+ return jabber_gmail_handle_new(ic, node);
} else if (!(c = xt_find_node(node->children, "query")) ||
!(s = xt_find_attr(c, "xmlns"))) {
return XT_HANDLED;
@@ -341,6 +346,9 @@ xt_status jabber_pkt_bind_sess(struct im_connection *ic, struct xt_node *node, s
if (!jabber_write_packet(ic, reply)) {
return XT_ABORT;
}
+ if (jd->flags & JFLAG_GMAILNOTIFY && node == NULL) {
+ jabber_iq_query_server(ic, jd->server, XMLNS_DISCO_INFO);
+ }
} else if ((jd->flags & (JFLAG_WANT_BIND | JFLAG_WANT_SESSION)) == 0) {
if (!jabber_get_roster(ic)) {
return XT_ABORT;
@@ -370,6 +378,25 @@ int jabber_get_roster(struct im_connection *ic)
return st;
}
+xt_status jabber_iq_query_gmail(struct im_connection *ic);
+
+static xt_status jabber_gmail_handle_new(struct im_connection *ic, struct xt_node *node)
+{
+ struct xt_node *response;
+ struct jabber_data *jd = ic->proto_data;
+
+ response = jabber_make_packet("iq", "result", g_strdup_printf("%s@%s", jd->username, jd->server), NULL);
+
+ jabber_cache_add(ic, response, NULL);
+ if (!jabber_write_packet(ic, response)) {
+ return XT_ABORT;
+ }
+
+ jabber_iq_query_gmail(ic);
+
+ return XT_HANDLED;
+}
+
static xt_status jabber_parse_roster(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
{
struct jabber_data *jd = ic->proto_data;
@@ -709,6 +736,34 @@ xt_status jabber_iq_parse_features(struct im_connection *ic, struct xt_node *nod
return XT_HANDLED;
}
+xt_status jabber_iq_parse_gmail(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
+
+xt_status jabber_iq_query_gmail(struct im_connection *ic)
+{
+ struct xt_node *node, *query;
+ struct jabber_data *jd = ic->proto_data;
+
+ node = xt_new_node("query", NULL, NULL);
+ xt_add_attr(node, "xmlns", XMLNS_GMAILNOTIFY);
+ if (jd->gmail_time) {
+ char *formatted = g_strdup_printf("%" G_GUINT64_FORMAT, (jd->gmail_time + 1));
+ xt_add_attr(node, "newer-than-time", formatted);
+ g_free(formatted);
+ }
+ if (jd->gmail_tid) {
+ xt_add_attr(node, "newer-than-tid", jd->gmail_tid);
+ }
+
+ if (!(query = jabber_make_packet("iq", "get", jd->me, node))) {
+ imcb_log(ic, "WARNING: Couldn't generate server query");
+ xt_free_node(node);
+ }
+
+ jabber_cache_add(ic, query, jabber_iq_parse_gmail);
+
+ return jabber_write_packet(ic, query) ? XT_HANDLED : XT_ABORT;
+}
+
xt_status jabber_iq_parse_server_features(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
xt_status jabber_iq_query_server(struct im_connection *ic, char *jid, char *xmlns)
@@ -730,6 +785,63 @@ xt_status jabber_iq_query_server(struct im_connection *ic, char *jid, char *xmln
return jabber_write_packet(ic, query) ? XT_HANDLED : XT_ABORT;
}
+xt_status jabber_iq_parse_gmail(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
+{
+ struct xt_node *c;
+ struct jabber_data *jd = ic->proto_data;
+ char *xmlns, *from;
+ guint64 l_time = 0;
+ char *tid = NULL;
+ int max = 0;
+
+ if (!(c = xt_find_node(node->children, "mailbox")) ||
+ !(from = xt_find_attr(node, "from")) ||
+ !(xmlns = xt_find_attr(c, "xmlns")) ||
+ (g_strcmp0(xmlns, XMLNS_GMAILNOTIFY) != 0)) {
+ imcb_log(ic, "WARNING: Received incomplete mailbox packet for gmail notify");
+ return XT_HANDLED;
+ }
+
+ max = set_getint(&ic->acc->set, "mail_notifications_limit");
+ c = c->children;
+
+ while ((max-- > 0) && (c = xt_find_node(c, "mail-thread-info"))) {
+ struct xt_node *s;
+ char *subject = "<no subject>";
+ char *sender = "<no sender>";
+ guint64 t_time;
+
+ t_time = g_ascii_strtoull(xt_find_attr(c, "date"), NULL, 10);
+ if (t_time && t_time > l_time) {
+ l_time = t_time;
+ tid = xt_find_attr(c, "tid");
+ }
+
+ if ((s = xt_find_node(c->children, "senders")) &&
+ (s = xt_find_node_by_attr(s->children, "sender", "unread", "1"))) {
+ sender = xt_find_attr(s, "name");
+ }
+
+ if ((s = xt_find_node(c->children, "subject")) && s->text) {
+ subject = s->text;
+ }
+
+ imcb_notify_email(ic, "New mail from %s: %s", sender, subject);
+
+ c = c->next;
+ }
+
+ if (l_time && (!jd->gmail_time || l_time > jd->gmail_time)) {
+ jd->gmail_time = l_time;
+ if (tid) {
+ g_free(jd->gmail_tid);
+ jd->gmail_tid = g_strdup(tid);
+ }
+ }
+
+ return XT_HANDLED;
+}
+
/*
* Query the server for "items", query each "item" for identities, query each "item" that's a proxy for it's bytestream info
*/
@@ -780,6 +892,19 @@ xt_status jabber_iq_parse_server_features(struct im_connection *ic, struct xt_no
c = c->next;
}
+
+ if (jd->flags & JFLAG_GMAILNOTIFY) {
+ /* search for gmail notification feature */
+ c = xt_find_node(node->children, "query");
+ c = c->children;
+ while ((c = xt_find_node(c, "feature"))) {
+ if (strcmp(xt_find_attr(c, "var"), XMLNS_GMAILNOTIFY) == 0) {
+ jabber_iq_query_gmail(ic);
+ }
+ c = c->next;
+ }
+ }
+
} else if (strcmp(xmlns, XMLNS_BYTESTREAMS) == 0) {
char *host, *jid, *port_s;
int port;