标题
    
    
        [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软件下载及使用技巧. 
    但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件. 
    验证问题说明申请入群原因即可.