标题
[c++/vc/ftp/vs2008] FileZilla_Server 的编译
clq
浏览(0) +
2009-06-09 10:02:52 发表
编辑
关键字:
其实只有 iputils.cpp 用到了 boost 实在是不值得,boost很不好用.自己用的话去掉好了,或者找一个类似的小库代替. -------------------------------------------------- 编译出来的东西也要安装 "vcredist_x86(Microsoft Visual C++ 2008 Redistributable Package (x86)).exe" 后才能运行.否则报 "由于应用程序配置不正确 应用程序未能启动。重新安装应用程序可能会纠正这个问题 2008" http://www.microsoft.com/downloads/details.aspx?FamilyID=9B2DA534-3E03-4391-8A4D-074B9F2BC1BF&displaylang=en
clq
用户信息是存在一个文件当中的. FileZilla Server.xml
clq
void CPermissions::ReadSettings() 读取用户权限,可以看到它是一次性全部读取所有用户信息的,所以是不适合大用户量的.
clq
对登录和用户信息部分进行改造可以让其兼容 apache ftp server 的 mysql 管理. //clq BOOL CPermissions::GetUser(CStdString username, CUser &userdata) const { forum_database f; const wchar_t * user_name = username.c_str(); std::string user_name2 = unicode_to_gbk(user_name); f.open_mysql_sql(std::string("select * from ftp_user2 where userid='") + user_name2 + std::string("' limit 1"), "id"); keys * key = f.get_first_line(); if (key != NULL) { std::string homedirectory = (*key)["homedirectory"]; std::string userpassword = (*key)["userpassword"]; std::string userpassword_plain = (*key)["userpassword_plain"]; //用户目录 userdata.homedir = homedirectory; //userdata. //-------------------------------------------------- BOOL bGotHome = FALSE; t_directory dir; dir.dir = homedirectory; dir.dir.Replace('/', '\\'); dir.dir.TrimRight('\\'); //if (dir.dir == _T("")) // continue; dir.bFileRead = TRUE; dir.bFileWrite = TRUE; dir.bFileDelete = TRUE; dir.bFileAppend = TRUE; dir.bDirCreate = TRUE; dir.bDirDelete = TRUE; dir.bDirList = TRUE; dir.bDirSubdirs = TRUE; dir.bIsHome = TRUE; //dir.bAutoCreate = TRUE; //Avoid multiple home dirs if (dir.bIsHome) if (!bGotHome) bGotHome = TRUE; else dir.bIsHome = FALSE; //userdata.SpeedLimits userdata.permissions.push_back(dir); //-------------------------------------------------- return TRUE; } // Get user from username return FALSE; }
clq
登录部分的改造比较复杂点.需要将 //std::map CServerThread::m_userIPs; 注释然后去掉相关的代码.因为这里检查 ip 和登录太紧了我去掉了,不然有崩溃.然后更改登录函数如下: //clq modify BOOL CControlSocket::DoUserLogin(LPCTSTR password, bool skipPass /*=false*/) { //return DoUserLogin_old(password, skipPass); //-------------------------------------------------- /* //1、初始化mysql MYSQL *mysql = mysql_init(NULL); //2、连接数据库 //mysql_real_connect(mysql, "172.16.252.244", USER, PASSWORD, DATABASE, 0, NULL, 0); mysql_real_connect(mysql, "172.16.252.244", "root", "root", "hzdb", 0, NULL, 0); //1、设置查询返回数据的字符集 mysql_query(mysql, "set names gbk"); //3、执行数据库操作 mysql_query(mysql, "select * from ftp_user2 where userid='" + m_status.user + "' limit 1"); //1、存储操作结果集 MYSQL_RES *mysql_res = mysql_store_result(mysql); //2、获取结果集中一行记录 MYSQL_ROW *mysql_row = mysql_fetch_row(mysql_res); //3、通过指针获取记录中的值 //指针mysql_row[0]指向的就是该条记录第一列(查询的第一个字段)的值 4、释放存储结果集 mysql_free_result(mysql_res); //4、关闭mysql mysql_close(mysql); */ forum_database f; const wchar_t * user_name = m_status.user.c_str(); std::string user_name2 = unicode_to_gbk(user_name); f.open_mysql_sql(std::string("select * from ftp_user2 where userid='") + user_name2 + std::string("' limit 1"), "id"); keys * key = f.get_first_line(); if (key != NULL) { std::string homedirectory = (*key)["homedirectory"]; std::string userpassword = (*key)["userpassword"]; std::string userpassword_plain = (*key)["userpassword_plain"]; if (str_eq(userpassword_plain, unicode_to_gbk(password))) {//登录成功 //用户目录 //m_CurrentServerDir = m_pOwner->m_pPermissions->GetHomeDir(m_status.user); //m_CurrentServerDir = homedirectory; m_CurrentServerDir = "/"; } else { Send(_T("530 Login or password incorrect!")); return FALSE; } } //-------------------------------------------------- CStdString ip; unsigned int nPort; SOCKADDR_IN sockAddr; memset(&sockAddr, 0, sizeof(sockAddr)); int nSockAddrLen = sizeof(sockAddr); BOOL bResult = GetPeerName((SOCKADDR*)&sockAddr, &nSockAddrLen); if (bResult) { nPort = ntohs(sockAddr.sin_port); #ifdef _UNICODE ip = ConvFromLocal(inet_ntoa(sockAddr.sin_addr)); #else ip = inet_ntoa(sockAddr.sin_addr); #endif } //用户目录 //m_CurrentServerDir = m_pOwner->m_pPermissions->GetHomeDir(m_status.user); if (m_CurrentServerDir == _T("")) { Send(_T("550 Could not get home dir!")); ForceClose(-1); return FALSE; } m_status.ip = ip; m_status.loggedon = TRUE; GetSystemTime(&m_LastTransferTime); //创建用户目录 //m_pOwner->m_pPermissions->AutoCreateDirs(m_status.user); t_connectiondata_changeuser *conndata = new t_connectiondata_changeuser; t_connop *op = new t_connop; op->data = conndata; op->op = USERCONTROL_CONNOP_CHANGEUSER; op->userid = m_userid; conndata->user = m_status.user; m_pOwner->SendNotification(FSM_CONNECTIONDATA, (LPARAM)op); return TRUE; }
clq
forum_database 是我写的一个私有类,大家要用的话直接改成访问 mysql 的代码就行了,很简单的,用文件也行.
clq
如何调试Windows服务? 楼主raulzzy()2005-11-01 15:56:50 在 .NET技术 / C# 提问 最近一直在做Windows服务,但是觉得调试相当麻烦,每次都是看系统日志,这样反复每次都要重新注册,比较麻烦,有没有可以跟踪到服务的调试?请高手指教?听说进程调试可以,但小弟不懂?高手多多帮忙 问题点数:20、回复次数:20Top 15 楼qzj(SoldierQ)回复于 2005-11-03 17:33:53 得分 0 先要注册你的服务,并启动 在VS.NET中,打开你的服务源代码,选 工具-〉调试进程(Ctrl+Alt+P),如果你服务注册并运行正常,可以在列表中看到,选择你的服务名称,点“附加”,然后关闭这个窗口就可以了。 接下来就可以像调试一般程序一样调试了 断点什么的都可以 -------------------------------------------------- vs 2008 下是 "工具 -> 附加到进程(Ctrl+Alt+P)" 功能还是很强的.
clq
它大量用了 CStdString 的类,要做这样的转换. const wchar_t * user_name = m_status.user.c_str(); std::string user_name2 = unicode_to_gbk(user_name);
clq
FileZilla_Server 支持开关 utf8 的,但它似乎对返回的文件名统一使用 utf8 字符集.所以我用 delphi7 的 idftp 控件时就是取的时候用 gbk 下载的时候用 utf8 . -------------------------------------------------- FileZilla_Server 代码: else if (args == _T("UTF8 ON")) { m_useUTF8 = true; Send(_T("200 UTF8 mode enabled")); } else if (args == _T("UTF8 OFF")) { m_useUTF8 = false; Send(_T("200 UTF8 mode disabled")); } -------------------------------------------------- d7 代码: function TForm_main.ftpDecode(const S: UTF8String): String; begin result := s; result := UTF8Decode(s); end; function TForm_main.ftpEncode(const S: UTF8String): WideString; begin result := s; //result := UTF8Encode(s);//FileZilla_Server 的命令很怪异,提交文件名可以用本地 gbk 编码,返回的却是 utf8 的 end;
clq
FileZilla_Server 工程项目是 unicode 的,所以很是有一些麻烦.
clq
[图片]
"421 No-transfer-time exceeded" 上传大文件时会有这个错误,这个是服务器强制关闭的,意思是多久没有对话消息后关闭,这对于有些客户端来说会关闭正在传送的文件通道 -- 比如 indy 的 ftp 控件,不过 FileZilla 自己的客户端不会. -------------------------------------------------- 其实现代码如下: ForceClose(2); if (elapsed>(nNoTransferTimeout*10000000)) { ForceClose(2); return; } 不过要改变这一行为是不用修改源码的,可在如图的管理界面上修改即可.
NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.