示例#1
0
MsnSession *
msn_session_new (const gchar *username,
                 const gchar *password,
                 gboolean http_method)
{
    MsnSession *session;

    session = g_new0 (MsnSession, 1);

    session->username = pn_normalize (username);
    session->password = g_strndup (password, 16);

#ifdef INTERNAL_MAINLOOP
    session->g_main_loop = g_main_loop_new  (NULL, FALSE);
    session->g_main_loop_timer = purple_timeout_add (1000, g_main_context_iteration_timer, NULL);
#endif

    session->config = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);

    /** @todo sb and ns need this here but should be updated on-the-fly. */
    msn_session_set_bool (session, "use_http_method", http_method);

#if 0
    if (session->http_method)
    {
        PnNode *foo;
        foo = PN_NODE (pn_http_server_new ("foo server"));
        foo->session = session;
        session->http_conn = foo;
    }
#endif

    session->dp_manager = pn_dp_manager_new (session);

    session->notification = msn_notification_new (session);
    pn_node_set_id(session->notification->cmdproc->conn,
                   session->conn_count++, "ns");

    session->contactlist = pn_contactlist_new (session);

    session->user = pn_contact_new (NULL);
    pn_contact_set_passport (session->user, session->username);

    session->conv_seq = 1;

    session->oim_session = pn_oim_session_new (session);

    session->conversations = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) msn_switchboard_unref);
    session->chats = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) msn_switchboard_unref);

#if defined(PECAN_CVR)
    session->links = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) pn_peer_link_unref);
