static gboolean stream_recv_cb(gint sk, XmppStream *stream) { gchar buf[BUF_LENGTH]; gint n; if (!stream->ssl) { if ((n = recv(sk, buf, sizeof(buf) - 1, 0)) == -1) { hybrid_debug_error("xmpp", "init stream error."); return FALSE; } } else { if ((n = hybrid_ssl_read(stream->ssl, buf, sizeof(buf) - 1)) == -1) { hybrid_debug_error("xmpp", "stream read io error."); return TRUE; } else if (0 == n) { hybrid_debug_error("xmpp", "connection closed by server."); return FALSE; } } buf[n] = '\0'; if (n > 0) { xmpp_process_pushed(stream, buf, n); } return TRUE; }
/** * Callback function to handle the ssi read event. We get the response * string from the ssi server here. */ static gboolean ssi_auth_cb(HybridSslConnection *ssl, gpointer user_data) { gchar buf[BUF_LENGTH]; gchar *pos; gchar *pos1; gint ret; gint code; fetion_account *ac = (fetion_account*)user_data; ret = hybrid_ssl_read(ssl, buf, sizeof(buf)); if (ret == -1 || ret == 0) { hybrid_debug_error("ssi", "ssi server response error"); return FALSE; } buf[ret] = '\0'; hybrid_ssl_connection_destory(ssl); hybrid_debug_info("fetion", "recv:\n%s", buf); code = hybrid_get_http_code(buf); if (421 == code || 420 == code) { /* confirm code needed. */ if (HYBRID_ERROR == parse_ssi_fail_resp(ac, buf)) { goto ssi_auth_err; } verify_data.ssl = ssl; verify_data.type = VERIFY_TYPE_SSI; hybrid_proxy_connect(NAV_SERVER, 80, pic_download_cb, ac); return FALSE; } if (200 != code) { goto ssi_auth_err; } if (!(pos = strstr(buf, "ssic="))) { goto ssi_auth_err; } pos += 5; for (pos1 = pos; *pos1 && *pos1 != ';'; pos1 ++); ac->ssic = g_strndup(pos, pos1 - pos); if (!(pos = g_strrstr(buf, "\r\n\r\n"))) { goto ssi_auth_err; } pos += 4; if (strlen(pos) != hybrid_get_http_length(buf)) { goto ssi_auth_err; } if (parse_ssi_response(ac, pos) != HYBRID_OK) { goto ssi_auth_err; } /* * First of all, we load the account's version information from the disk, * so that we can use it for authenticating, if the server find the versions * are up-to-date, it would return a brief response message in stead of the * full version, so that we can use the information store locally. This method * makes account logining more faster. */ fetion_config_load_account(ac); /* now we will download the configuration */ hybrid_proxy_connect(NAV_SERVER, 80, cfg_connect_cb, ac); return FALSE; ssi_auth_err: hybrid_account_error_reason(ac->account, _("ssi authentication failed")); return FALSE; }