mcabber/src/jab_iq.c
changeset 619 44ddf9bec3a5
parent 613 a6b8b373e4de
child 683 c5e0d8c3f00c
equal deleted inserted replaced
618:341568185492 619:44ddf9bec3a5
     2  * jab_iq.c     -- Jabber protocol IQ-related fonctions
     2  * jab_iq.c     -- Jabber protocol IQ-related fonctions
     3  *
     3  *
     4  * Copyright (C) 2005 Mikael Berthe <bmikael@lists.lilotux.net>
     4  * Copyright (C) 2005 Mikael Berthe <bmikael@lists.lilotux.net>
     5  * Some parts initially came from the centericq project:
     5  * Some parts initially came from the centericq project:
     6  * Copyright (C) 2002-2005 by Konstantin Klyagin <konst@konst.org.ua>
     6  * Copyright (C) 2002-2005 by Konstantin Klyagin <konst@konst.org.ua>
       
     7  * Some small parts come from the Gaim project <http://gaim.sourceforge.net/>
     7  *
     8  *
     8  * This program is free software; you can redistribute it and/or modify
     9  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU General Public License as published by
    10  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or (at
    11  * the Free Software Foundation; either version 2 of the License, or (at
    11  * your option) any later version.
    12  * your option) any later version.
    19  * along with this program; if not, write to the Free Software
    20  * along with this program; if not, write to the Free Software
    20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
    21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
    21  * USA
    22  * USA
    22  */
    23  */
    23 
    24 
       
    25 #include <sys/utsname.h>
    24 #include <glib.h>
    26 #include <glib.h>
    25 
    27 
    26 #include "jabglue.h"
    28 #include "jabglue.h"
    27 #include "jab_priv.h"
    29 #include "jab_priv.h"
    28 #include "roster.h"
    30 #include "roster.h"
    29 #include "utils.h"
    31 #include "utils.h"
    30 #include "screen.h"
    32 #include "screen.h"
       
    33 #include "settings.h"
    31 
    34 
    32 int s_id; // XXX
    35 int s_id; // XXX
    33 
    36 
    34 static void request_roster(void)
    37 static void request_roster(void)
    35 {
    38 {
   175     // so we should be there only once.  (That's ugly, however)
   178     // so we should be there only once.  (That's ugly, however)
   176     jb_setstatus(available, NULL, NULL);
   179     jb_setstatus(available, NULL, NULL);
   177   }
   180   }
   178 }
   181 }
   179 
   182 
       
   183 static void handle_iq_version(jconn conn, char *from, const char *id,
       
   184                               xmlnode xmldata)
       
   185 {
       
   186   xmlnode senderquery, x;
       
   187   xmlnode myquery;
       
   188   char *os = NULL;
       
   189 
       
   190   // "from" has already been converted to user locale
       
   191   scr_LogPrint(LPRINT_LOGNORM, "Received an IQ version request from <%s>", from);
       
   192 
       
   193   senderquery = xmlnode_get_tag(xmldata, "query");
       
   194   if (!settings_opt_get_int("iq_version_hide_os")) {
       
   195     struct utsname osinfo;
       
   196     uname(&osinfo);
       
   197     os = g_strdup_printf("%s %s %s", osinfo.sysname, osinfo.release,
       
   198                          osinfo.machine);
       
   199   }
       
   200 
       
   201   x = jutil_iqnew(JPACKET__RESULT, NS_VERSION);
       
   202   xmlnode_put_attrib(x, "id", id);
       
   203   xmlnode_put_attrib(x, "to", xmlnode_get_attrib(xmldata, "from"));
       
   204   myquery = xmlnode_get_tag(x, "query");
       
   205 
       
   206   xmlnode_insert_cdata(xmlnode_insert_tag(myquery, "name"), PACKAGE, -1);
       
   207   xmlnode_insert_cdata(xmlnode_insert_tag(myquery, "version"), VERSION, -1);
       
   208   if (os) {
       
   209     xmlnode_insert_cdata(xmlnode_insert_tag(myquery, "os"), os, -1);
       
   210     g_free(os);
       
   211   }
       
   212 
       
   213   jab_send(jc, x);
       
   214   xmlnode_free(x);
       
   215 }
       
   216 
       
   217 // This function borrows some code from the Gaim project
       
   218 static void handle_iq_time(jconn conn, char *from, const char *id,
       
   219                               xmlnode xmldata)
       
   220 {
       
   221   xmlnode senderquery, x;
       
   222   xmlnode myquery;
       
   223   char *buf, *utf8_buf;
       
   224   time_t now_t;
       
   225   struct tm *now;
       
   226 
       
   227   time(&now_t);
       
   228   now = localtime(&now_t);
       
   229 
       
   230   // "from" has already been converted to user locale
       
   231   scr_LogPrint(LPRINT_LOGNORM, "Received an IQ time request from <%s>", from);
       
   232 
       
   233   buf = g_new0(char, 512);
       
   234   senderquery = xmlnode_get_tag(xmldata, "query");
       
   235 
       
   236   x = jutil_iqnew(JPACKET__RESULT, NS_TIME);
       
   237   xmlnode_put_attrib(x, "id", id);
       
   238   xmlnode_put_attrib(x, "to", xmlnode_get_attrib(xmldata, "from"));
       
   239   myquery = xmlnode_get_tag(x, "query");
       
   240 
       
   241   strftime(buf, 512, "%Y%m%dT%T", now);
       
   242   xmlnode_insert_cdata(xmlnode_insert_tag(myquery, "utc"), buf, -1);
       
   243 
       
   244   strftime(buf, 512, "%Z", now);
       
   245   if ((utf8_buf = to_utf8(buf))) {
       
   246     xmlnode_insert_cdata(xmlnode_insert_tag(myquery, "tz"), utf8_buf, -1);
       
   247     g_free(utf8_buf);
       
   248   }
       
   249 
       
   250   strftime(buf, 512, "%d %b %Y %T", now);
       
   251   if ((utf8_buf = to_utf8(buf))) {
       
   252     xmlnode_insert_cdata(xmlnode_insert_tag(myquery, "display"), utf8_buf, -1);
       
   253     g_free(utf8_buf);
       
   254   }
       
   255 
       
   256   jab_send(jc, x);
       
   257   xmlnode_free(x);
       
   258   g_free(buf);
       
   259 }
       
   260 
       
   261 // This function borrows some code from the Gaim project
   180 static void handle_iq_get(jconn conn, char *from, xmlnode xmldata)
   262 static void handle_iq_get(jconn conn, char *from, xmlnode xmldata)
   181 {
   263 {
   182   char *id;
   264   const char *id, *ns;
   183   xmlnode x, y, z;
   265   xmlnode x, y, z;
       
   266   guint iq_not_implemented = FALSE;
   184 
   267 
   185   id = xmlnode_get_attrib(xmldata, "id");
   268   id = xmlnode_get_attrib(xmldata, "id");
   186   if (!id) {
   269   if (!id) {
   187     scr_LogPrint(LPRINT_LOG, "IQ get stanza with no ID, ignored.");
   270     scr_LogPrint(LPRINT_LOG, "IQ get stanza with no ID, ignored.");
   188     return;
   271     return;
   189   }
   272   }
   190 
   273 
   191   // Nothing implemented yet.
   274   x = xmlnode_get_tag(xmldata, "query");
       
   275   ns = xmlnode_get_attrib(x, "xmlns");
       
   276   if (ns && !strcmp(ns, NS_VERSION)) {
       
   277     handle_iq_version(conn, from, id, xmldata);
       
   278   } else if (ns && !strcmp(ns, NS_TIME)) {
       
   279     handle_iq_time(conn, from, id, xmldata);
       
   280   } else {
       
   281     iq_not_implemented = TRUE;
       
   282   }
       
   283 
       
   284   if (!iq_not_implemented)
       
   285     return;
       
   286 
       
   287   // Not implemented.
   192   x = xmlnode_dup(xmldata);
   288   x = xmlnode_dup(xmldata);
   193   xmlnode_put_attrib(x, "to", xmlnode_get_attrib(xmldata, "from"));
   289   xmlnode_put_attrib(x, "to", xmlnode_get_attrib(xmldata, "from"));
   194   xmlnode_hide_attrib(x, "from");
   290   xmlnode_hide_attrib(x, "from");
   195 
   291 
   196   xmlnode_put_attrib(x, "type", TMSG_ERROR);
   292   xmlnode_put_attrib(x, "type", TMSG_ERROR);
   204   xmlnode_free(x);
   300   xmlnode_free(x);
   205 }
   301 }
   206 
   302 
   207 static void handle_iq_set(jconn conn, char *from, xmlnode xmldata)
   303 static void handle_iq_set(jconn conn, char *from, xmlnode xmldata)
   208 {
   304 {
   209   char *id, *ns;
   305   const char *id, *ns;
   210   xmlnode x, y, z;
   306   xmlnode x, y, z;
   211   guint iq_error = FALSE;
   307   guint iq_not_implemented = FALSE;
   212 
   308 
   213   id = xmlnode_get_attrib(xmldata, "id");
   309   id = xmlnode_get_attrib(xmldata, "id");
   214   if (!id)
   310   if (!id)
   215     scr_LogPrint(LPRINT_LOG, "IQ set stanza with no ID...");
   311     scr_LogPrint(LPRINT_LOG, "IQ set stanza with no ID...");
   216 
   312 
   217   x = xmlnode_get_tag(xmldata, "query");
   313   x = xmlnode_get_tag(xmldata, "query");
   218   ns = xmlnode_get_attrib(x, "xmlns");
   314   ns = xmlnode_get_attrib(x, "xmlns");
   219   if (ns && !strcmp(ns, NS_ROSTER)) {
   315   if (ns && !strcmp(ns, NS_ROSTER)) {
   220     handle_iq_roster(x);
   316     handle_iq_roster(x);
   221   } else {
   317   } else {
   222     iq_error = TRUE;
   318     iq_not_implemented = TRUE;
   223   }
   319   }
   224 
   320 
   225   if (!id) return;
   321   if (!id) return;
   226 
   322 
   227   if (!iq_error) {
   323   if (!iq_not_implemented) {
   228     x = xmlnode_new_tag("iq");
   324     x = xmlnode_new_tag("iq");
   229     xmlnode_put_attrib(x, "to", xmlnode_get_attrib(xmldata, "from"));
   325     xmlnode_put_attrib(x, "to", xmlnode_get_attrib(xmldata, "from"));
   230     xmlnode_put_attrib(x, "type", "result");
   326     xmlnode_put_attrib(x, "type", "result");
   231     xmlnode_put_attrib(x, "id", id);
   327     xmlnode_put_attrib(x, "id", id);
   232   } else {
   328   } else {