#endif /* defined(PECAN_CVR) */

    purple_signal_connect (purple_conversations_get_handle(), "conversation-created",
                           session, PURPLE_CALLBACK (conversation_created_cb), session);

    return session;
}
示例#2
0
static void
finalize (GObject *obj)
{
    PnNode *conn = PN_NODE (obj);

    pn_node_close (conn);

    g_free (conn->name);
    parent_class->finalize (obj);
}
示例#3
0
static void
connect_cb(GObject *source,
           GAsyncResult *res,
           gpointer user_data)
{
    GSocketConnection *socket_conn;
    PnNode *conn;
    GError *error = NULL;

    conn = PN_NODE(user_data);
    socket_conn = g_socket_client_connect_to_host_finish(G_SOCKET_CLIENT(source), res, &error);

    g_object_unref(source);

    if (error) {
        g_error_free(error);
        return;
    }

    g_object_ref(conn);

    if (socket_conn) {
        GSocket *socket;
        GInputStream *input;

        conn->socket_conn = socket_conn;
        socket = g_socket_connection_get_socket(socket_conn);

        conn->status = PN_NODE_STATUS_OPEN;

        input = g_io_stream_get_input_stream (G_IO_STREAM (conn->socket_conn));
        g_object_ref (conn);
        g_input_stream_read_async (input, conn->input_buffer, PN_BUF_LEN,
                                   G_PRIORITY_DEFAULT, NULL,
                                   read_cb, conn);
    }
    else {
        conn->error = g_error_new_literal(PN_NODE_ERROR, PN_NODE_ERROR_OPEN,
                                          "Unable to connect");

        pn_node_error(conn);
    }

    {
        PnNodeClass *class;
        class = g_type_class_peek(PN_NODE_TYPE);
        g_signal_emit(G_OBJECT(conn), class->open_sig, 0, conn);
    }

    g_object_unref(conn);
}
示例#4
0
static void
connect_cb (gpointer data,
            gint source,
            const gchar *error_message)
{
    PnNode *conn;

    pn_log ("begin");

    conn = PN_NODE (data);
    conn->connect_data = NULL;

    g_object_ref (conn);

    if (source >= 0)
    {
        GIOChannel *channel;

        conn->stream = pn_stream_new (source);
        channel = conn->stream->channel;

        PN_NODE_GET_CLASS (conn)->channel_setup (conn, channel);

        conn->status = PN_NODE_STATUS_OPEN;

        pn_info ("connected: conn=%p,channel=%p", conn, channel);
        conn->read_watch = g_io_add_watch (channel, G_IO_IN, read_cb, conn);
#if 0
        g_io_add_watch (channel, G_IO_ERR | G_IO_HUP | G_IO_NVAL, close_cb, conn);
#endif
    }
    else
    {
        /* pn_error ("connection error: conn=%p,msg=[%s]", conn, error_message); */
        conn->error = g_error_new_literal (PN_NODE_ERROR, PN_NODE_ERROR_OPEN,
                                           error_message ? error_message : "Unable to connect");

        pn_node_error (conn);
    }

    {
        PnNodeClass *class;
        class = g_type_class_peek (PN_NODE_TYPE);
        g_signal_emit (G_OBJECT (conn), class->open_sig, 0, conn);
    }

    g_object_unref (conn);

    pn_log ("end");
}
示例#5
0
static void
read_cb (GObject *source,
         GAsyncResult *result,
         gpointer user_data)
{
    PnNode *conn;
    gssize size;
    GError *error = NULL;

    conn = PN_NODE(user_data);
    size = g_input_stream_read_finish (G_INPUT_STREAM (source),
                                       result, &error);

    conn = PN_NODE(user_data);

    if (G_UNLIKELY (size == 0))
        error = g_error_new_literal(PN_NODE_ERROR, PN_NODE_ERROR_OPEN,
                                    "End of stream");

    if (error)
        goto nok;

    pn_node_parse (conn, (char *) conn->input_buffer, size);

    if (conn->status == PN_NODE_STATUS_OPEN)
        g_input_stream_read_async (G_INPUT_STREAM (source), conn->input_buffer, PN_BUF_LEN,
                                   G_PRIORITY_DEFAULT, NULL, read_cb, conn);
    else
        g_object_unref (conn);

    return;

nok:
    conn->error = error;
    pn_node_error (conn);
    g_object_unref (conn);
}
示例#6
0
static gboolean
read_cb (GIOChannel *source,
         GIOCondition condition,
         gpointer data)
{
    PnNode *conn;
    gchar buf[PN_BUF_LEN + 1];
    gsize bytes_read;

    pn_log ("begin");

    conn = PN_NODE (data);

    pn_debug ("conn=%p,name=%s", conn, conn->name);

    g_object_ref (conn);

    {
        GIOStatus status = G_IO_STATUS_NORMAL;

        status = pn_node_read (conn, buf, PN_BUF_LEN, &bytes_read, NULL);

        if (status == G_IO_STATUS_AGAIN)
        {
            g_object_unref (conn);
            return TRUE;
        }

        if (status == G_IO_STATUS_EOF)
        {
            conn->error = g_error_new (PN_NODE_ERROR, PN_NODE_ERROR_OPEN, "End of stream");
        }

        if (conn->error)
        {
            pn_node_error (conn);
            g_object_unref (conn);
            return FALSE;
        }
    }

    pn_node_parse (conn, buf, bytes_read);

    g_object_unref (conn);

    pn_log ("end");

    return TRUE;
}
示例#7
0
static void
connect_cb(GObject *source,
           GAsyncResult *res,
           gpointer user_data)
{
    GSocketConnection *socket_conn;
    PnNode *conn;

    conn = PN_NODE(user_data);
    socket_conn = g_socket_client_connect_to_host_finish(G_SOCKET_CLIENT(source), res, NULL);

    g_object_unref(source);

    g_object_ref(conn);

    if (socket_conn) {
        GIOChannel *channel;
        GSocket *socket;

        conn->socket_conn = socket_conn;
        socket = g_socket_connection_get_socket(socket_conn);
        conn->stream = pn_stream_new(g_socket_get_fd(socket));
        channel = conn->stream->channel;

        PN_NODE_GET_CLASS (conn)->channel_setup (conn, channel);

        conn->status = PN_NODE_STATUS_OPEN;

        pn_info("connected: conn=%p,channel=%p", conn, channel);
        conn->read_watch = g_io_add_watch(channel, G_IO_IN, read_cb, conn);
#if 0
        g_io_add_watch (channel, G_IO_ERR | G_IO_HUP | G_IO_NVAL, close_cb, conn);
#endif
    }
    else {
        conn->error = g_error_new_literal(PN_NODE_ERROR, PN_NODE_ERROR_OPEN,
                                          "Unable to connect");

        pn_node_error(conn);
    }

    {
        PnNodeClass *class;
        class = g_type_class_peek(PN_NODE_TYPE);
        g_signal_emit(G_OBJECT(conn), class->open_sig, 0, conn);
    }

    g_object_unref(conn);
}
示例#8
0
static gboolean
write_cb (GIOChannel *source,
          GIOCondition condition,
          gpointer data)
{
    PnHttpServer *http_conn = data;

    if (http_conn->last_flush == G_IO_STATUS_AGAIN) {
        http_conn->last_flush = pn_stream_flush(PN_NODE(http_conn)->stream, NULL);
        if (http_conn->last_flush == G_IO_STATUS_AGAIN)
            return TRUE;
    }

    http_conn->write_watch = 0;

    return FALSE;
}
示例#9
0
PnNode *
pn_node_new (gchar *name,
             PnNodeType type)
{
    PnNode *conn;

    pn_log ("begin");

    conn = PN_NODE (g_type_create_instance (PN_NODE_TYPE));

    conn->name = g_strdup (name);
    conn->type = type;

    pn_log ("end");

    return conn;
}
示例#10
0
PnHttpServer *
pn_http_server_new (const gchar *name)
{
    PnHttpServer *http_conn;

    pn_log ("begin");

    http_conn = PN_HTTP_SERVER (g_type_create_instance (PN_HTTP_SERVER_TYPE));

    {
        PnNode *tmp = PN_NODE (http_conn);
        tmp->name = g_strdup (name);
        tmp->type = PN_NODE_HTTP;
    }

    pn_log ("end");

    return http_conn;
}
示例#11
0
static void
close_cb (PnNode *next,
          gpointer data)
{
    PnNode *conn;

    conn = PN_NODE (data);

    pn_log ("begin");

    pn_node_close (conn);

    {
        PnNodeClass *class;
        class = g_type_class_peek (PN_NODE_TYPE);
        g_signal_emit (G_OBJECT (conn), class->close_sig, 0, conn);
    }

    pn_log ("end");
}
示例#12
0
文件: nexus.c 项目: felipec/msn-pecan
void
msn_nexus_connect(MsnNexus *nexus)
{
    PnSslConn *ssl_conn;
    PnNode *conn;

    ssl_conn = pn_ssl_conn_new("nexus", PN_NODE_NULL);

    conn = PN_NODE(ssl_conn);
    conn->session = nexus->session;

    nexus->parser = pn_parser_new(conn);
    pn_ssl_conn_set_read_cb(ssl_conn, nexus_read_cb, nexus);

    nexus->conn = conn;
    nexus->open_handler = g_signal_connect(conn, "open", G_CALLBACK(nexus_open_cb), nexus);
    nexus->error_handler = g_signal_connect(conn, "error", G_CALLBACK(close_cb), nexus);

    pn_node_connect(conn, "nexus.passport.com", 443);
}
示例#13
0
static void
dispose (GObject *obj)
{
    PnNode *conn = PN_NODE (obj);

    pn_log ("begin");

    if (conn->next)
    {
        g_signal_handler_disconnect (conn->next, conn->open_sig_handler);
        g_signal_handler_disconnect (conn->next, conn->close_sig_handler);
        g_signal_handler_disconnect (conn->next, conn->error_sig_handler);
        pn_node_free (conn->next);
        conn->next = NULL;
    }

    parent_class->dispose (obj);

    pn_log ("end");
}
示例#14
0
static void
process_queue (PnHttpServer *http_conn,
               GError **error)
{
    HttpQueueData *queue_data;

    queue_data = g_queue_pop_head (http_conn->write_queue);

    if (queue_data)
    {
        foo_write (PN_NODE (http_conn),
                   queue_data->conn,
                   queue_data->body,
                   queue_data->body_len,
                   NULL,
                   error);
        g_object_unref (queue_data->conn);
        g_free (queue_data->body);
        g_free (queue_data);
    }
}
示例#15
0
static void auth_cb (PnAuth *auth, void *data)
{
    PnSslConn *ssl_conn;
    PnNode *conn;
    RoamingRequest *roaming_request = data;

    ssl_conn = pn_ssl_conn_new ("ab_roaming", PN_NODE_NULL);

    conn = PN_NODE (ssl_conn);
    conn->session = roaming_request->roaming_session->session;

    roaming_request->parser = pn_parser_new (conn);
    pn_ssl_conn_set_read_cb (ssl_conn, read_cb, roaming_request);

    if (!roaming_request->roaming_session->hostname)
        pn_node_connect (conn, "tkrdr.storage.msn.com", 443);
    else
        pn_node_connect (conn, roaming_request->roaming_session->hostname, 443);

    roaming_request->conn = conn;
    roaming_request->open_sig_handler = g_signal_connect (conn, "open", G_CALLBACK (open_cb), roaming_request);
}
示例#16
0
static void
open_cb (PnNode *next,
         gpointer data)
{
    PnNode *conn;

    conn = PN_NODE (data);

    pn_log ("begin");

    conn->status = PN_NODE_STATUS_OPEN;

    {
        PnNodeClass *class;
        class = g_type_class_peek (PN_NODE_TYPE);
        g_signal_emit (G_OBJECT (conn), class->open_sig, 0, conn);
    }

    g_signal_handler_disconnect (next, conn->open_sig_handler);
    conn->open_sig_handler = 0;

    pn_log ("end");
}
示例#17
0
static void
error_cb (PnNode *next,
          gpointer data)
{
    PnNode *conn;

    conn = PN_NODE (data);

    pn_log ("begin");

    if (next->error)
    {
        g_propagate_error (&conn->error, next->error);
        next->error = NULL;
    }

    {
        PnNodeClass *class;
        class = g_type_class_peek (PN_NODE_TYPE);
        g_signal_emit (G_OBJECT (conn), class->error_sig, 0, conn);
    }

    pn_log ("end");
}
示例#18
0
static gboolean
http_poll (gpointer data)
{
    PnNode *conn;
    PnHttpServer *http_conn;
    GIOStatus status = G_IO_STATUS_NORMAL;
    GError *tmp_error = NULL;
    gsize bytes_written = 0;
    static guint count = 0;

    gchar *header;
    gchar *params;
    gchar *auth = NULL;

    g_return_val_if_fail (data != NULL, FALSE);

    conn = PN_NODE (data);
    http_conn = PN_HTTP_SERVER (data);

    pn_debug ("stream=%p", conn->stream);

    if (!http_conn->cur)
        return TRUE;

    g_return_val_if_fail (http_conn->cur, FALSE);

    count++;

    /* Don't poll if we already sent something, unless we have been waiting for
     * too long; a disconnection might have happened. */
    if (http_conn->waiting_response && count < 10)
    {
        /* There's no need to poll if we're already waiting for a response */
        pn_debug ("waiting for response");
        return TRUE;
    }

#ifdef HAVE_LIBPURPLE
    auth = get_auth(conn);
#endif /* HAVE_LIBPURPLE */

    params = g_strdup_printf ("Action=poll&SessionID=%s",
                              (gchar *) http_conn->cur->foo_data);

    header = g_strdup_printf ("POST http://%s/gateway/gateway.dll?%s HTTP/1.1\r\n"
                              "Accept: */*\r\n"
                              "User-Agent: MSMSGS\r\n"
                              "Host: %s\r\n"
                              "%s" /* Proxy auth */
                              "Proxy-Connection: Keep-Alive\r\n"
                              "Connection: Keep-Alive\r\n"
                              "Pragma: no-cache\r\n"
                              "Cache-Control: no-cache\r\n"
                              "Content-Type: application/x-msn-messenger\r\n"
                              "Content-Length: 0\r\n\r\n",
                              http_conn->gateway,
                              params,
                              http_conn->gateway,
                              auth ? auth : "");

#ifdef PECAN_DEBUG_HTTP
    pn_debug ("header=[%s]", header);
#endif

    g_free (params);

    status = pn_stream_write_full (conn->stream, header, strlen (header), &bytes_written, &tmp_error);

    g_free (header);

    http_conn->waiting_response = TRUE;
    pn_timer_stop (http_conn->timer);

    if (status == G_IO_STATUS_NORMAL)
    {
        status = pn_stream_flush (conn->stream, &tmp_error);

        if (status == G_IO_STATUS_AGAIN) {
            http_conn->last_flush = status;
            http_conn->write_watch = g_io_add_watch(conn->stream->channel,
                                                    G_IO_OUT, write_cb, http_conn);
            /* fake status */
            status = G_IO_STATUS_NORMAL;
        }

        if (status == G_IO_STATUS_NORMAL)
            pn_log ("bytes_written=%zu", bytes_written);
    }

    if (status != G_IO_STATUS_NORMAL)
    {
        PnNodeClass *class;
        pn_error ("not normal: status=%d", status);
        class = g_type_class_peek (PN_NODE_TYPE);
        g_signal_emit (G_OBJECT (conn), class->error_sig, 0, conn);
        return FALSE;
    }
示例#19
0
MsnSession *
msn_session_new (const gchar *username,
                 const gchar *password,
                 gboolean http_method)
{
    MsnSession *session;
    PnClientCaps caps;

    session = g_new0 (MsnSession, 1);

    session->username = pn_normalize (username);
    session->password = g_strndup (password, 16);

#ifdef INTERNAL_MAINLOOP
    session->g_main_loop = g_main_loop_new  (NULL, FALSE);
    session->g_main_loop_timer = purple_timeout_add (1000, g_main_context_iteration_timer, NULL);
#endif

    session->config = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);

    /** @todo sb and ns need this here but should be updated on-the-fly. */
    msn_session_set_bool (session, "use_http_method", http_method);

#if 0
    if (session->http_method)
    {
        PnNode *foo;
        foo = PN_NODE (pn_http_server_new ("foo server"));
        foo->session = session;
        session->http_conn = foo;
    }
#endif

    session->dp_manager = pn_dp_manager_new (session);

    session->notification = msn_notification_new (session);
    pn_node_set_id(session->notification->cmdproc->conn,
                   session->conn_count++, "ns");

    session->contactlist = pn_contactlist_new (session);

    session->user = pn_contact_new (NULL);
    pn_contact_set_passport (session->user, session->username);

    session->conv_seq = 1;

    session->machineguid = pn_rand_guid ();

    session->oim_session = pn_oim_session_new (session);
    session->service_session = pn_service_session_new (session);
    session->roaming_session = pn_roaming_session_new (session);

    session->conversations = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) msn_switchboard_unref);
    session->chats = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) msn_switchboard_unref);

