Function to detect which jid resource support jingle.
authorNicolas Cornu <nicolas.cornu@ensi-bourges.fr>
Fri, 30 Jul 2010 00:03:48 +0200
changeset 79 a654afc4a74a
parent 78 0b138243bd4a
child 80 1c2ef2c5debe
Function to detect which jid resource support jingle.
jingle-filetransfer/filetransfer.c
jingle/CMakeLists.txt
jingle/disco.c
jingle/disco.h
jingle/jingle.c
jingle/jingle.h
--- a/jingle-filetransfer/filetransfer.c	Tue Jul 27 12:20:29 2010 +0200
+++ b/jingle-filetransfer/filetransfer.c	Fri Jul 30 00:03:48 2010 +0200
@@ -22,6 +22,7 @@
 #include "config.h"
 
 #include <glib.h>
+#include <glib/gstdio.h>
 #include <string.h>
 
 #include <mcabber/modules.h>
@@ -32,6 +33,7 @@
 #include <mcabber/compl.h>
 #include <mcabber/commands.h>
 #include <mcabber/roster.h>
+#include <mcabber/utils.h>
 
 #include <jingle/jingle.h>
 #include <jingle/check.h>
@@ -48,8 +50,6 @@
 static void jingle_ft_init(void);
 static void jingle_ft_uninit(void);
 
-static guint file_cid = 0;
-
 const gchar *deps[] = { "jingle", NULL };
 
 JingleAppFuncs funcs = {
@@ -195,76 +195,71 @@
   return TRUE;
 }
 
