예제 #1
0
파일: fetion.c 프로젝트: celiachen/hybrid
/**
 * Process the user left message, we close the current channel,
 * and remove the session from the session list.
 */
static void
process_left_cb(fetion_account *ac, const gchar *sipmsg)
{
    extern GSList *channel_list;
    GSList        *pos;

    g_return_if_fail(ac != NULL);
    g_return_if_fail(sipmsg != NULL);

    hybrid_debug_info("fetion", "buddy left, recv:\n%s", sipmsg);

    for (pos = channel_list; pos; pos = pos->next) {
        if (pos->data == ac) {
            channel_list = g_slist_remove(channel_list, ac);

            goto channel_removed;
        }
    }

    hybrid_debug_error("fetion", "FATAL, can't find channel");

    return;

channel_removed:
    /* remove the read event source. */
    g_source_remove(ac->source);

    /* close the channel. */
    close(ac->sk);

    /* destroy the account. */
    fetion_account_destroy(ac);
}
예제 #2
0
파일: fx_login.c 프로젝트: GCrean/hybrid
/**
 * Callback function to handle the pushed message.
 */
gboolean
hybrid_push_cb(gint sk, gpointer user_data)
{
    gchar           sipmsg[BUF_LENGTH];
    gchar          *pos;
    gchar          *h;
    gchar          *msg;
    fetion_account *ac = (fetion_account*)user_data;
    gint            n;
    guint           len, data_len;

    if ((n = recv(sk, sipmsg, sizeof(sipmsg), 0)) == -1) {
        hybrid_account_error_reason(ac->account, _("connection terminated"));
        return FALSE;
    } else if (0 == n) {
        hybrid_debug_info("fetion", "hybrid_push_cb in fetion received 0 bytes,"
                          "connection closed.");
        channel_list = g_slist_remove(channel_list, ac);
        fetion_account_destroy(ac);
        close(sk);
        return FALSE;
    }

    sipmsg[n] = '\0';

    data_len = ac->buffer ? strlen(ac->buffer) : 0;
    ac->buffer = (gchar*)realloc(ac->buffer, data_len + n + 1);
    memcpy(ac->buffer + data_len, sipmsg, n + 1);

recheck:
    data_len = ac->buffer ? strlen(ac->buffer) : 0;

    if ((pos = strstr(ac->buffer, "\r\n\r\n"))) {
        pos += 4;
        h = (gchar*)g_malloc0(data_len - strlen(pos) + 1);
        memcpy(h, ac->buffer, data_len - strlen(pos));
        h[data_len - strlen(pos)] = '\0';

        if (strstr(h, "L: ")) {
            len = fetion_sip_get_length(ac->buffer);

            if (len <= strlen(pos)) {
                msg = (gchar*)g_malloc0(strlen(h) + len + 1);
                memcpy(msg, ac->buffer, strlen(h) + len);
                msg[strlen(h) + len] = '\0';
                /* A message is complete, process it. */
                process_pushed(ac, msg);

                memmove(ac->buffer, ac->buffer + strlen(msg), data_len - strlen(msg));
                ac->buffer = (gchar*)realloc(ac->buffer, data_len - strlen(msg) + 1);
                ac->buffer[data_len - strlen(msg)] = '\0';

                g_free(msg);
                g_free(h);
                msg = NULL;
                h = NULL;

                goto recheck;
            }

        } else {
            /* A message is complete, process it. */
            process_pushed(ac, h);

            memmove(ac->buffer, ac->buffer + strlen(h), data_len - strlen(h));
            ac->buffer = (gchar*)realloc(ac->buffer, data_len - strlen(h) + 1);
            ac->buffer[data_len - strlen(h)] = '\0';

            g_free(h);
            h = NULL;
            goto recheck;
        }
        g_free(h);
    }

    return TRUE;
}