#if defined(PECAN_CVR)
    session->links = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) pn_peer_link_unref);
#endif /* defined(PECAN_CVR) */

    caps = PN_CLIENT_CAP_BASE;
#if defined(PECAN_CVR)
    caps |= PN_CLIENT_CAP_INK_GIF;
#if defined(PECAN_LIBSIREN)
    caps |= PN_CLIENT_CAP_VOICE_CLIP;
#endif
#if defined(PECAN_LIBMSPACK)
    caps |= PN_CLIENT_CAP_WINKS;
#endif
#endif

    session->client_id = caps | PN_CLIENT_VER_2009;

    return session;
}
示例#20
0
文件: nexus.c 项目: felipec/msn-pecan
static void
nexus_read_cb(PnNode *conn,
              gpointer data)
{
    MsnNexus *nexus = data;
    GIOStatus status = G_IO_STATUS_NORMAL;
    gchar *str = NULL;

    while (nexus->parser_state == 0) {
        gsize terminator_pos;

        status = pn_parser_read_line(nexus->parser, &str, NULL, &terminator_pos, NULL);

        if (status == G_IO_STATUS_AGAIN)
            return;

        if (status != G_IO_STATUS_NORMAL) {
            msn_session_set_error(nexus->session, MSN_ERROR_AUTH,
                                  _("nexus stream error"));
            return;
        }

        if (str) {
            char *field;
            str[terminator_pos] = '\0';

            if ((field = get_field(str, "PassportURLs: "))) {
                char *da_login;

                da_login = strstr(field, "DALogin="******"DALogin="******"msnia.login.live.com");
#endif
                }
            }

            g_free(str);

            if (nexus->login_host) {
                PnSslConn *ssl_conn;
                PnNode *conn;

                ssl_conn = pn_ssl_conn_new("login", PN_NODE_NULL);

                conn = PN_NODE(ssl_conn);
                conn->session = nexus->session;

                if (nexus->error_handler)
                    g_signal_handler_disconnect(nexus->conn, nexus->error_handler);
                if (nexus->open_handler)
                    g_signal_handler_disconnect(nexus->conn, nexus->open_handler);
                g_object_unref(nexus->conn);
                pn_parser_free(nexus->parser);
                nexus->parser_state = 0;

                nexus->parser = pn_parser_new(conn);
                pn_ssl_conn_set_read_cb(ssl_conn, login_read_cb, nexus);

                nexus->conn = conn;
                nexus->open_handler = g_signal_connect(conn, "open", G_CALLBACK(login_open_cb), nexus);
                nexus->error_handler = g_signal_connect(conn, "error", G_CALLBACK(close_cb), nexus);

                pn_node_connect(conn, nexus->login_host, 443);

                return;
            }
        }
    }
}
示例#21
0
static gboolean
read_cb (GIOChannel *source,
         GIOCondition condition,
         gpointer data)
{
    PnNode *conn;
    gchar buf[PN_BUF_LEN + 1];
    gsize bytes_read;

    pn_log ("begin");

    conn = PN_NODE (data);

    pn_debug ("conn=%p,source=%p", conn, source);

    g_object_ref (conn);

    {
        GIOStatus status = G_IO_STATUS_NORMAL;

        status = pn_node_read (conn, buf, PN_BUF_LEN, &bytes_read, &conn->error);

        if (status == G_IO_STATUS_AGAIN)
        {
            g_object_unref (conn);
            return TRUE;
        }

        if (conn->error)
        {
            pn_node_error (conn);
            g_object_unref (conn);
            return FALSE;
        }

        if (status != G_IO_STATUS_NORMAL)
        {
            pn_warning ("not normal, status=%d", status);
            g_object_unref (conn);
            return TRUE;
        }
    }

    if (!conn->error)
    {
        PnHttpServer *http_conn;

        http_conn = PN_HTTP_SERVER (conn);

        if (http_conn->cur)
        {
            /* make sure the server is not sending the same buffer again */
            /** @todo find out why this happens */
            if (!(http_conn->old_buffer &&
                  strncmp (buf, http_conn->old_buffer, bytes_read) == 0))
            {
                pn_node_parse (http_conn->cur, buf, bytes_read);

                g_free (http_conn->old_buffer);
                http_conn->old_buffer = g_strndup (buf, bytes_read);
            }
        }

        if (conn->error)
        {
            pn_node_error (conn);
            g_object_unref (conn);
            return FALSE;
        }
    }

    g_object_unref (conn);

    pn_log ("end");

    return TRUE;
}