-static void do_file(char *arg)
+static void do_sendfile(char *arg)
 {
-  char **args = split_arg(arg, 2, 0);
+  char **args = split_arg(arg, 1, 0);
   
   if (!args[1]) {
     scr_LogPrint(LPRINT_LOGNORM, "Jingle File Transfer: give me a name!");
     return;
   }
   
-  if (!g_file_test (args[1], G_FILE_TEST_IS_REGULAR | G_FILE_TEST_EXISTS)) {
+  if (!g_file_test(args[1], G_FILE_TEST_IS_REGULAR | G_FILE_TEST_EXISTS)) {
     scr_LogPrint(LPRINT_LOGNORM, "File doesn't exist!");
     return;
   }
   
-  if (!g_strcmp0(args[0], "send")) {
-    scr_LogPrint(LPRINT_LOGNORM, "Jingle File Transfer: try to sent %s!",
-                 args[1]);
-    // Create a new session for send a file
-    {
-      JingleSession *sess;
-      GChecksum *md5 = g_checksum_new(G_CHECKSUM_MD5);
-      gchar *sid = new_sid();
-      guchar data[1024];
-      gsize bytes_read;
-      gchar *jid;
-      GSList *el;
-      const gchar *jid = settings_opt_get("jid");
-      JingleFT *jft = g_new0(JingleFT, 1);
-      sess = session_new(sid, jid, jid);
-      session_add_content(sess, "file", JINGLE_SESSION_STATE_PENDING);
-      
-      jft->desc = g_strdup(args[2]);
-      jft->type = JINGLE_FT_OFFER;
-      jft->name = g_path_get_basename(args[1]);
-      jft->date = 0;
-      jft->size = 0;
-      jft->outfile = g_io_channel_new_file (args[1], "r", NULL);
-      g_io_channel_set_encoding(jft->outfile, NULL, NULL);
-      // For the md5 and the size
-      while (g_io_channel_read_chars(jft->outfile,
-                                     (gchar*)data, 1024, &bytes_read, NULL)
-             != G_IO_STATUS_EOF) {
-        jft->size+=bytes_read;
-        g_checksum_update(md5, data, bytes_read);
-      }
-      jft->hash = g_strdup(g_checksum_get_string(md5));
-      g_io_channel_seek_position (jft->outfile, 0, G_SEEK_SET, NULL);
-      session_add_app(sess, "file", NS_JINGLE_APP_FT, jft);
-      
-      jid = CURRENT_JID;
-        
-      el = get_sorted_resources(jid);
-      if (el == NULL)
-        return;
+  scr_LogPrint(LPRINT_LOGNORM, "Jingle File Transfer: try to sent %s",
+               args[1]);
+
+  {
+    /*GChecksum *md5 = g_checksum_new(G_CHECKSUM_MD5);
+    guchar data[1024];
+    gsize bytes_read;*/
+    JingleSession *sess;
+    gchar *sid = jingle_generate_sid();
+    gchar *ressource, *jid;
+    const gchar *namespaces[] = {NS_JINGLE, NS_JINGLE_APP_FT, NULL};
+    struct stat fileinfo;
+    const gchar *myjid = settings_opt_get("jid");
+    JingleFT *jft = g_new0(JingleFT, 1);
+
+    sess = session_new(sid, myjid, myjid);
+    session_add_content(sess, "file", JINGLE_SESSION_STATE_PENDING);
 
-      jid = g_strdup_printf("%s/%s", jid, (gchar*)el->data);
-      jingle_handle_app(sess, "file", NS_JINGLE_APP_FT, jft, jid);
-      
-      free_gslist_resources(el);
-      g_checksum_free(md5);
-      g_free(sid);
-    }  
-  } else if (!g_strcmp0(args[0], "request")) {
-    scr_LogPrint(LPRINT_LOGNORM, "Jingle File Transfer: try to request %s!",
-                 args[1]);
-    //later
+    if (g_stat(args[1], &fileinfo) != 0) {
+      scr_LogPrint(LPRINT_LOGNORM, "Jingle File Transfer: unable to stat %s", args[1]);
+      return;
+    }
+    jft->desc = g_strdup(args[1]);
+    jft->type = JINGLE_FT_OFFER;
+    jft->name = g_path_get_basename(args[1]);
+    jft->date = fileinfo.st_mtime;
+    jft->size = fileinfo.st_size;
+    jft->outfile = g_io_channel_new_file (args[1], "r", NULL);
+    g_io_channel_set_encoding(jft->outfile, NULL, NULL);
+    /*while (g_io_channel_read_chars(jft->outfile,
+                                   (gchar*)data, 1024, &bytes_read, NULL)
+           != G_IO_STATUS_EOF) {
+      jft->size+=bytes_read;
+      g_checksum_update(md5, data, bytes_read);
+    }
+    jft->hash = g_strdup(g_checksum_get_string(md5));
+    g_io_channel_seek_position(jft->outfile, 0, G_SEEK_SET, NULL);*/
+    session_add_app(sess, "file", NS_JINGLE_APP_FT, jft);
+
+    ressource = jingle_find_compatible_res(CURRENT_JID, namespaces);
+    if (ressource == NULL)
+      return;
+
+    jid = g_strdup_printf("%s/%s", CURRENT_JID, ressource);
+    jingle_handle_app(sess, "file", NS_JINGLE_APP_FT, jft, jid);
+
+    g_free(ressource);
+    //g_checksum_free(md5);
+    g_free(sid);
   }
-  
-  
-  
+
   free_arg_lst(args);
 }
 
@@ -301,14 +296,13 @@
 {
   jingle_register_app(NS_JINGLE_APP_FT, &funcs, JINGLE_TRANSPORT_STREAMING);
   xmpp_add_feature(NS_JINGLE_APP_FT);
-  /* Create completions */
-  file_cid = compl_new_category();
+  /*file_cid = compl_new_category();
   if (file_cid) {
-    compl_add_category_word(file_cid, "send");
-    compl_add_category_word(file_cid, "request");
-  }
+    compl_add_category_word(sendfile_cid, "send");
+    compl_add_category_word(send file_cid, "request");
+  }*/
   /* Add command */
-  cmd_add("file", "Send / Request a file", file_cid, 0, do_file, NULL);
+  cmd_add("sendfile", "Send a file", 0, 0, do_sendfile, NULL);
 }
 
 static void jingle_ft_uninit(void)
@@ -316,6 +310,6 @@
   xmpp_del_feature(NS_JINGLE_APP_FT);
   jingle_unregister_app(NS_JINGLE_APP_FT);
   cmd_del("file");
-  if (file_cid)
-    compl_del_category(file_cid);
+  /*if (file_cid)
+    compl_del_category(file_cid);*/
 }
--- a/jingle/CMakeLists.txt	Tue Jul 27 12:20:29 2010 +0200
+++ b/jingle/CMakeLists.txt	Fri Jul 30 00:03:48 2010 +0200
@@ -1,4 +1,4 @@
-add_library(jingle MODULE disco.c disco.h jingle.c jingle.h check.c check.h action-handlers.c action-handlers.c register.c register.h sessions.c sessions.h send.c send.h)
+add_library(jingle MODULE jingle.c jingle.h check.c check.h action-handlers.c action-handlers.c register.c register.h sessions.c sessions.h send.c send.h)
 set_target_properties(jingle PROPERTIES COMPILE_FLAGS "-O0 -g")
 include_directories(${LM_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR})
 target_link_libraries(jingle ${LM_LIBRARIES})
--- a/jingle/disco.c	Tue Jul 27 12:20:29 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-st/*
- * disco.c
- *
- * Copyrigth (C) 2010 Nicolas Cornu <nicolas.cornu@ensi-bourges.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#include "config.h"
- 
-#include <glib.h>
-#include <loudmouth/loudmouth.h>
-
-#include <mcabber/roster.h>
-
-static gint compare_resources(gconstpointer a, gconstpointer b)
-{
-  return buddy_getresourceprio(a)-buddy_getresourceprio(b);
-}
-
-GSList* get_sorted_resources(const gchar *jid)
-{
-  roster *rs;
-  
-  GSList *reslist = buddy_search_jid(jid);
-  
-  if (reslist == NULL)
-    return NULL;
-  
-  rs = (roster*)reslist->data;
-
-  reslist = buddy_getresources(rs);
-  
-  reslist = g_slist_sort(reslist, compare_resources);
-  
-  return reslist;
-}
-
-void free_gslist_resources(GSList *reslist)
-{
-  GSList *el;
-  roster *rs;
-  
-  for (el=reslist; el; el=el->next) {
-    rs=(roster*)el->data;
-    free_roster_user_data(rs);
-  }
-  g_slist_free(reslist);
-}
-
-
--- a/jingle/disco.h	Tue Jul 27 12:20:29 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-#ifndef __JINGLE_CHECK_H__
-#define __JINGLE_CHECK_H__ 1
-
-#include <glib.h>
-#include <loudmouth/loudmouth.h>
-
-#include <jingle/jingle.h>
-
-GSList* get_sorted_resources(const gchar *jid);
-void free_gslist_resources(GSList *reslist);
-#endif
--- a/jingle/jingle.c	Tue Jul 27 12:20:29 2010 +0200
+++ b/jingle/jingle.c	Fri Jul 30 00:03:48 2010 +0200
@@ -274,6 +274,36 @@
 }
 
 /**
+ * Find the best resource to initiate a jingle session.
+ * Test every ressource for a given jid and return the one
+ * who support all namespaces in ns.
+ */
+gchar *jingle_find_compatible_res(const gchar *jid, const gchar *ns[])
+{
+  gchar *choosenres;
+  guint indexns;
+  gboolean found;
+  GList *roster_usr;
+  GSList *reslist, *thisres;
+
+  roster_usr = buddy_search_jid(jid);
+  reslist = buddy_getresources(roster_usr->data);
+  for (thisres = reslist; thisres; thisres = g_slist_next(thisres)) {
+    found = TRUE;
+    for (indexns = 0; ns[indexns]; indexns++) {
+	  if (!caps_has_feature(buddy_resource_getcaps(roster_usr->data, thisres->data), ns[indexns]))
+	    found = FALSE;
+	}
+	if (!found) continue;
+
+    choosenres = g_strdup(thisres->data);
+    g_slist_foreach(reslist, (GFunc)g_free, NULL);
+    g_slist_free(reslist);
+    return choosenres;
+  }
+}
+
+/**
  * Find the jingle_action corresponding to a string
  */
 JingleAction jingle_action_from_str(const gchar *string)
@@ -476,7 +506,7 @@
   sc->appfuncs->handle_data(sc->description, data2, len);
 }
 
-gchar *new_sid(void)
+gchar *jingle_generate_sid(void)
 {
   gchar *sid;
   gchar car[] = "azertyuiopqsdfghjklmwxcvbn1234567890AZERTYUIOPQSDFGHJKLMWXCVBN";
--- a/jingle/jingle.h	Tue Jul 27 12:20:29 2010 +0200
+++ b/jingle/jingle.h	Fri Jul 30 00:03:48 2010 +0200
@@ -126,6 +126,8 @@
 void jingle_send_iq_error(LmMessage *m, const gchar *errtype,
                           const gchar *cond, const gchar *jinglecond);
 
+gchar *jingle_find_compatible_res(const gchar *jid, const gchar *ns[]);
+
 void jingle_ack_iq(LmMessage *m);
 
 LmMessage *lm_message_from_jinglenode(const JingleNode *jn, const gchar *to);
@@ -138,6 +140,6 @@
                             
 void handle_trans_data(const gchar *xmlns, gconstpointer data, const gchar *data2, guint len);
 
-gchar *new_sid(void);
+gchar *jingle_generate_sid(void);
 
 #endif