From d5faaf9f81b868c59f2e5f5f980e51cee6ae1cc2 Mon Sep 17 00:00:00 2001 From: Andrea Zagli Date: Wed, 19 Aug 2015 23:03:06 +0200 Subject: [PATCH] Trying to get a reply. --- src/glib-mldonkey.c | 323 +++++++++++++++++++++++++++++++++++------- src/glib-mldonkey.h | 5 +- tests/glib-mldonkey.c | 2 +- 3 files changed, 276 insertions(+), 54 deletions(-) diff --git a/src/glib-mldonkey.c b/src/glib-mldonkey.c index d0e3a41..5ef94fa 100644 --- a/src/glib-mldonkey.c +++ b/src/glib-mldonkey.c @@ -45,7 +45,8 @@ static void glib_mldonkey_get_property (GObject *object, GValue *value, GParamSpec *pspec); -static void glib_mldonkey_dump_reply (GlibMldonkey *glibmldonkey); +static gboolean glib_mldonkey_read_message (GlibMldonkey* glibmldonkey); +static void glib_mldonkey_reply (GlibMldonkey *glibmldonkey, guint32 fopcode); #define GLIB_MLDONKEY_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GLIB_TYPE_MLDONKEY, GlibMldonkeyPrivate)) @@ -54,6 +55,11 @@ struct _GlibMldonkeyPrivate { GSocketClient *sclient; GSocketConnection *sconn; + GInputStream *istream; + GOutputStream *ostream; + + gchar *username; + gchar *password; }; G_DEFINE_TYPE (GlibMldonkey, glib_mldonkey, G_TYPE_OBJECT) @@ -95,6 +101,10 @@ glib_mldonkey_init (GlibMldonkey *glib_mldonkey) priv->sclient = NULL; priv->sconn = NULL; + priv->istream = NULL; + priv->ostream = NULL; + priv->username = NULL; + priv->password = NULL; } /** @@ -148,12 +158,18 @@ GlibMldonkey } gboolean -glib_mldonkey_connect (GlibMldonkey *glibmldonkey, const gchar *host_port) +glib_mldonkey_connect (GlibMldonkey *glibmldonkey, + const gchar *host_port, + const gchar *username, + const gchar *password) { GError *error; GlibMldonkeyPrivate *priv = GLIB_MLDONKEY_GET_PRIVATE (glibmldonkey); + priv->username = g_strdup (username); + priv->password = g_strdup (password); + priv->sclient = g_socket_client_new (); g_socket_client_set_enable_proxy (priv->sclient, FALSE); @@ -164,7 +180,8 @@ glib_mldonkey_connect (GlibMldonkey *glibmldonkey, const gchar *host_port) NULL, &error); if (priv->sconn == NULL - || error != NULL) + || error != NULL + || !g_socket_connection_is_connected (priv->sconn)) { g_warning ("Unable to connect to «%s»: %s.", host_port, @@ -173,15 +190,14 @@ glib_mldonkey_connect (GlibMldonkey *glibmldonkey, const gchar *host_port) return FALSE; } - if (g_socket_connection_is_connected (priv->sconn)) - { - glib_mldonkey_dump_reply (glibmldonkey); - return TRUE; - } - else + priv->istream = g_io_stream_get_input_stream (G_IO_STREAM (priv->sconn)); + priv->ostream = g_io_stream_get_output_stream (G_IO_STREAM (priv->sconn)); + + while (glib_mldonkey_read_message (glibmldonkey)) { - return FALSE; } + + return TRUE; } /* PRIVATE */ @@ -213,56 +229,259 @@ glib_mldonkey_get_property (GObject *object, guint property_id, GValue *value, G } } -static void -glib_mldonkey_dump_reply (GlibMldonkey *glibmldonkey) +typedef struct + { + guint16 fopcode; + guint32 length; + guint8 *data; + } GlibMldonkeyMessage; + +static guint16 +bytes2guint16 (const char *bytes) +{ + return (guint16)((bytes[1]<<8)|(bytes[0])); +} + +static guint32 +bytes2guint32 (const char *bytes) +{ + return (guint32)((bytes[3]<<24)|(bytes[2]<<16)|(bytes[1]<<8)|(bytes[0])); +} + +static gboolean +glib_mldonkey_read_message (GlibMldonkey *glibmldonkey) { - GInputStream *istream; - guint32 buf; + GlibMldonkeyMessage *msg; + guint16 buf16; + guint32 buf32; + gsize written; GError *error; + guint16 l; + GlibMldonkeyPrivate *priv = GLIB_MLDONKEY_GET_PRIVATE (glibmldonkey); - istream = g_io_stream_get_input_stream (G_IO_STREAM (priv->sconn)); + msg = (GlibMldonkeyMessage *)g_new0 (GlibMldonkeyMessage, 1); /* read first 4 byte, the content size */ - g_input_stream_read_all (istream, - &buf, - 4, - NULL, - NULL, - &error); - g_message ("content size: %d",GLONG_FROM_LE(buf)); + error = NULL; + written = g_input_stream_read (priv->istream, + &buf32, + 4, + NULL, + &error); + if (written < 1 + || error != NULL) + { + g_warning ("error %s", error != NULL && error->message != NULL ? error->message : "no details"); + return FALSE; + } + msg->length = buf32 - 2; + g_message ("content size: %d", msg->length); /* read next 2 byte, the function opcode */ - g_input_stream_read_all (istream, - &buf, - 2, - NULL, - NULL, - &error); - g_message ("function opcode: %d",GLONG_FROM_LE(buf)); - - /* function 0 */ - g_input_stream_read_all (istream, - &buf, - 4, - NULL, - NULL, - &error); - g_message ("maximum protocol version: %d",GLONG_FROM_LE(buf)); - g_input_stream_read_all (istream, - &buf, - 4, - NULL, - NULL, - &error); - g_message ("maximum opcode gui: %d",GLONG_FROM_LE(buf)); - g_input_stream_read_all (istream, - &buf, - 4, - NULL, - NULL, - &error); - g_message ("maximum opcode core: %d",GLONG_FROM_LE(buf)); + error = NULL; + written = g_input_stream_read (priv->istream, + &buf16, + 2, + NULL, + &error); + if (written < 1 + || error != NULL) + { + g_warning ("error %s", error != NULL && error->message != NULL ? error->message : "no details"); + return FALSE; + } + msg->fopcode = buf16; + g_message ("function opcode: %d", msg->fopcode); + /* the content */ + error = NULL; + msg->data = (guint8 *)g_new0 (guint8, msg->length); + written = g_input_stream_read (priv->istream, + &msg->data[0], + msg->length, + NULL, + &error); + if (written < 1 + || error != NULL) + { + g_warning ("error %s", error->message != NULL ? error->message : "no details"); + return FALSE; + } + else + { + g_message ("written: %d", written); + } + + switch (msg->fopcode) + { + case 0: /* CoreProtocol */ + g_message ("maximum protocol version: %d", bytes2guint32 (msg->data)); + g_message ("maximum opcode gui: %d", bytes2guint32 (msg->data + 4)); + g_message ("maximum opcode core: %d", bytes2guint32 (msg->data + 8)); + + glib_mldonkey_reply (glibmldonkey, msg->fopcode); + + break; + + case 19: /* ConsoleMessage */ + l = bytes2guint16 (msg->data); + g_message ("strlen %d", l); + + break; + + case 47: /* BadPassword */ + g_warning ("Bad username/password"); + + break; + } + + return TRUE; +} + +static void +glib_mldonkey_reply (GlibMldonkey *glibmldonkey, guint32 fopcode) +{ + gssize written; + guint16 buf16; + guint32 buf32; + GError *error; + + GlibMldonkeyPrivate *priv = GLIB_MLDONKEY_GET_PRIVATE (glibmldonkey); + + switch (fopcode) + { + case 0: + /* protocol version */ + buf32 = 4 + 2 + 4; + error = NULL; + written = g_output_stream_write (priv->ostream, + &buf32, + 4, + NULL, + &error); + if (written < 1 + || error != NULL) + { + g_warning ("error %s", error != NULL && error->message != NULL ? error->message : "no details"); + return; + } + + buf16 = 0; + error = NULL; + written = g_output_stream_write (priv->ostream, + &buf16, + 2, + NULL, + &error); + if (written < 1 + || error != NULL) + { + g_warning ("error %s", error != NULL && error->message != NULL ? error->message : "no details"); + return; + } + + buf32 = 41; + error = NULL; + written = g_output_stream_write (priv->ostream, + &buf32, + 4, + NULL, + &error); + if (written < 1 + || error != NULL) + { + g_warning ("error %s", error != NULL && error->message != NULL ? error->message : "no details"); + return; + } + + /* password */ + guint16 lname = strlen (priv->username); + guint16 lpassword = strlen (priv->password); + + buf32 = 4 + 2 + 2 + lname + 2 + lpassword; + error = NULL; + written = g_output_stream_write (priv->ostream, + &buf32, + 4, + NULL, + &error); + if (written < 1 + || error != NULL) + { + g_warning ("error %s", error != NULL && error->message != NULL ? error->message : "no details"); + return; + } + + buf16 = 52; + error = NULL; + written = g_output_stream_write (priv->ostream, + &buf16, + 2, + NULL, + &error); + if (written < 1 + || error != NULL) + { + g_warning ("error %s", error != NULL && error->message != NULL ? error->message : "no details"); + return; + } + + buf16 = lname; + error = NULL; + written = g_output_stream_write (priv->ostream, + &buf16, + 2, + NULL, + &error); + if (written < 1 + || error != NULL) + { + g_warning ("error %s", error != NULL && error->message != NULL ? error->message : "no details"); + return; + } + + error = NULL; + written = g_output_stream_write (priv->ostream, + &priv->username, + lname, + NULL, + &error); + if (written < 1 + || error != NULL) + { + g_warning ("error %s", error != NULL && error->message != NULL ? error->message : "no details"); + return; + } + + buf16 = lpassword; + error = NULL; + written = g_output_stream_write (priv->ostream, + &buf16, + 2, + NULL, + &error); + if (written < 1 + || error != NULL) + { + g_warning ("error %s", error != NULL && error->message != NULL ? error->message : "no details"); + return; + } + + error = NULL; + written = g_output_stream_write (priv->ostream, + &priv->password, + lpassword, + NULL, + &error); + if (written < 1 + || error != NULL) + { + g_warning ("error %s", error != NULL && error->message != NULL ? error->message : "no details"); + return; + } + + break; + } } diff --git a/src/glib-mldonkey.h b/src/glib-mldonkey.h index 72466cd..b848c9a 100644 --- a/src/glib-mldonkey.h +++ b/src/glib-mldonkey.h @@ -58,7 +58,10 @@ GType glib_mldonkey_get_type (void) G_GNUC_CONST; GlibMldonkey *glib_mldonkey_new (void); -gboolean glib_mldonkey_connect (GlibMldonkey *glibmldonkey, const gchar *host_port); +gboolean glib_mldonkey_connect (GlibMldonkey *glibmldonkey, + const gchar *host_port, + const gchar *username, + const gchar *password); G_END_DECLS diff --git a/tests/glib-mldonkey.c b/tests/glib-mldonkey.c index 49d7ddf..2ad984c 100644 --- a/tests/glib-mldonkey.c +++ b/tests/glib-mldonkey.c @@ -26,7 +26,7 @@ main (int argc, char **argv) GlibMldonkey *glibm; glibm = glib_mldonkey_new (); - glib_mldonkey_connect (glibm, "10.3.4.200:4001"); + glib_mldonkey_connect (glibm, argv[1], argv[2], argv[3]); return 0; } -- 2.49.0