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

📄 simple.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		purple_debug(PURPLE_DEBUG_MISC, "simple", "received a incomplete sip msg: %s\n", conn->inbuf);	}}static void simple_udp_process(gpointer data, gint source, PurpleInputCondition con) {	PurpleConnection *gc = data;	struct simple_account_data *sip = gc->proto_data;	struct sipmsg *msg;	int len;	time_t currtime;	static char buffer[65536];	if((len = recv(source, buffer, sizeof(buffer) - 1, 0)) > 0) {		buffer[len] = '\0';		purple_debug_info("simple", "\n\nreceived - %s\n######\n%s\n#######\n\n", ctime(&currtime), buffer);		msg = sipmsg_parse_msg(buffer);		if(msg) process_input_message(sip, msg);	}}static void simple_input_cb(gpointer data, gint source, PurpleInputCondition cond){	PurpleConnection *gc = data;	struct simple_account_data *sip = gc->proto_data;	int len;	struct sip_connection *conn = connection_find(sip, source);	if(!conn) {		purple_debug_error("simple", "Connection not found!\n");		return;	}	if(conn->inbuflen < conn->inbufused + SIMPLE_BUF_INC) {		conn->inbuflen += SIMPLE_BUF_INC;		conn->inbuf = g_realloc(conn->inbuf, conn->inbuflen);	}	len = read(source, conn->inbuf + conn->inbufused, SIMPLE_BUF_INC - 1);	if(len < 0 && errno == EAGAIN)		return;	else if(len <= 0) {		purple_debug_info("simple", "simple_input_cb: read error\n");		connection_remove(sip, source);		if(sip->fd == source) sip->fd = -1;		return;	}	conn->inbufused += len;	conn->inbuf[conn->inbufused] = '\0';	process_input(sip, conn);}/* Callback for new connections on incoming TCP port */static void simple_newconn_cb(gpointer data, gint source, PurpleInputCondition cond) {	PurpleConnection *gc = data;	struct simple_account_data *sip = gc->proto_data;	struct sip_connection *conn;	int newfd = accept(source, NULL, NULL);	conn = connection_create(sip, newfd);	conn->inputhandler = purple_input_add(newfd, PURPLE_INPUT_READ, simple_input_cb, gc);}static void login_cb(gpointer data, gint source, const gchar *error_message) {	PurpleConnection *gc = data;	struct simple_account_data *sip;	struct sip_connection *conn;	if (!PURPLE_CONNECTION_IS_VALID(gc))	{		if (source >= 0)			close(source);		return;	}	if(source < 0) {		purple_connection_error(gc, _("Could not connect"));		return;	}	sip = gc->proto_data;	sip->fd = source;	conn = connection_create(sip, source);	sip->registertimeout = purple_timeout_add((rand()%100)+10*1000, (GSourceFunc)subscribe_timeout, sip);	do_register(sip);	conn->inputhandler = purple_input_add(sip->fd, PURPLE_INPUT_READ, simple_input_cb, gc);}static guint simple_ht_hash_nick(const char *nick) {	char *lc = g_utf8_strdown(nick, -1);	guint bucket = g_str_hash(lc);	g_free(lc);	return bucket;}static gboolean simple_ht_equals_nick(const char *nick1, const char *nick2) {	return (purple_utf8_strcasecmp(nick1, nick2) == 0);}static void simple_udp_host_resolved_listen_cb(int listenfd, gpointer data) {	struct simple_account_data *sip = (struct simple_account_data*) data;	sip->listen_data = NULL;	if(listenfd == -1) {		purple_connection_error(sip->gc, _("Could not create listen socket"));		return;	}	sip->fd = listenfd;	sip->listenport = purple_network_get_port_from_fd(sip->fd);	sip->listenfd = sip->fd;	sip->listenpa = purple_input_add(sip->fd, PURPLE_INPUT_READ, simple_udp_process, sip->gc);	sip->resendtimeout = purple_timeout_add(2500, (GSourceFunc) resend_timeout, sip);	sip->registertimeout = purple_timeout_add((rand()%100)+10*1000, (GSourceFunc)subscribe_timeout, sip);	do_register(sip);}static void simple_udp_host_resolved(GSList *hosts, gpointer data, const char *error_message) {	struct simple_account_data *sip = (struct simple_account_data*) data;	int addr_size;	sip->query_data = NULL;	if (!hosts || !hosts->data) {		purple_connection_error(sip->gc, _("Couldn't resolve host"));		return;	}	addr_size = GPOINTER_TO_INT(hosts->data);	hosts = g_slist_remove(hosts, hosts->data);	memcpy(&(sip->serveraddr), hosts->data, addr_size);	g_free(hosts->data);	hosts = g_slist_remove(hosts, hosts->data);	while(hosts) {		hosts = g_slist_remove(hosts, hosts->data);		g_free(hosts->data);		hosts = g_slist_remove(hosts, hosts->data);	}	/* create socket for incoming connections */	sip->listen_data = purple_network_listen_range(5060, 5160, SOCK_DGRAM,				simple_udp_host_resolved_listen_cb, sip);	if (sip->listen_data == NULL) {		purple_connection_error(sip->gc, _("Could not create listen socket"));		return;	}}static voidsimple_tcp_connect_listen_cb(int listenfd, gpointer data) {	struct simple_account_data *sip = (struct simple_account_data*) data;	sip->listen_data = NULL;	sip->listenfd = listenfd;	if(sip->listenfd == -1) {		purple_connection_error(sip->gc, _("Could not create listen socket"));		return;	}	purple_debug_info("simple", "listenfd: %d\n", sip->listenfd);	sip->listenport = purple_network_get_port_from_fd(sip->listenfd);	sip->listenpa = purple_input_add(sip->listenfd, PURPLE_INPUT_READ,			simple_newconn_cb, sip->gc);	purple_debug_info("simple", "connecting to %s port %d\n",			sip->realhostname, sip->realport);	/* open tcp connection to the server */	if (purple_proxy_connect(sip->gc, sip->account, sip->realhostname,			sip->realport, login_cb, sip->gc) == NULL) {		purple_connection_error(sip->gc, _("Couldn't create socket"));	}}static void srvresolved(PurpleSrvResponse *resp, int results, gpointer data) {	struct simple_account_data *sip;	gchar *hostname;	int port;	sip = data;	sip->srv_query_data = NULL;	port = purple_account_get_int(sip->account, "port", 0);	/* find the host to connect to */	if(results) {		hostname = g_strdup(resp->hostname);		if(!port)			port = resp->port;		g_free(resp);	} else {		if(!purple_account_get_bool(sip->account, "useproxy", FALSE)) {			hostname = g_strdup(sip->servername);		} else {			hostname = g_strdup(purple_account_get_string(sip->account, "proxy", sip->servername));		}	}	sip->realhostname = hostname;	sip->realport = port;	if(!sip->realport) sip->realport = 5060;	/* TCP case */	if(!sip->udp) {		/* create socket for incoming connections */		sip->listen_data = purple_network_listen_range(5060, 5160, SOCK_STREAM,					simple_tcp_connect_listen_cb, sip);		if (sip->listen_data == NULL) {			purple_connection_error(sip->gc, _("Could not create listen socket"));			return;		}	} else { /* UDP */		purple_debug_info("simple", "using udp with server %s and port %d\n", hostname, port);		sip->query_data = purple_dnsquery_a(hostname, port, simple_udp_host_resolved, sip);		if (sip->query_data == NULL) {			purple_connection_error(sip->gc, _("Could not resolve hostname"));		}	}}static void simple_login(PurpleAccount *account){	PurpleConnection *gc;	struct simple_account_data *sip;	gchar **userserver;	gchar *hosttoconnect;	const char *username = purple_account_get_username(account);	gc = purple_account_get_connection(account);	if (strpbrk(username, " \t\v\r\n") != NULL) {		gc->wants_to_die = TRUE;		purple_connection_error(gc, _("SIP screen names may not contain whitespaces or @ symbols"));		return;	}	gc->proto_data = sip = g_new0(struct simple_account_data, 1);	sip->gc = gc;	sip->account = account;	sip->registerexpire = 900;	sip->udp = purple_account_get_bool(account, "udp", FALSE);	/* TODO: is there a good default grow size? */	if(!sip->udp)		sip->txbuf = purple_circ_buffer_new(0);	userserver = g_strsplit(username, "@", 2);	purple_connection_set_display_name(gc, userserver[0]);	sip->username = g_strdup(userserver[0]);	sip->servername = g_strdup(userserver[1]);	sip->password = g_strdup(purple_connection_get_password(gc));	g_strfreev(userserver);	sip->buddies = g_hash_table_new((GHashFunc)simple_ht_hash_nick, (GEqualFunc)simple_ht_equals_nick);	purple_connection_update_progress(gc, _("Connecting"), 1, 2);	/* TODO: Set the status correctly. */	sip->status = g_strdup("available");	if(!purple_account_get_bool(account, "useproxy", FALSE)) {		hosttoconnect = g_strdup(sip->servername);	} else {		hosttoconnect = g_strdup(purple_account_get_string(account, "proxy", sip->servername));	}	sip->srv_query_data = purple_srv_resolve("sip",			sip->udp ? "udp" : "tcp", hosttoconnect, srvresolved, sip);	g_free(hosttoconnect);}static void simple_close(PurpleConnection *gc){	struct simple_account_data *sip = gc->proto_data;	if(sip) {		/* unregister */		do_register_exp(sip, 0);		connection_free_all(sip);		if (sip->query_data != NULL)			purple_dnsquery_destroy(sip->query_data);		if (sip->srv_query_data != NULL)			purple_srv_cancel(sip->srv_query_data);		if (sip->listen_data != NULL)			purple_network_listen_cancel(sip->listen_data);		g_free(sip->servername);		g_free(sip->username);		g_free(sip->password);		g_free(sip->registrar.nonce);		g_free(sip->registrar.opaque);		g_free(sip->registrar.target);		g_free(sip->registrar.realm);		g_free(sip->registrar.digest_session_key);		g_free(sip->proxy.nonce);		g_free(sip->proxy.opaque);		g_free(sip->proxy.target);		g_free(sip->proxy.realm);		g_free(sip->proxy.digest_session_key);		if(sip->txbuf)			purple_circ_buffer_destroy(sip->txbuf);		g_free(sip->realhostname);		if(sip->listenpa) purple_input_remove(sip->listenpa);		if(sip->tx_handler) purple_input_remove(sip->tx_handler);		if(sip->resendtimeout) purple_timeout_remove(sip->resendtimeout);		if(sip->registertimeout) purple_timeout_remove(sip->registertimeout);	}	g_free(gc->proto_data);	gc->proto_data = NULL;}/* not needed since privacy is checked for every subscribe */static void dummy_add_deny(PurpleConnection *gc, const char *name) {}static void dummy_permit_deny(PurpleConnection *gc) {}static PurplePluginProtocolInfo prpl_info ={	0,	NULL,					/* user_splits */	NULL,					/* protocol_options */	NO_BUDDY_ICONS,			/* icon_spec */	simple_list_icon,		/* list_icon */	NULL,					/* list_emblems */	NULL,					/* status_text */	NULL,					/* tooltip_text */	simple_status_types,	/* away_states */	NULL,					/* blist_node_menu */	NULL,					/* chat_info */	NULL,					/* chat_info_defaults */	simple_login,			/* login */	simple_close,			/* close */	simple_im_send,			/* send_im */	NULL,					/* set_info */	simple_typing,			/* send_typing */	NULL,					/* get_info */	simple_set_status,		/* set_status */	NULL,					/* set_idle */	NULL,					/* change_passwd */	simple_add_buddy,		/* add_buddy */	NULL,					/* add_buddies */	simple_remove_buddy,	/* remove_buddy */	NULL,					/* remove_buddies */	dummy_add_deny,			/* add_permit */	dummy_add_deny,			/* add_deny */	dummy_add_deny,			/* rem_permit */	dummy_add_deny,			/* rem_deny */	dummy_permit_deny,		/* set_permit_deny */	NULL,					/* join_chat */	NULL,					/* reject_chat */	NULL,					/* get_chat_name */	NULL,					/* chat_invite */	NULL,					/* chat_leave */	NULL,					/* chat_whisper */	NULL,					/* chat_send */	simple_keep_alive,		/* keepalive */	NULL,					/* register_user */	NULL,					/* get_cb_info */	NULL,					/* get_cb_away */	NULL,					/* alias_buddy */	NULL,					/* group_buddy */	NULL,					/* rename_group */	NULL,					/* buddy_free */	NULL,					/* convo_closed */	NULL,					/* normalize */	NULL,					/* set_buddy_icon */	NULL,					/* remove_group */	NULL,					/* get_cb_real_name */	NULL,					/* set_chat_topic */	NULL,					/* find_blist_chat */	NULL,					/* roomlist_get_list */	NULL,					/* roomlist_cancel */	NULL,					/* roomlist_expand_category */	NULL,					/* can_receive_file */	NULL,					/* send_file */	NULL,					/* new_xfer */	NULL,					/* offline_message */	NULL,					/* whiteboard_prpl_ops */	simple_send_raw,		/* send_raw */	NULL,					/* roomlist_room_serialize */	/* padding */	NULL,	NULL,	NULL,	NULL};static PurplePluginInfo info ={	PURPLE_PLUGIN_MAGIC,	PURPLE_MAJOR_VERSION,	PURPLE_MINOR_VERSION,	PURPLE_PLUGIN_PROTOCOL,                             /**< type           */	NULL,                                             /**< ui_requirement */	0,                                                /**< flags          */	NULL,                                             /**< dependencies   */	PURPLE_PRIORITY_DEFAULT,                            /**< priority       */	"prpl-simple",                                    /**< id             */	"SIMPLE",                                         /**< name           */	VERSION,                                          /**< version        */	N_("SIP/SIMPLE Protocol Plugin"),                 /**  summary        */	N_("The SIP/SIMPLE Protocol Plugin"),             /**  description    */	"Thomas Butter <butter@uni-mannheim.de>",         /**< author         */	PURPLE_WEBSITE,                                     /**< homepage       */	NULL,                                             /**< load           */	NULL,                                             /**< unload         */	NULL,                                             /**< destroy        */	NULL,                                             /**< ui_info        */	&prpl_info,                                       /**< extra_info     */	NULL,	NULL,	/* padding */	NULL,	NULL,	NULL,	NULL};static void _init_plugin(PurplePlugin *plugin){	PurpleAccountUserSplit *split;	PurpleAccountOption *option;	split = purple_account_user_split_new(_("Server"), "", '@');	prpl_info.user_splits = g_list_append(prpl_info.user_splits, split);	option = purple_account_option_bool_new(_("Publish status (note: everyone may watch you)"), "dopublish", TRUE);	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);	option = purple_account_option_int_new(_("Connect port"), "port", 0);	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);	option = purple_account_option_bool_new(_("Use UDP"), "udp", FALSE);	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);	option = purple_account_option_bool_new(_("Use proxy"), "useproxy", FALSE);	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);	option = purple_account_option_string_new(_("Proxy"), "proxy", "");	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);	option = purple_account_option_string_new(_("Auth User"), "authuser", "");	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);	option = purple_account_option_string_new(_("Auth Domain"), "authdomain", "");	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);}PURPLE_INIT_PLUGIN(simple, _init_plugin, info);

⌨️ 快捷键说明

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