⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ops.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	default:		if (success)			purple_debug_info("silc", "Unhandled command: %d (succeeded)\n", command);		else			purple_debug_info("silc", "Unhandled command: %d (failed: %s)\n", command,							silc_get_status_message(status));		break;	}	va_end(vp);}/* Called to indicate that connection was either successfully established   or connecting failed.  This is also the first time application receives   the SilcClientConnection object which it should save somewhere.   If the `success' is FALSE the application must always call the function   silc_client_close_connection. */static voidsilc_connected(SilcClient client, SilcClientConnection conn,	       SilcClientConnectionStatus status){	PurpleConnection *gc = client->application;	SilcPurple sg;	if (gc == NULL) {		silc_client_close_connection(client, conn);		return;	}	sg = gc->proto_data;	switch (status) {	case SILC_CLIENT_CONN_SUCCESS:	case SILC_CLIENT_CONN_SUCCESS_RESUME:		purple_connection_set_state(gc, PURPLE_CONNECTED);		/* Send the server our buddy list */		silcpurple_send_buddylist(gc);		g_unlink(silcpurple_session_file(purple_account_get_username(sg->account)));		/* Send any UMODEs configured for account */		if (purple_account_get_bool(sg->account, "block-ims", FALSE)) {			silc_client_command_call(sg->client, sg->conn, NULL,					"UMODE", "+P", NULL);		}		return;		break;	case SILC_CLIENT_CONN_ERROR:		purple_connection_error(gc, _("Error during connecting to SILC Server"));		g_unlink(silcpurple_session_file(purple_account_get_username(sg->account)));		break;	case SILC_CLIENT_CONN_ERROR_KE:		purple_connection_error(gc, _("Key Exchange failed"));		break;	case SILC_CLIENT_CONN_ERROR_AUTH:		purple_connection_error(gc, _("Authentication failed"));		break;	case SILC_CLIENT_CONN_ERROR_RESUME:		purple_connection_error(gc,				      _("Resuming detached session failed. "					"Press Reconnect to create new connection."));		g_unlink(silcpurple_session_file(purple_account_get_username(sg->account)));		break;	case SILC_CLIENT_CONN_ERROR_TIMEOUT:		purple_connection_error(gc, _("Connection Timeout"));		break;	}	/* Error */	sg->conn = NULL;	silc_client_close_connection(client, conn);}/* Called to indicate that connection was disconnected to the server.   The `status' may tell the reason of the disconnection, and if the   `message' is non-NULL it may include the disconnection message   received from server. */static voidsilc_disconnected(SilcClient client, SilcClientConnection conn,		  SilcStatus status, const char *message){	PurpleConnection *gc = client->application;	SilcPurple sg = gc->proto_data;	if (sg->resuming && !sg->detaching)		g_unlink(silcpurple_session_file(purple_account_get_username(sg->account)));	sg->conn = NULL;	/* Close the connection */	if (!sg->detaching)		purple_connection_error(gc, _("Disconnected by server"));	else		/* TODO: Does this work correctly? Maybe we need to set wants_to_die? */		purple_account_disconnect(purple_connection_get_account(gc));}typedef struct {	SilcGetAuthMeth completion;	void *context;} *SilcPurpleGetAuthMethod;/* Callback called when we've received the authentication method information   from the server after we've requested it. */static void silc_get_auth_method_callback(SilcClient client,					  SilcClientConnection conn,					  SilcAuthMethod auth_meth,					  void *context){	SilcPurpleGetAuthMethod internal = context;	switch (auth_meth) {	case SILC_AUTH_NONE:		/* No authentication required. */		(*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);		break;	case SILC_AUTH_PASSWORD:		/* By returning NULL here the library will ask the passphrase from us		   by calling the silc_ask_passphrase. */		(*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);		break;	case SILC_AUTH_PUBLIC_KEY:		/* Do not get the authentication data now, the library will generate		   it using our default key, if we do not provide it here. */		(*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);		break;	}	silc_free(internal);}/* Find authentication method and authentication data by hostname and   port. The hostname may be IP address as well. When the authentication   method has been resolved the `completion' callback with the found   authentication method and authentication data is called. The `conn'   may be NULL. */static voidsilc_get_auth_method(SilcClient client, SilcClientConnection conn,		     char *hostname, SilcUInt16 port,		     SilcGetAuthMeth completion, void *context){	PurpleConnection *gc = client->application;	SilcPurple sg = gc->proto_data;	SilcPurpleGetAuthMethod internal;	const char *password;	/* Progress */	if (sg->resuming)		purple_connection_update_progress(gc, _("Resuming session"), 4, 5);	else		purple_connection_update_progress(gc, _("Authenticating connection"), 4, 5);	/* Check configuration if we have this connection configured.  If we	   have then return that data immediately, as it's faster way. */	if (purple_account_get_bool(sg->account, "pubkey-auth", FALSE)) {		completion(TRUE, SILC_AUTH_PUBLIC_KEY, NULL, 0, context);		return;	}	password = purple_connection_get_password(gc);	if (password && *password) {		completion(TRUE, SILC_AUTH_PASSWORD, (unsigned char *)password, strlen(password), context);		return;	}	/* Resolve the authentication method from server, as we may not know it. */	internal = silc_calloc(1, sizeof(*internal));	if (!internal)		return;	internal->completion = completion;	internal->context = context;	silc_client_request_authentication_method(client, conn,						  silc_get_auth_method_callback,						  internal);}/* Verifies received public key. The `conn_type' indicates which entity   (server, client etc.) has sent the public key. If user decides to trust   the application may save the key as trusted public key for later   use. The `completion' must be called after the public key has been   verified. */static voidsilc_verify_public_key(SilcClient client, SilcClientConnection conn,		       SilcSocketType conn_type, unsigned char *pk,		       SilcUInt32 pk_len, SilcSKEPKType pk_type,		       SilcVerifyPublicKey completion, void *context){	PurpleConnection *gc = client->application;	SilcPurple sg = gc->proto_data;	if (!sg->conn && (conn_type == SILC_SOCKET_TYPE_SERVER ||			  conn_type == SILC_SOCKET_TYPE_ROUTER)) {		/* Progress */		if (sg->resuming)			purple_connection_update_progress(gc, _("Resuming session"), 3, 5);		else			purple_connection_update_progress(gc, _("Verifying server public key"),							3, 5);	}	/* Verify public key */	silcpurple_verify_public_key(client, conn, NULL, conn_type, pk,				   pk_len, pk_type, completion, context);}typedef struct {	SilcAskPassphrase completion;	void *context;} *SilcPurpleAskPassphrase;static voidsilc_ask_passphrase_cb(SilcPurpleAskPassphrase internal, const char *passphrase){	if (!passphrase || !(*passphrase))		internal->completion(NULL, 0, internal->context);	else		internal->completion((unsigned char *)passphrase,				     strlen(passphrase), internal->context);	silc_free(internal);}/* Ask (interact, that is) a passphrase from user. The passphrase is   returned to the library by calling the `completion' callback with   the `context'. The returned passphrase SHOULD be in UTF-8 encoded,   if not then the library will attempt to encode. */static voidsilc_ask_passphrase(SilcClient client, SilcClientConnection conn,		    SilcAskPassphrase completion, void *context){	PurpleConnection *gc = client->application;	SilcPurpleAskPassphrase internal = silc_calloc(1, sizeof(*internal));	if (!internal)		return;	internal->completion = completion;	internal->context = context;	purple_request_input(gc, _("Passphrase"), NULL,			   _("Passphrase required"), NULL, FALSE, TRUE, NULL,			   _("OK"), G_CALLBACK(silc_ask_passphrase_cb),			   _("Cancel"), G_CALLBACK(silc_ask_passphrase_cb),			   purple_connection_get_account(gc), NULL, NULL, internal);}/* Notifies application that failure packet was received.  This is called   if there is some protocol active in the client.  The `protocol' is the   protocol context.  The `failure' is opaque pointer to the failure   indication.  Note, that the `failure' is protocol dependant and   application must explicitly cast it to correct type.  Usually `failure'   is 32 bit failure type (see protocol specs for all protocol failure   types). */static voidsilc_failure(SilcClient client, SilcClientConnection conn,	     SilcProtocol protocol, void *failure){	PurpleConnection *gc = client->application;	char buf[128];	memset(buf, 0, sizeof(buf));	if (protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) {		SilcSKEStatus status = (SilcSKEStatus)SILC_PTR_TO_32(failure);		if (status == SILC_SKE_STATUS_BAD_VERSION)			g_snprintf(buf, sizeof(buf),				   _("Failure: Version mismatch, upgrade your client"));		if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY)			g_snprintf(buf, sizeof(buf),				   _("Failure: Remote does not trust/support your public key"));		if (status == SILC_SKE_STATUS_UNKNOWN_GROUP)			g_snprintf(buf, sizeof(buf),				   _("Failure: Remote does not support proposed KE group"));		if (status == SILC_SKE_STATUS_UNKNOWN_CIPHER)			g_snprintf(buf, sizeof(buf),				   _("Failure: Remote does not support proposed cipher"));		if (status == SILC_SKE_STATUS_UNKNOWN_PKCS)			g_snprintf(buf, sizeof(buf),				   _("Failure: Remote does not support proposed PKCS"));		if (status == SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION)			g_snprintf(buf, sizeof(buf),				   _("Failure: Remote does not support proposed hash function"));		if (status == SILC_SKE_STATUS_UNKNOWN_HMAC)			g_snprintf(buf, sizeof(buf),				   _("Failure: Remote does not support proposed HMAC"));		if (status == SILC_SKE_STATUS_INCORRECT_SIGNATURE)			g_snprintf(buf, sizeof(buf), _("Failure: Incorrect signature"));		if (status == SILC_SKE_STATUS_INVALID_COOKIE)			g_snprintf(buf, sizeof(buf), _("Failure: Invalid cookie"));		/* Show the error on the progress bar.  A more generic error message		   is going to be showed to user after this in the silc_connected. */		purple_connection_update_progress(gc, buf, 2, 5);	}	if (protocol->protocol->type == SILC_PROTOCOL_CLIENT_CONNECTION_AUTH) {		SilcUInt32 err = SILC_PTR_TO_32(failure);		if (err == SILC_AUTH_FAILED)			g_snprintf(buf, sizeof(buf), _("Failure: Authentication failed"));		/* Show the error on the progress bar.  A more generic error message		   is going to be showed to user after this in the silc_connected. */		purple_connection_update_progress(gc, buf, 4, 5);	}}/* Asks whether the user would like to perform the key agreement protocol.   This is called after we have received an key agreement packet or an   reply to our key agreement packet. This returns TRUE if the user wants   the library to perform the key agreement protocol and FALSE if it is not   desired (application may start it later by calling the function   silc_client_perform_key_agreement). If TRUE is returned also the   `completion' and `context' arguments must be set by the application. */static boolsilc_key_agreement(SilcClient client, SilcClientConnection conn,		   SilcClientEntry client_entry, const char *hostname,		   SilcUInt16 port, SilcKeyAgreementCallback *completion,		   void **context){	silcpurple_buddy_keyagr_request(client, conn, client_entry, hostname, port);	*completion = NULL;	*context = NULL;	return FALSE;}/* Notifies application that file transfer protocol session is being   requested by the remote client indicated by the `client_entry' from   the `hostname' and `port'. The `session_id' is the file transfer   session and it can be used to either accept or reject the file   transfer request, by calling the silc_client_file_receive or   silc_client_file_close, respectively. */static voidsilc_ftp(SilcClient client, SilcClientConnection conn,	 SilcClientEntry client_entry, SilcUInt32 session_id,	 const char *hostname, SilcUInt16 port){	silcpurple_ftp_request(client, conn, client_entry, session_id,			     hostname, port);}/* Delivers SILC session detachment data indicated by `detach_data' to the   application.  If application has issued SILC_COMMAND_DETACH command   the client session in the SILC network is not quit.  The client remains   in the network but is detached.  The detachment data may be used later   to resume the session in the SILC Network.  The appliation is   responsible of saving the `detach_data', to for example in a file.   The detachment data can be given as argument to the functions   silc_client_connect_to_server, or silc_client_add_connection when   creating connection to remote server, inside SilcClientConnectionParams   structure.  If it is provided the client library will attempt to resume   the session in the network.  After the connection is created   successfully, the application is responsible of setting the user   interface for user into the same state it was before detaching (showing   same channels, channel modes, etc).  It can do this by fetching the   information (like joined channels) from the client library. */static voidsilc_detach(SilcClient client, SilcClientConnection conn,	    const unsigned char *detach_data, SilcUInt32 detach_data_len){	PurpleConnection *gc = client->application;	SilcPurple sg = gc->proto_data;	const char *file;	/* Save the detachment data to file. */	file = silcpurple_session_file(purple_account_get_username(sg->account));	g_unlink(file);	silc_file_writefile(file, (char *)detach_data, detach_data_len);}SilcClientOperations ops = {	silc_say,	silc_channel_message,	silc_private_message,	silc_notify,	silc_command,	silc_command_reply,	silc_connected,	silc_disconnected,	silc_get_auth_method,	silc_verify_public_key,	silc_ask_passphrase,	silc_failure,	silc_key_agreement,	silc_ftp,	silc_detach};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -