--- a/jingle-filetransfer/filetransfer.c Mon Aug 16 18:32:55 2010 +0200
+++ b/jingle-filetransfer/filetransfer.c Mon Aug 16 18:33:33 2010 +0200
@@ -59,12 +59,22 @@
static void jingle_ft_uninit(void);
// Return must be free
static gchar *_convert_size(guint64 size);
+static int _next_index(void);
+static void _free(gconstpointer data);
const gchar *deps[] = { "jingle", NULL };
static GSList *info_list = NULL;
static guint jft_cid = 0;
+const gchar* strstate[] = {
+ "PENDING",
+ "STARTING",
+ "ENDING",
+ "REJECT",
+ "ERROR"
+};
+
static JingleAppFuncs funcs = {
.check = check,
.handle = handle,
@@ -122,7 +132,6 @@
ft->name = (gchar *) lm_message_node_get_attribute(node, "name");
sizestr = lm_message_node_get_attribute(node, "size");
ft->transmit = 0;
-
ft->dir = JINGLE_FT_INCOMING;
if (!ft->name || !sizestr) {
@@ -169,6 +178,13 @@
}
ft->hash = g_strndup(ft->hash, 32);
+ {
+ JingleFTInfo *jfti = g_new0(JingleFTInfo, 1);
+ jfti->index = _next_index();
+ jfti->jft = ft;
+ info_list = g_slist_append(info_list, jfti);
+ }
+
return (gconstpointer) ft;
}
@@ -226,6 +242,7 @@
g_error_free(err);
return FALSE;
}
+ jft->state = JINGLE_FT_STARTING;
status = g_io_channel_set_encoding(jft->outfile, NULL, &err);
if (status != G_IO_STATUS_NORMAL || err != NULL) {
scr_LogPrint(LPRINT_LOGNORM, "Jingle File Transfer: %s %s", err->message,
@@ -234,7 +251,9 @@
return FALSE;
}
}
-
+
+ jft->state = JINGLE_FT_STARTING;
+
status = g_io_channel_write_chars(jft->outfile, data, (gssize) len,
&bytes_written, &err);
if (status != G_IO_STATUS_NORMAL || err != NULL) {
@@ -261,7 +280,7 @@
}
-static int _next_index()
+static int _next_index(void)
{
static int a = 0;
return a++;
@@ -296,7 +315,7 @@
}
scr_LogPrint(LPRINT_LOGNORM, "Jingle File Transfer: Trying to send %s",
- args[0]);
+ args[1]);
{
JingleSession *sess;
@@ -330,6 +349,7 @@
jft->date = fileinfo.st_mtime;
jft->size = fileinfo.st_size;
jft->transmit = 0;
+ jft->state = JINGLE_FT_PENDING;
jft->dir = JINGLE_FT_OUTGOING;
jft->outfile = g_io_channel_new_file (filename, "r", &err);
if (jft->outfile == NULL || err != NULL) {
@@ -370,21 +390,52 @@
scr_LogPrint(LPRINT_LOGNORM, "JFT: no file");
for (el = info_list; el; el = el->next) {
- JingleFTInfo* jftio = el->data;
+ JingleFTInfo *jftio = el->data;
gchar *strsize = _convert_size(jftio->jft->size);
- scr_LogPrint(LPRINT_LOGNORM, "[%i]%s %s %s %.2f%%: %s", jftio->index,
+ scr_LogPrint(LPRINT_LOGNORM, "[%i]%s %s %s %.2f%%: %s %s", jftio->index,
(jftio->jft->dir == JINGLE_FT_INCOMING)?"<==":"-->",
jftio->jft->name, strsize,
(gfloat)jftio->jft->transmit/(gfloat)jftio->jft->size * 100,
- jftio->jft->desc);
+ jftio->jft->desc?jftio->jft->desc:"",
+ strstate[jftio->jft->state]);
g_free(strsize);
}
-
+ } else if (!g_strcmp0(args[0], "flush")) {
+ GSList *el, *el2 = NULL;
+ int count = 0;
+ for (el = info_list; el; el = el -> next) {
+ JingleFTInfo *jftio = el->data;
+ if (jftio->jft->state == JINGLE_FT_ERROR ||
+ jftio->jft->state == JINGLE_FT_REJECT ||
+ jftio->jft->state == JINGLE_FT_ENDING) {
+ g_slist_free_1(el2);
+ count++;
+ _free(jftio->jft);
+ info_list = g_slist_remove(info_list, jftio);
+ el2 = el;
+ }
+ }
+ g_slist_free_1(el2);
+ scr_LogPrint(LPRINT_LOGNORM, "JFT: %i files removed", count);
+ } else {
+ scr_LogPrint(LPRINT_LOGNORM, "/jft: %s is not a correct option.", args[1]);
}
free_arg_lst(args);
}
+static void _free(gconstpointer data)
+{
+ JingleFT *jft = (JingleFT *)data;
+ g_free(jft->hash);
+ g_free(jft->name);
+ g_free(jft->desc);
+ g_io_channel_unref(jft->outfile);
+ if (jft->dir == JINGLE_FT_INCOMING)
+ g_checksum_free(jft->md5);
+ g_free(jft);
+}
+
static void tomessage(gconstpointer data, LmMessageNode *node)
{
JingleFT *jft = (JingleFT*) data;
@@ -424,7 +475,7 @@
//if (jft->data != 0)
}
-static void send_hash(gchar *sid, gchar *to, gchar *hash)
+static void send_hash(const gchar *sid, const gchar *to, const gchar *hash)
{
JingleAckHandle *ackhandle;
GError *err = NULL;
@@ -540,7 +591,7 @@
SessionContent *sc2 = session_find_sessioncontent(sess, sc->name);
jft = (JingleFT*)sc2->description;
-
+ jft->state = JINGLE_FT_STARTING;
jft->md5 = g_checksum_new(G_CHECKSUM_MD5);
scr_LogPrint(LPRINT_LOGNORM, "Jingle File Transfer: Transfer start (%s)",
@@ -556,14 +607,14 @@
GError *err = NULL;
GIOStatus status;
+ jft->state = JINGLE_FT_ENDING;
if (jft->outfile != NULL) {
- status = g_io_channel_flush(jft->outfile, &err);
+ status = g_io_channel_shutdown(jft->outfile, TRUE, &err);
if (status != G_IO_STATUS_NORMAL || err != NULL) {
scr_LogPrint(LPRINT_LOGNORM, "Jingle File Transfer: %s",
err->message);
g_error_free(err);
}
- g_io_channel_unref(jft->outfile);
}
if (jft->hash != NULL && jft->md5 != NULL) {
@@ -578,9 +629,6 @@
scr_LogPrint(LPRINT_LOGNORM, "Jingle File Transfer: transfer finished (%s)"
" but not verified", jft->name);
}
-
- g_checksum_free(jft->md5);
-
}
static gchar *_convert_size(guint64 size)
@@ -619,6 +667,7 @@
compl_add_category_word(jft_cid, "send");
//compl_add_category_word(jft_cid, "request");
compl_add_category_word(jft_cid, "info");
+ compl_add_category_word(jft_cid, "flush");
}
/* Add command */
cmd_add("jft", "Manage file transfer", jft_cid, 0, do_sendfile, NULL);
@@ -626,6 +675,7 @@
static void jingle_ft_uninit(void)
{
+ g_slist_free(info_list);
xmpp_del_feature(NS_JINGLE_APP_FT);
jingle_unregister_app(NS_JINGLE_APP_FT);
cmd_del("file");
--- a/jingle-filetransfer/filetransfer.h Mon Aug 16 18:32:55 2010 +0200
+++ b/jingle-filetransfer/filetransfer.h Mon Aug 16 18:33:33 2010 +0200
@@ -15,6 +15,15 @@
JINGLE_FT_INCOMING,
JINGLE_FT_OUTGOING
} JingleFTDirection;
+
+typedef enum {
+ JINGLE_FT_PENDING,
+ JINGLE_FT_STARTING,
+ JINGLE_FT_ENDING,
+ JINGLE_FT_REJECT,
+ JINGLE_FT_ERROR
+} JingleFTState;
+
typedef struct {
/* the last modification of the file, optional */
time_t date;
@@ -40,6 +49,9 @@
/* Is it if the file is incoming or outgoing */
JingleFTDirection dir;
+ /* The state of the file (PENDING, STARTING, ...) */
+ JingleFTState state;
+
/* A little description of the transfer */
gchar *desc;
--- a/jingle-ibb/ibb.c Mon Aug 16 18:32:55 2010 +0200
+++ b/jingle-ibb/ibb.c Mon Aug 16 18:33:33 2010 +0200
@@ -41,16 +41,16 @@
static LmMessageHandler* jingle_ibb_handler = NULL;
static gconstpointer check(JingleContent *cn, GError **err);
-static gboolean cmp(gconstpointer data1, gconstpointer data2);
static void tomessage(gconstpointer data, LmMessageNode *node);
static gconstpointer new(void);
static void send(session_content *sc, gconstpointer data, gchar *buf, gsize size);
static void init(session_content *sc, gconstpointer data);
static void end(session_content *sc, gconstpointer data);
static gchar *info(gconstpointer data);
+
static void _send_internal(session_content *sc, const gchar *to, gchar *buf,
gsize size, const gchar *sid, gint64 *seq);
-
+
static void jingle_ibb_init(void);
static void jingle_ibb_uninit(void);
@@ -63,7 +63,6 @@
static JingleTransportFuncs funcs = {
.check = check,
.tomessage = tomessage,
- .cmp = cmp,
.new = new,
.send = send,
.init = init,
@@ -85,7 +84,6 @@
/* Hash-Table of all emited JingleIBB struct */
static GHashTable *JingleIBBs = NULL;
-
static gconstpointer check(JingleContent *cn, GError **err)
{
JingleIBB *ibb = NULL;
@@ -128,7 +126,7 @@
gpointer user_data)
{
const gchar *data64;
- JingleIBB *jibb = g_new0(JingleIBB, 1);
+ JingleIBB *jibb = g_new0(JingleIBB, 1), *jibb2;
gsize len;
guchar *data;
@@ -144,7 +142,12 @@
if (g_strcmp0(lm_message_node_get_attribute(dnode, "xmlns"),
NS_TRANSPORT_IBB))
- return LM_HANDLER_RESULT_REMOVE_MESSAGE;
+ return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+
+ jibb2 = g_hash_table_lookup(JingleIBBs,
+ lm_message_node_get_attribute(dnode, "sid"));
+ if (jibb2 == NULL)
+ return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
jingle_ack_iq(message);
@@ -154,21 +157,12 @@
data64 = lm_message_node_get_value(dnode);
data = g_base64_decode(data64, &len);
-
- handle_trans_data(NS_JINGLE_TRANSPORT_IBB, jibb, (const gchar *)data, (guint)len);
+
+ handle_trans_data(jibb2, (const gchar *)data, (guint)len);
return LM_HANDLER_RESULT_REMOVE_MESSAGE;
}
-
-static gboolean cmp(gconstpointer data1, gconstpointer data2)
-{
- const JingleIBB *ibb1 = data1, *ibb2 = data2;
- if(g_strcmp0(ibb1->sid, ibb2->sid))
- return FALSE;
- return TRUE;
-}
-
static gchar *new_ibb_sid(void)
{
gchar *sid;
--- a/jingle/action-handlers.c Mon Aug 16 18:32:55 2010 +0200
+++ b/jingle/action-handlers.c Mon Aug 16 18:33:33 2010 +0200
@@ -105,6 +105,7 @@
sess = session_new_from_jinglenode(jn);
for (child = jn->content; child; child = child->next) {
+ SessionContent *sc;
cn = (JingleContent *)(child->data);
xmlns = lm_message_node_get_attribute(cn->description, "xmlns");
@@ -115,15 +116,15 @@
transfuncs = jingle_get_transportfuncs(xmlns);
if (transfuncs == NULL) continue;
- description = appfuncs->check(cn, &err);
- if (description == NULL || err != NULL) continue;
- transport = transfuncs->check(cn, &err);
- if (transport == NULL || err != NULL) continue;
-
- session_add_content_from_jinglecontent(sess, cn,
- JINGLE_SESSION_STATE_PENDING);
+ sc = session_add_content_from_jinglecontent(sess, cn,
+ JINGLE_SESSION_STATE_PENDING,
+ &err);
+ if (err != NULL || sc == NULL) {
+ scr_LogPrint(LPRINT_LOGNORM, "Cannot add a content: %s", err->message);
+ g_error_free(err);
+ }
}
-
+
if(g_slist_length(sess->content) == 0) {
jingle_send_session_terminate(sess, "unsupported-applications");
session_delete(sess);
--- a/jingle/jingle.c Mon Aug 16 18:32:55 2010 +0200
+++ b/jingle/jingle.c Mon Aug 16 18:33:33 2010 +0200
@@ -236,6 +236,7 @@
scr_LogPrint(LPRINT_LOGNORM, "Jingle event from %s cancelled.",
js->from);
jingle_send_session_terminate(js, "decline");
+
}
return FALSE;
@@ -419,9 +420,9 @@
}
}
-void handle_trans_data(const gchar *xmlns, gconstpointer data, const gchar *data2, guint len)
+void handle_trans_data(gconstpointer data, const gchar *data2, guint len)
{
- SessionContent *sc = session_find_transport(xmlns, data);
+ SessionContent *sc = session_find_transport(data);
if (sc == NULL) {
return;
}
--- a/jingle/jingle.h Mon Aug 16 18:32:55 2010 +0200
+++ b/jingle/jingle.h Mon Aug 16 18:33:33 2010 +0200
@@ -163,7 +163,7 @@
gboolean evscallback_jingle(guint evcontext, const gchar *arg,
gpointer userdata);
-void handle_trans_data(const gchar *xmlns, gconstpointer data, const gchar *data2, guint len);
+void handle_trans_data(gconstpointer data, const gchar *data2, guint len);
gchar *jingle_generate_sid(void);
--- a/jingle/register.h Mon Aug 16 18:32:55 2010 +0200
+++ b/jingle/register.h Mon Aug 16 18:33:33 2010 +0200
@@ -45,7 +45,6 @@
typedef gconstpointer (*JingleTransportCheck) (JingleContent *cn, GError **err);
typedef void (*JingleTransportToMessage) (gconstpointer data, LmMessageNode *node);
-typedef gboolean (*JingleTransportCmp) (gconstpointer data1, gconstpointer data2);
typedef gconstpointer (*JingleTransportNew) (void);
typedef void (*JingleTransportSend) (session_content *sc, gconstpointer data, gchar *buf, gsize size);
typedef void (*JingleTransportInit) (session_content *sc, gconstpointer data);
@@ -81,8 +80,6 @@
JingleTransportToMessage tomessage;
- JingleTransportCmp cmp;
-
JingleTransportNew new;
JingleTransportSend send;
--- a/jingle/sessions.c Mon Aug 16 18:32:55 2010 +0200
+++ b/jingle/sessions.c Mon Aug 16 18:33:33 2010 +0200
@@ -85,8 +85,8 @@
return session_find_by_sid(jn->sid, from);
}
-void session_add_content(JingleSession *sess, const gchar *name,
- SessionState state)
+SessionContent* session_add_content(JingleSession *sess, const gchar *name,
+ SessionState state)
{
SessionContent *sc = g_new0(SessionContent, 1);
@@ -94,6 +94,8 @@
sc->state = state;
sess->content = g_slist_append(sess->content, sc);
+
+ return sc;
}
void session_add_app(JingleSession *sess, const gchar *name,
@@ -116,22 +118,48 @@
sc->transport = data;
}
-void session_add_content_from_jinglecontent(JingleSession *sess,
+SessionContent* session_add_content_from_jinglecontent(JingleSession *sess,
JingleContent *cn,
- SessionState state)
+ SessionState state,
+ GError **err)
{
const gchar *xmlns;
- JingleAppFuncs *app_funcs;
- JingleTransportFuncs *trans_funcs;
- session_add_content(sess, cn->name, state);
+ JingleAppFuncs *appfuncs;
+ JingleTransportFuncs *transfuncs;
+ GError *error = NULL;
+ SessionContent *sc;
+ gconstpointer data;
+
+ sc = session_add_content(sess, cn->name, state);
- xmlns = lm_message_node_get_attribute(cn->description, "xmlns");
- app_funcs = jingle_get_appfuncs(xmlns);
- session_add_app(sess, cn->name, xmlns, app_funcs->check(cn, NULL));
+ // Check and add the application
+ {
+ xmlns = lm_message_node_get_attribute(cn->description, "xmlns");
+ appfuncs = jingle_get_appfuncs(xmlns);
+ data = appfuncs->check(cn, &error);
+ if (data == NULL || error != NULL) {
+ g_propagate_error(err, error);
+ sess->content = g_slist_remove(sess->content, sc);
+ return NULL;
+ }
+ session_add_app(sess, cn->name, xmlns, data);
+ }
- xmlns = lm_message_node_get_attribute(cn->transport, "xmlns");
- trans_funcs = jingle_get_transportfuncs(xmlns);
- session_add_trans(sess, cn->name, xmlns, trans_funcs->check(cn, NULL));
+ // Check and add the transport
+ {
+ xmlns = lm_message_node_get_attribute(cn->transport, "xmlns");
+ transfuncs = jingle_get_transportfuncs(xmlns);
+ data = transfuncs->check(cn, &error);
+ if (data == NULL || error != NULL) {
+ g_propagate_error(err, error);
+ g_free(sc->xmlns_desc);
+ sess->content = g_slist_remove(sess->content, sc);
+ return NULL;
+ }
+ session_add_trans(sess, cn->name, xmlns, data);
+ }
+
+ return sc;
}
SessionContent *session_find_sessioncontent(JingleSession *sess,
@@ -147,7 +175,7 @@
return NULL;
}
-SessionContent *session_find_transport(const gchar *xmlns_trans, gconstpointer data)
+SessionContent *session_find_transport(gconstpointer data)
{
GSList *el, *el1;
JingleSession *sess;
@@ -156,7 +184,7 @@
sess = (JingleSession*) el1->data;
for (el = sess->content; el; el = el->next) {
sc = (SessionContent*) el->data;
- if (!g_strcmp0(sc->xmlns_trans, xmlns_trans) && sc->transfuncs->cmp(sc->transport, data))
+ if (data == sc->transport)
return sc;
}
}
--- a/jingle/sessions.h Mon Aug 16 18:32:55 2010 +0200
+++ b/jingle/sessions.h Mon Aug 16 18:33:33 2010 +0200
@@ -75,16 +75,17 @@
JingleSession *session_new_from_jinglenode(JingleNode *jn);
JingleSession *session_find_by_sid(const gchar *sid, const gchar *from);
JingleSession *session_find(const JingleNode *jn);
-void session_add_content(JingleSession *sess, const gchar *name,
- SessionState state);
+SessionContent* session_add_content(JingleSession *sess, const gchar *name,
+ SessionState state);
void session_add_app(JingleSession *sess, const gchar *name,
const gchar *xmlns, gconstpointer data);
void session_add_trans(JingleSession *sess, const gchar *name,
const gchar *xmlns, gconstpointer data);
-void session_add_content_from_jinglecontent(JingleSession *sess, JingleContent *cn,
- SessionState state);
-SessionContent *session_find_sessioncontent(JingleSession *sess, const gchar *name);
-SessionContent *session_find_transport(const gchar *xmlns_trans, gconstpointer data);
+SessionContent* session_add_content_from_jinglecontent(JingleSession *sess,
+ JingleContent *cn, SessionState state, GError **err);
+SessionContent *session_find_transport(gconstpointer data);
+SessionContent *session_find_sessioncontent(JingleSession *sess,
+ const gchar *name);
int session_remove_sessioncontent(JingleSession *sess, const gchar *name);
void session_changestate_sessioncontent(JingleSession *sess, const gchar *name,
SessionState state);