使用libpurple函数库接入服务器

代码;

#define CUSTOM_USER_DIRECTORY  "/dev/null"					// 定义用户目录
#define CUSTOM_PLUGIN_PATH ""							// 定义插件目录
#define PLUGIN_SAVE_PREF "/purple/nullclient/plugins/saved"		// 定义插件头目录
#define UI_ID "nullclient"										// 定义用户接口ID
#include <purple.h>											// 包含libpurple库
#include <glib.h>											// 包含GLib库
#include <signal.h>
#include <string.h>
#include <unistd.h>
#define PURPLE_GLIB_READ_COND  (G_IO_IN | G_IO_HUP | G_IO_ERR)		// 定义GLib读成员
#define PURPLE_GLIB_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL)// 定义GLib写成员
typedef struct _PurpleGLibIOClosure {							// 该结构用于作为回调函数参数PurpleInputFunction function;								// 函数名guint result;												// 返回结果gpointer data;											// 数据参数
} PurpleGLibIOClosure;static void purple_glib_io_destroy(gpointer data)					// 该函数用于清除数据
{g_free(data);											// 释放data所指向的内存空间
}static gboolean purple_glib_io_invoke(GIOChannel *source,GIOCondition condition,gpointer data)				// 调用GLib输入输出接口
{PurpleGLibIOClosure *closure = data;							// 创建libpurple输入输出终止符PurpleInputCondition purple_cond = 0;							// 创建libpurple输入条件对象if (condition & PURPLE_GLIB_READ_COND)					// 判断条件是否为读取purple_cond |= PURPLE_INPUT_READ;					// 将libpurple输入条件对象设为读取if (condition & PURPLE_GLIB_WRITE_COND)					// 判断条件是否为写入purple_cond |= PURPLE_INPUT_WRITE;					// 将libpurple输入条件对象设为写入closure->function(closure->data, g_io_channel_unix_get_fd(source),purple_cond);										// 调用回调函数执行输入输出操作return TRUE;
}static guint glib_input_add(gint fd,PurpleInputCondition condition,PurpleInputFunction function,gpointer data)						// 加入一个GLib输入接口
{PurpleGLibIOClosure *closure = g_new0(PurpleGLibIOClosure, 1);	// 创建libpurple输入输出终止符GIOChannel *channel;										// 声明GLib通道对象GIOCondition cond = 0;									// 声明GLib输入输出条件closure->function = function;								// 定义回调函数closure->data = data;										// 定义数据指针if (condition & PURPLE_INPUT_READ)						// 判断条件是否为读取cond |= PURPLE_GLIB_READ_COND; 					// 将libpurple输入条件对象设为读取if (condition & PURPLE_INPUT_WRITE) 						// 判断条件是否为写入cond |= PURPLE_GLIB_WRITE_COND; 					// 将libpurple输入条件对象设为写入channel = g_io_channel_unix_new(fd);							// 创建GLib通道closure->result = g_io_add_watch_full(channel,G_PRIORITY_DEFAULT,cond,purple_glib_io_invoke,closure,purple_glib_io_destroy);		// 设置通道中的回调函数g_io_channel_unref(channel);								// 将通道对象托管return closure->result;
}static PurpleEventLoopUiOps glib_eventloops = 					// 定义GLib事件循环
{g_timeout_add,											// 超时处理g_source_remove,										// 源删除glib_input_add,											// 添加输入管道g_source_remove,										// 源删除NULL,
#if GLIB_CHECK_VERSION(2,14,0)								// 判断GLib版本是否为2.14.0g_timeout_add_seconds,									// 超时秒数
#elseNULL,
#endifNULL
};static void null_write_conv(PurpleConversation *conv,				// 会话标识符const char *who,						// 好友IDconst char *alias,						// 昵称const char *message,					// 消息PurpleMessageFlags flags,				// 消息类型time_t mtime)							// 发送时间
{const char *name;										// 用于保存好友名称if (alias && *alias)										// 判断存在好友昵称name = alias;											// 将好友名称设为昵称else if (who && *who)										// 判断好友ID存在name = who;											// 将好友名称设为好友IDelsename = NULL;printf("(%s) %s %s: %s\n", purple_conversation_get_name(conv),purple_utf8_strftime("(%H:%M:%S)", localtime(&mtime)),name, message);									// 输出会话
}static PurpleConversationUiOps null_conv_uiops = 					// 定义会话UI选项
{NULL,													// 创建会话NULL,													// 清除会话NULL,													// 输入聊天消息NULL,													// 输入通信信息null_write_conv,											// 写入会话NULL,													// 添加联系人NULL,													// 修改联系人名NULL,													// 删除联系人NULL,													// 更新联系人姓名NULL,													// 当前时间NULL,													// 获得焦点NULL,													// 增加表情NULL,													// 输入表情NULL,													// 关闭表情NULL,													// 发送确认
};static void null_ui_init(void)									// 初始化用户接口
{purple_conversations_set_ui_ops(&null_conv_uiops);				// 使用会话UI选项初始化用户接口
}static PurpleCoreUiOps null_core_uiops = 						// 定义核心用户接口选项
{NULL, NULL, null_ui_init, NULL
};static void init_libpurple(void)									// 初始化libpurple
{purple_util_set_user_dir(CUSTOM_USER_DIRECTORY);			// 设置用户目录purple_debug_set_enabled(FALSE);							// 不接受调试信息purple_core_set_ui_ops(&null_core_uiops);						// 设置核心用户接口选项purple_eventloop_set_ui_ops(&glib_eventloops);					// 设置GLib事件循环purple_plugins_add_search_path(CUSTOM_PLUGIN_PATH);		// 添加搜索插件路径if (!purple_core_init(UI_ID)) {								// 初始化libpurple环境fprintf(stderr,"libpurple初始化失败!\n");abort();}purple_set_blist(purple_blist_new());							// 读取联系人列表purple_blist_load();purple_prefs_load();										// 读取用户配置purple_plugins_load_saved(PLUGIN_SAVE_PREF);				// 加载插件purple_pounces_load();									// 完成初始化
}static void signed_on(PurpleConnection *gc, gpointer null)			// 接收libpurple信号
{PurpleAccount *account = purple_connection_get_account(gc);		// 读取本地账户信息printf("Account connected: %s %s\n", account->username, account->protocol_id);
}static void connect_to_signals_for_demonstration_purposes_only(void)	// 对信号进行过滤
{static int handle;											// 用于保存句柄purple_signal_connect(purple_connections_get_handle(), "signed-on", &handle,PURPLE_CALLBACK(signed_on), NULL);				// 设置过滤器和回调函数
}int main(int argc, char *argv[])
{GList *iter;												// 声明GList链表节点int i, num;												// 用户循环控制变量GList *names = NULL;										// 声明GList链表const char *prpl;char name[128];											// 用于保存用户名char *password;											// 用于保存密码GMainLoop *loop = g_main_loop_new(NULL, FALSE);			// 创建一个主循环PurpleAccount *account;									// 定义libpurple账户PurpleSavedStatus *status;									// 定义libpurple状态char *res;												// 用于用户输入交互signal(SIGCHLD, SIG_IGN);								// 设置libpurple信号init_libpurple();											// 初始化libpurple库printf("libpurple初始化成功。\n");iter = purple_plugins_get_protocols();							// 通过插件获得即时通信协议for (i = 0; iter; iter = iter->next) {								// 遍历GList链表PurplePlugin *plugin = iter->data;							// 取得libpurple插件信息PurplePluginInfo *info = plugin->info;if (info && info->name) {printf("\t%d: %s\n", i++, info->name);						// 输出libpurple插件名names = g_list_append(names, info->id);					// 将libpurple插件名加入GList链表}}printf("请选择一个协议 [0-%d]: ", i-1);							// 提示用户选择一个IM协议res = fgets(name, sizeof(name), stdin);							// 从终端读取用户输入if (!res) {fprintf(stderr, "协议选择不正确");abort();}sscanf(name, "%d", &num);									// 输入协议编号prpl = g_list_nth_data(names, num);							// 在GList链表中读取相关协议信息printf("用户名: ");											// 提述输入用户名res = fgets(name, sizeof(name), stdin);							// 从终端读取用户输入if (!res) {fprintf(stderr, "无法读取用户名");abort();}name[strlen(name) - 1] = 0;account = purple_account_new(name, prpl);					// 创建账户password = getpass("请输入密码: ");purple_account_set_password(account, password);				// 获取用户密码purple_account_set_enabled(account, UI_ID, TRUE);				// 激活账户status = purple_savedstatus_new(NULL, PURPLE_STATUS_AVAILABLE);	// 设置当前状态为可用purple_savedstatus_activate(status);							// 设置用户状态为“活动”connect_to_signals_for_demonstration_purposes_only();			// 接收IM服务器传来的消息g_main_loop_run(loop);									// 启动GLib主循环return 0;
}

编译;

运行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/350401.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

秋招突击——第四弹——Java的SSN框架快速入门——Maven

文章目录 引言Maven分模块开发与设计分模块开发的过程 依赖管理可选依赖与排除依赖 继承与聚合聚合继承 属性和版本管理属性扩大集中管理的范围版本管理 多环境开发多环境开发 私服简介安装私服资源操作流程分析上传和下载 总结 引言 前一个部分花了太多时间&#xff0c;后续得…

IBM,开始构建以量子为中心的超级计算机

6月6日&#xff0c;IBM与Pasqal宣布了一项重大合作!IBM和Pasqal打算合作开发一种以量子为中心的超级计算的通用方法并促进化学和材料科学的应用研究。IBM和Pasqal将与高性能计算领域的领先机构合作&#xff0c;为以量子为中心的超级计算奠定基础——将量子计算与先进的经典计算…

理解Python的元类

1.type()函数 type 函数是一个内置函数&#xff0c;用来获取一个对象的类型。它可以接受一个参数&#xff0c;返回这个参数的数据类型。type也可以用来创建类&#xff0c;type就是元类 x333 list["ab"] tuple (1, "a", True, 3.14) dict {name: Alice,…

机器学习实验------PCA

目录 一、介绍 二、算法流程 &#xff08;1&#xff09;数据中心化 &#xff08;2&#xff09;计算协方差矩阵 &#xff08;3&#xff09;特征值分解 &#xff08;4&#xff09;选择特征 三、运行结果展示 四、实验中遇到的问题 五、PCA的优缺点 优点&#xff1a; 缺点…

广东启动“粤企质量提升工作会议” 着力提升产品和服务质量

6月5日,由广东质量峰会组委会牵头,联合相关质量、信用、打假和检验检测等部门共同举办的“粤企质量提升工作会议”在广州正式启动。本次工作会议旨在贯彻落实《质量强国建设纲要》及《广东省质量强省建设纲要》精神,深入开展全民质量行动,弘扬企业家和工匠精神,营造政府重视质量…

如何解决mfc100u.dll丢失问题,关于mfc100u.dll丢失的多种解决方法

在计算机使用过程中&#xff0c;我们常常会遇到一些错误提示&#xff0c;其中之一就是“计算显示缺失mfc100u.dll”。这个问题可能会影响到我们的正常使用&#xff0c;因此了解它的原因、表现以及解决方法是非常重要的。小编将详细介绍计算显示缺失mfc100u.dll的问题&#xff0…

软件工程期末复习题

目录 选择 判断 选择 下列说法中正确的是 ( B )。 A、20 世纪50 年代提出了软件工程的概念摇 B、20 世纪60 年代提出了软件工程的概念 C、20 世纪70 年代出现了客户端/ 服务器技术 D、20 世纪80 年代软件工程学科达到成熟 软件危机的主要原因是 ( D )。 A、软件工具落后…

数据预处理 #数据挖掘 #python

数据分析中的预处理步骤是数据分析流程中的重要环节&#xff0c;它的目的是清洗、转换和整理原始数据&#xff0c;以便后续的分析能够准确、有效。预处理通常包括以下几个关键步骤&#xff1a; 数据收集&#xff1a;确定数据来源&#xff0c;可能是数据库、文件、API或网络抓取…

【C++】stack、queue和deque的使用

&#x1f497;个人主页&#x1f497; ⭐个人专栏——C学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 目录 导读 一、stack 1. stack介绍 2. stack使用 二、queue 1. queue介绍 2. queue使用 三、deque 1. deque介绍 2. deque的…

<Linux>进程

进程 文章目录 进程PCBpid与ppidfork系统调用进程状态孤儿进程状态优先级环境变量进程地址空间虚拟地址 最直观的表示&#xff1a;启动一个软件&#xff0c;本质就是启动一个进程 PCB PCB是Process Control Block的简称&#xff0c;是用来描述进程状态信息的数据结构。 进程运…

uniapp开发微信小程序问题汇总

1. 自定义校验规则validateFunction失效 2. 微信小程序不支持<Br>换行 在 <text></text> 标签中使用\n(必须 text 标签&#xff0c;view 标签无效 ) 3. 微信小程序无法使用本地静态资源图片的解决方法 (1) 将图片上传到服务器&#xff0c;小程序访问该图片…

springboot与flowable(9):候选人组

act_id_xxx相关表存储了所有用户和组的数据。 一、维护用户信息 Autowiredprivate IdentityService identityService;/*** 维护用户*/Testvoid createUser() {User user identityService.newUser("zhangsan");user.setEmail("zhangsanqq.com");user.setF…

Java_异常

什么是异常&#xff1f; 异常就是代表程序出现问题 Error&#xff1a;代表系统级别的错误&#xff08;属于严重问题&#xff09;&#xff0c;也就是说系统一旦出现问题&#xff0c;sun公司会把这些问题封装成Error对象给出来&#xff0c;说白了&#xff0c;Error是给sun公司自…

02_01_SpringMVC初识

一、回顾MVC三层架构 1、什么是MVC三层 MVC是 模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;、控制器&#xff08;Controller&#xff09;的简写&#xff0c;是一种软件设计规范。主要作用是降低视图与业务逻辑之间的双向耦合&#xff0c;它不是一种…

android 播放视频

播放视频文件 新建一个activity_main.xml文件&#xff0c;文件中放置了3个按钮&#xff0c;分别用于控制视频的播放、暂停和重新播放。另外在按钮的下面又放置了一个VideoView&#xff0c;稍后的视频就将在这里显示。 <LinearLayout xmlns:android"http://schemas.an…

大模型应用:LangChain-Golang核心模块使用

1.简介 LangChain是一个开源的框架&#xff0c;它提供了构建基于大模型的AI应用所需的模块和工具。它可以帮助开发者轻松地与大型语言模型(LLM)集成&#xff0c;实现文本生成、问答、翻译、对话等任务。LangChain的出现大大降低了AI应用开发的门槛&#xff0c;使得任何人都可以…

爬虫可以不必自己写,使用ChatGPT编写抓取电影评论数据脚本

经常去新华书店看看有没有什么新书上架&#xff0c;还是更新挺及时的&#xff0c;可以反映新的技术趋势。这不&#xff0c;最近就看到了这本《巧用 ChatGPT 快速搞定数据分析》&#xff0c;作者是个大牛&#xff0c;第一次看到prompt可以这么写&#xff0c;得写这么长&#xff…

网络协议,OSI,简单通信,IP和mac地址

认识协议 1.讲故事 2004年&#xff0c;小明因为给他爹打电话&#xff08;座机&#xff09;费用太贵&#xff0c;所以约定一种信号&#xff0c;响一次是报平安&#xff0c;响两次是要钱&#xff0c;响三次才需要接通。 2.概念 协议&#xff1a;是一种约定&#xff0c;这种约…

14. RTCP 协议

RTCP 协议概述 RTCP&#xff08;Real-time Transport Control Protocol 或 RTP Control Protocol 或简写 RTCP&#xff09;&#xff0c;实时传输控制协议&#xff0c;是实时传输协议&#xff08;RTP&#xff09;的一个姐妹协议。 注&#xff1a;RTP 协议和 RTP 控制协议&#…

新版嘎嘎快充互联互通系统配置文档

宝塔环境配置 登录宝塔账号&#xff0c;安装nginx、mysql5.7、php7.2、supervisor、redisphp安装扩展&#xff1a; 1&#xff09;安装swooleloader72 将嘎嘎官方提供的swoole_loader_72_nts.so文件上传到 /www/server/php/72/lib/php/extensions/no-debug-non-zts-20170718…