/** * Callback function to handle the cfg read event. */ static gboolean cfg_read_cb(gint sk, gpointer user_data) { gchar buf[BUF_LENGTH]; gint n; gint length = 0; gchar *pos; fetion_account *ac = (fetion_account*)user_data; if ((n = recv(sk, buf, sizeof(buf), 0)) == -1) { hybrid_account_error_reason(ac->account, _("read cfg failed")); return FALSE; } buf[n] = '\0'; if (n != 0) { /* larger the recv buffer, and copy the new * received bytes to the buffer */ length = ac->buffer ? strlen(ac->buffer) : 0; ac->buffer = g_realloc(ac->buffer, length + n + 1); memcpy(ac->buffer + length, buf, n + 1); return TRUE; } else { /* receive complete, start process */ if (hybrid_get_http_code(ac->buffer) != 200) { goto error; } hybrid_debug_info("fetion", "cfg recv:\n%s", ac->buffer); if (!(pos = g_strrstr(ac->buffer, "\r\n\r\n"))) { goto error; } pos += 4; if (strlen(pos) != hybrid_get_http_length(ac->buffer)) { goto error; } if (parse_configuration(ac, pos) != HYBRID_OK) { g_free(ac->buffer); ac->buffer = NULL; goto error; } g_free(ac->buffer); ac->buffer = NULL; /* now we start sipc register */ hybrid_proxy_connect(ac->sipc_proxy_ip, ac->sipc_proxy_port, sipc_reg_action, ac); } return FALSE; error: hybrid_account_error_reason(ac->account, _("read cfg failed")); return FALSE; }
/** * 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; }
/** * Callback function to handle the portrait receive event. */ static gboolean portrait_recv_cb(gint sk, gpointer user_data) { gchar buf[BUF_LENGTH]; gint n; gchar *pos; HybridBuddy *imbuddy; portrait_trans *trans = (portrait_trans*)user_data; if ((n = recv(sk, buf, sizeof(buf), 0)) == -1) { hybrid_debug_error("fetion", "get portrait for \'%s\':%s", trans->buddy ? trans->buddy->sid : trans->ac->sid, strerror(errno)); return FALSE; } buf[n] = '\0'; if (n == 0) { if (trans->portrait_type == PORTRAIT_TYPE_BUDDY) { imbuddy = hybrid_blist_find_buddy(trans->ac->account, trans->buddy->userid); } if (hybrid_get_http_code(trans->data) != 200) { /* * Note that we got no portrait, but we still need * to set buddy icon, just for the portrait checksum, we * set it default to "0" instead of leaving it NULL, * so that in the next login, we just check the changes * of the buddy's checksum to determine whether to fetch a * portrait from the server. */ if (trans->portrait_type == PORTRAIT_TYPE_BUDDY) { hybrid_blist_set_buddy_icon(imbuddy, NULL, 0, trans->buddy->portrait_crc); } else { hybrid_account_set_icon(trans->ac->account, NULL, 0, trans->ac->portrait_crc); } goto pt_fin; } trans->data_len = hybrid_get_http_length(trans->data); if (!(pos = strstr(trans->data, "\r\n\r\n"))) { goto pt_fin; } pos += 4; if (trans->portrait_type == PORTRAIT_TYPE_BUDDY) { /**< buddy portrait */ hybrid_blist_set_buddy_icon(imbuddy, (guchar*)pos, trans->data_len, trans->buddy->portrait_crc); } else { hybrid_account_set_icon(trans->ac->account, (guchar*)pos, trans->data_len, trans->ac->portrait_crc); } goto pt_fin; } else { trans->data = realloc(trans->data, trans->data_size + n); memcpy(trans->data + trans->data_size, buf, n); trans->data_size += n; } return TRUE; pt_fin: g_free(trans->data); g_free(trans); return FALSE; }