gint push_cb(gpointer data, gint source, const gchar *UNUSED(error_message)) { gchar sipmsg[BUFLEN * 10], *h, *pos, *msg; gint n, data_len; guint len; fetion_account *ses = (fetion_account*)data; if((n = recv(source, sipmsg, sizeof(sipmsg), 0)) == -1) return -1; sipmsg[n] = '\0'; data_len = ses->data ? strlen(ses->data) : 0; ses->data = (gchar*)realloc(ses->data, data_len + n + 1); memcpy(ses->data + data_len, sipmsg, n + 1); recheck: data_len = strlen(ses->data); if((pos = strstr(ses->data, "\r\n\r\n"))) { pos += 4; h = (gchar*)g_malloc0(data_len - strlen(pos) + 1); memcpy(h, ses->data, data_len - strlen(pos)); h[data_len - strlen(pos)] = '\0'; if(strstr(h, "L: ")) { len = fetion_sip_get_length(ses->data); if(len <= strlen(pos)) { msg = (gchar*)g_malloc0(strlen(h) + len + 1); memcpy(msg, ses->data, strlen(h) + len); msg[strlen(h) + len] = '\0'; process_push_cb(ses, msg); memmove(ses->data, ses->data + strlen(msg), data_len - strlen(msg)); ses->data = (gchar*)realloc(ses->data, data_len - strlen(msg) + 1); ses->data[data_len - strlen(msg)] = '\0'; g_free(msg); msg = (gchar*)0; g_free(h); h = (gchar*)0; goto recheck; } } else { process_push_cb(ses, h); memmove(ses->data, ses->data + strlen(h), data_len - strlen(h)); ses->data = (gchar*)realloc(ses->data, data_len - strlen(h) + 1); ses->data[data_len - strlen(h)] = '\0'; g_free(h); h = (gchar*)0; goto recheck; } g_free(h); } return 0; }
/** * Callback function to handle the read event after * rendered sipc authentication. */ static gint sipc_auth_cb(fetion_account *ac, const gchar *sipmsg, fetion_transaction *trans) { gint code; gint length; gchar *pos; code = fetion_sip_get_code(sipmsg); hybrid_debug_info("fetion", "sipc recv:\n%s", sipmsg); if (code == FETION_SIP_OK) { /**< ok, we got the contact list */ /* update the portrait. */ fetion_account_update_portrait(ac); length = fetion_sip_get_length(sipmsg); pos = strstr(ac->buffer, "\r\n\r\n") + 4; parse_sipc_resp(ac, pos, length); /* set the nickname of the hybrid account. */ hybrid_account_set_nickname(ac->account, ac->nickname); /* set the mood phrase of the hybrid account. */ hybrid_account_set_status_text(ac->account, ac->mood_phrase); hybrid_account_set_state(ac->account, HYBRID_STATE_INVISIBLE); /* set the connection status. */ hybrid_account_set_connection_status(ac->account, HYBRID_CONNECTION_CONNECTED); /* init group list */ fetion_groups_init(ac); /* init buddy list */ fetion_buddies_init(ac); /* start scribe the pushed msg */ fetion_buddy_scribe(ac); } else if (420 == code || 421 == code) { if (HYBRID_ERROR == parse_sipc_verification(ac, sipmsg)) { hybrid_account_error_reason(ac->account, _("Fetion Protocol ERROR.")); return FALSE; } hybrid_debug_error("fetion", "sipc authentication need Verification."); verify_data.sipc_conn = ac->sk; verify_data.type = VERIFY_TYPE_SIP; hybrid_proxy_connect(NAV_SERVER, 80, pic_download_cb, ac); g_free(ac->buffer); ac->buffer = NULL; return HYBRID_OK; } else { g_free(ac->buffer); ac->buffer = NULL; return HYBRID_ERROR; } return HYBRID_ERROR; }
/** * 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; }