]> saetta.ns0.it Git - libglib-mldonkey/commitdiff
Trying to get a reply.
authorAndrea Zagli <andrea.zagli@email.it>
Wed, 19 Aug 2015 21:03:06 +0000 (23:03 +0200)
committerAndrea Zagli <andrea.zagli@email.it>
Wed, 19 Aug 2015 21:03:06 +0000 (23:03 +0200)
src/glib-mldonkey.c
src/glib-mldonkey.h
tests/glib-mldonkey.c

index d0e3a41b33ac561728a6df171f643d1b63b1c98d..5ef94fafab3baf67db966fd5a2c66ff2e1717e87 100644 (file)
@@ -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;
+               }
 }
index 72466cd17b4c9ec572bef107c5a7e59c87e7955e..b848c9a766c0a4be0581437df7d4c241194e9478 100644 (file)
@@ -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
index 49d7ddf2f46a70f1ccdc4995bad620fe89a855b2..2ad984ce244c2e078252792595704c0380925e73 100644 (file)
@@ -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;
 }