Esempio n. 1
0
bool SFtpReader::Copy(	Selection& tSelection, 		// remote
						const string& sTargetPath, 	// local
						Selection*	pSelection )	
{
	string			sCurName, sTargetPathTmp, sTargetPathTmp2;
	string			sSourceName, sTargetName;
	vector<File*>	vFiles;

	ullong	uFileSize = tSelection.CalcSize();
	uint	uSize = tSelection.GetSize();
	
	string 	sSize = toregular(uSize), sRestSize;

	bool	bSkipAll = false, bOverwriteAll = false;
	ullong	uLastSize = 0, uViewCount=1, uPsize=0, uCsize = 0;
	
	struct stat src_stat, tar_stat;

	int	nBufSize = g_tCfg.GetValueNum("SSH", "DefBufSize", 8196);

	char	buf[nBufSize];	// reading byte 

	vFiles = tSelection.GetData();

	if (sTargetPath.size() == 0)
		sTargetPathTmp2 = _sCurPath;
	else
		sTargetPathTmp2 = sTargetPath;

	CommonProgress	tProgress(	_("Copy"), (_("To ") + sTargetPathTmp2).c_str(), true);
	
	if (pSelection != NULL)
	{
		pSelection->Clear();
		pSelection->SetSelectPath(sTargetPathTmp2);
	}

	tProgress.Start();

	string sSourcePath = tSelection.GetSelectPath();
	
	LOG_WRITE("Copy sTargetPath [%s] [%s] [%s]", sTargetPath.c_str(), _sCurPath.c_str(), sTargetPathTmp2.c_str());

	// 파일 복사
	for (int n=0; n<(int)vFiles.size(); n++)
	{
		File*	pFile = vFiles[n];
		bool	bOverwrite = false;
		
		// 파일 이름이 없을경우 continue
		if (!pFile) continue;

		// 소스 이름과 타겟 이름 정하기	
		sSourceName = pFile->sFullName;
		sTargetName = 	sTargetPathTmp2 + 
						ChgCurLocale( pFile->sFullName.substr(sSourcePath.size()) );

		LIBSSH2_SFTP_ATTRIBUTES 	tAttr;
		if (libssh2_sftp_stat((LIBSSH2_SFTP*)_pSessionSFtp, (char*)sSourceName.c_str(), &tAttr) == -1)
		{
			// 소스가 없다니.. 참
			String	sMsg; string sErrMsg = GetLastErrMsg();
			sMsg.Append(_("File access error (%s), continue? !!! "), pFile->sName.c_str());
			if (!sErrMsg.empty()) sMsg.Append("[%s]", sErrMsg.c_str());
			tProgress.End();
			if (YNBox(_("Error"), sMsg.c_str(), false) == false) break;
			tProgress.Start();
			continue;
		}

		LOG_WRITE("SFtpReader Copy sTargetName 1 [%s] [%s] [%s] [%d]", 
					sSourceName.c_str(), sTargetName.c_str(), _sCurPath.c_str(), tAttr.filesize);
		
		String	sCount, sCount2;
		sCount.Printf("%s/%s", toregular(uViewCount).c_str(), sSize.c_str());

		tProgress.setLeftStr(pFile->sName.c_str());
		tProgress.setRightStr2(sCount.c_str());
		
		if (stat(sTargetName.c_str(), &tar_stat)!=-1)
		{
			if (bSkipAll) continue;
			else if (bOverwriteAll == false)
			{// 파일이 있을 경우..
askagain_sftp_copy:
				vector<string> q;
				q.push_back(_("Overwrite"));
				q.push_back(_("Skip"));
				q.push_back(_("Rename"));
				q.push_back(_("Overwrite All"));
				q.push_back(_("Skip All"));
				q.push_back(_("Cancel"));

				int 	nSelect = 0;
				tProgress.End();
				nSelect = SelectBox((_("File exists : ") + pFile->sName).c_str(), q, 0);
				tProgress.Start();

				LOG_WRITE("Selection [%d]", nSelect);
				
				switch(nSelect)
				{
					case 0:	// overwrite
						LOG_WRITE("OverWrite");
						bOverwrite = true;
						break;
					
					case 1: // skip
						uPsize += tAttr.filesize;
						uViewCount++;
						continue;
						
					case 2: // rename 
					{
						if ( !pFile->bDir )
						{	
							struct stat statbuf;
							string sRename = pFile->sName;
							
							while(1)
							{
								tProgress.End();
								if (InputBox(	_("Rename"),
												sRename) < 0) goto askagain_sftp_copy;
								tProgress.Start();
								sTargetName = sTargetPathTmp2 + sRename;
															
								if (lstat(sTargetName.c_str(), &statbuf) != -1)
								{
									tProgress.End();
									MsgBox(	_("Error"), _("File exists"));
									tProgress.Start();
									continue;
								}
								break;
							}
						}
						else
						{
							tProgress.End();
							MsgBox(	_("Error"), _("Directory can't rename."));
							tProgress.Start();
						}	
						break;
					}
					
					case 3: // overwriteall
						bOverwriteAll = true;
						break;
						
					case 4: // skipall
						bSkipAll = true;
						uPsize += tAttr.filesize;
						uViewCount++;
						continue;
					
					case -1:
					case 5: // cancel
						goto halt_sftp_copy;
							
					default:
						break;
				}
			}
		}
		
		// 파일 리스트가 디렉토리 라면
		if (pFile->bDir)
		{
			if (pSelection != NULL)
			{
				File	tTargetFile = *pFile;
				tTargetFile.sFullName = sTargetName;
				pSelection->Add(&tTargetFile);
			}

			if (mkdir(sTargetName.c_str(), tAttr.permissions)==-1) // 디렉토리를 만든다.
			{
				// 실패하면
				if ( !bOverwriteAll && !bSkipAll && !bOverwrite)
				{
					tProgress.End();
					MsgBox(_("Error"), _("Directory Making error"));
					break;
				}
			}
			continue;
		}
		
		uCsize=0;
		// 실제 복사 오퍼레이션	
		
		uViewCount++;
		
		LIBSSH2_SFTP_HANDLE*		pFtpFileHandle = NULL;
		
		pFtpFileHandle = libssh2_sftp_open( (LIBSSH2_SFTP*)_pSessionSFtp, (char*)sSourceName.c_str(), 
												LIBSSH2_FXF_READ, 0644);

		if (pFtpFileHandle == NULL)
		{
			String	sMsg; string sErrMsg = GetLastErrMsg();
			sMsg.Append(_("File access error (%s), continue? !!! "), pFile->sFullName.c_str());
			if (!sErrMsg.empty()) sMsg.Append("[%s]", sErrMsg.c_str());
			tProgress.End();
			if (YNBox(_("Error"), sMsg.c_str(), false) == false) break;
			tProgress.Start();
			continue;
		}		

		FILE*	out = fopen(sTargetName.c_str(), "wb");
		
		if ( out )
		{
			for(;;)
			{
				if (tProgress.isExit())
				{
					tProgress.End();
					if (YNBox(_("Warning"), _("Do you want to stop copy operation?"), false)==true)
					{
						fclose(out);
						libssh2_sftp_close_handle(pFtpFileHandle);
						remove( sTargetName.c_str() );
						goto halt_sftp_copy;
					}
					tProgress.Start();
				}	
				
				if (tAttr.filesize <= (libssh2_uint64_t)uCsize ) break;
			
				if ((uLastSize = libssh2_sftp_read(pFtpFileHandle, buf, sizeof(buf))) == -1)
				{
					String	sMsg; string sErrMsg  = GetLastErrMsg();
					sMsg.Append(_("remote file access error (%s), continue? !!! "), pFile->sFullName.c_str());
					if (!sErrMsg.empty()) sMsg.Append("[%s]", sErrMsg.c_str());
					tProgress.End();
					if (YNBox(_("Error"), sMsg.c_str(), false) == false) break;
					fclose(out);
					libssh2_sftp_close_handle(pFtpFileHandle);
					remove( sTargetName.c_str() );
					goto halt_sftp_copy;
				}
				
				fwrite(buf, 1, uLastSize, out);
	
				uCsize +=uLastSize;
				uPsize +=uLastSize;

				// libssh2_sftp_seek(pFtpFileHandle, uCsize);
				sCount2.Printf("%s/%s", toregular(uCsize).c_str(), 
										toregular(pFile->uSize).c_str());
				tProgress.setRightStr(sCount2.c_str());

				if ( pFile->uSize && uCsize && uPsize && uFileSize )
					tProgress.setCount(	uCsize * 100 / pFile->uSize,
										uPsize * 100 / uFileSize );
			}
		}
		else
		{
			libssh2_sftp_close_handle(pFtpFileHandle);
			tProgress.End();
			if (YNBox(_("Error"), _("local file access error, continue?"), false) == false) 	break;
			tProgress.Start();
			continue;
		}

		fclose(out);

		chmod(sTargetName.c_str(), tAttr.permissions);
		libssh2_sftp_close_handle(pFtpFileHandle);
		
		if (pSelection != NULL)
		{
			File	tTargetFile = *pFile;
			tTargetFile.sFullName = sTargetName;
			pSelection->Add(&tTargetFile);
		}
	}
halt_sftp_copy:
	tProgress.End();
	if (pSelection)
		pSelection->SetSelectPath(sTargetPathTmp2);

	LOG_WRITE("DirReader Copy End");
	return true;
}
Esempio n. 2
0
bool	SFtpReader::Paste(Selection& tSelection)
{
	string			sCurName, sTargetPathTmp, sTargetPathTmp2;
	string			sSourceName, sTargetName;
	vector<File*>	vFiles;
	struct stat 	src_stat;

	int		nBufSize = g_tCfg.GetValueNum("SSH", "DefBufSize", 8196);
	char	buf[nBufSize];

	ullong	uFileSize = tSelection.CalcSize();
	uint	uSize = tSelection.GetSize();
	
	string 	sSize = toregular(uSize), sRestSize;

	bool	bSkipAll = false, bOverwriteAll = false;
	ullong	uLastSize = 0, uViewCount=1, uPsize=0, uCsize = 0;

	vFiles = tSelection.GetData();
	sTargetPathTmp2 = _sCurPath;
	
	CommonProgress	tProgress(	_("Copy"), (_("To ") + sTargetPathTmp2).c_str(), true);
	
	string sSourcePath = tSelection.GetSelectPath();
	
	LOG_WRITE("Copy sTargetPath [%s] [%s]", _sCurPath.c_str(), sTargetPathTmp2.c_str());

	EncodeChk(vFiles, false);

	tProgress.Start();

	// 파일 디렉토리 먼저 생성 복사
	for (int n=0; n<(int)vFiles.size(); n++)
	{
		File*	pFile = vFiles[n];
		
		// 파일 이름이 없을경우 continue
		if (!pFile) continue;
		// 소스 이름과 타겟 이름 정하기	
		sSourceName = pFile->sFullName;
		sTargetName = sTargetPathTmp2 + pFile->sFullName.substr(sSourcePath.size());
		sTargetName = KorCodeChg(sTargetName, _eEncode);

		// 파일 리스트가 디렉토리 라면
		if (pFile->bDir)
		{
			if ( libssh2_sftp_mkdir( (LIBSSH2_SFTP*)_pSessionSFtp, (char*)sTargetName.c_str(), 0755) == -1)
			{
				String	sMsg; string sErrMsg = GetLastErrMsg();
				sMsg.Append(_("SFtp Directory exists, continue !!! [%s]"), sTargetName.c_str());
				if (!sErrMsg.empty()) sMsg.Append("[%s]", sErrMsg.c_str());
				tProgress.End();
				if (YNBox(_("Error"), sMsg.c_str(), false) == false) break;
				tProgress.Start();
				return false;
			}
			continue;
		}
	}

	for (int n=0; n<(int)vFiles.size(); n++)
	{
		File*	pFile = vFiles[n];
		
		// 파일 이름이 없을경우 continue
		if (!pFile) continue;

		// 소스 이름과 타겟 이름 정하기	
		sSourceName = pFile->sFullName;
		sTargetName = sTargetPathTmp2 + pFile->sFullName.substr(sSourcePath.size());
		sTargetName = KorCodeChg(sTargetName, _eEncode);

		LOG_WRITE("SFtpReader::Paste [%s] [%s]", sSourceName.c_str(), sTargetName.c_str());

		if (stat(sSourceName.c_str(), &src_stat)==-1)
		{
			// 소스가 없다니.. 참
			String	sStr;
			sStr.Append(_("Source is not found : %s"), sSourceName.c_str());
			tProgress.End();
			MsgBox(_("Error"), sStr);
			tProgress.Start();
			break;
		}

		LOG_WRITE("SFtpReader Paste sTargetName 1 [%s] [%s] [%s]", sSourceName.c_str(), sTargetName.c_str(), _sCurPath.c_str());
		
		mode_t permission = src_stat.st_mode;

		// 파일 리스트가 디렉토리 라면
		if (pFile->bDir) continue; 

		String	sCount, sCount2;
		sCount.Printf("%s/%s", toregular(uViewCount).c_str(), sSize.c_str());

		tProgress.setLeftStr(pFile->sName.c_str());
		tProgress.setRightStr2(sCount.c_str());

		LIBSSH2_SFTP_ATTRIBUTES 	tAttrs;
		
		if (libssh2_sftp_stat((LIBSSH2_SFTP*)_pSessionSFtp, (char*)sTargetName.c_str(), &tAttrs) != -1)
		{
			if (bSkipAll) continue;
			else if (bOverwriteAll == false)
			{// 파일이 있을 경우..
askagain_sftp_paste:
				vector<string> q;
				q.push_back(_("Overwrite"));
				q.push_back(_("Skip"));
				q.push_back(_("Rename"));
				q.push_back(_("Overwrite All"));
				q.push_back(_("Skip All"));
				q.push_back(_("Cancel"));

				int 	nSelect = 0;
				tProgress.End();
				nSelect = SelectBox((_("File exists : ") + pFile->sName).c_str(), q, 0);
				tProgress.Start();

				LOG_WRITE("Selection [%d]", nSelect);
				
				switch(nSelect)
				{
					case 0:	// overwrite
						LOG_WRITE("OverWrite");
						break;
					
					case 1: // skip
						uPsize += src_stat.st_size;
						uViewCount++;
						continue;
						
					case 2: // rename 
					{
						if ( !pFile->bDir )
						{
							string sRename = pFile->sName;
							
							while(1)
							{
								tProgress.End();
								if (InputBox(	_("Rename"), sRename) < 0) goto askagain_sftp_paste;
								tProgress.Start();
	
								sTargetName = sTargetPathTmp2 + sRename;
								
								if ( libssh2_sftp_rename_ex( 	(LIBSSH2_SFTP*)_pSessionSFtp, 
									(char*)pFile->sFullName.c_str(), 
									pFile->sFullName.size(),
									(char*)sTargetName.c_str(),
									sTargetName.size(), 
									0644) == -1)
								{							
									tProgress.End();
									MsgBox(	_("Error"), _("File exists"));
									tProgress.Start();
									continue;
								}
								tProgress.End();
							}
							break;
						}
						else
						{
							tProgress.End();
							MsgBox(	_("Error"), _("Directory can't rename."));
							tProgress.Start();
						}
						break;
					}
					
					case 3: // overwriteall
						bOverwriteAll = true;
						break;
						
					case 4: // skipall
						bSkipAll = true;
						uPsize += src_stat.st_size;
						uViewCount++;
						continue;
							
					case -1:
					case 5: // cancel
						goto halt_sftp_paste;
							
					default:
						break;
				}
			}
		}
		
		uCsize=0;	
		// 실제 복사 오퍼레이션	
		
		uViewCount++;

		LIBSSH2_SFTP_HANDLE*		pFtpOutFileHandle = NULL;
		
		pFtpOutFileHandle = libssh2_sftp_open( (LIBSSH2_SFTP*)_pSessionSFtp, (char*)sTargetName.c_str(), 
												LIBSSH2_FXF_READ | LIBSSH2_FXF_WRITE | LIBSSH2_FXF_TRUNC | LIBSSH2_FXF_CREAT ,
												0644);

		if (pFtpOutFileHandle == NULL)
		{
			String	sMsg; string sErrMsg = GetLastErrMsg();
			sMsg.Append("File write access error (%s), continue? !!! ", sTargetName.c_str());
			if (!sErrMsg.empty()) sMsg.Append("[%s]", sErrMsg.c_str());
			tProgress.End();
			if (YNBox(_("Error"), sMsg.c_str(), false) == false) break;
			tProgress.Start();
			continue;
		}

		FILE*	fp = fopen(sSourceName.c_str(), "rb");
		
		LOG_WRITE("TEST1");

		if ( fp )
		{
			while( !feof(fp) )
			{
				if (tProgress.isExit())
				{
					tProgress.End();
					if (YNBox(_("Warning"), _("Do you want to stop copy operation?"), false)==true)
					{
						libssh2_sftp_close_handle(pFtpOutFileHandle);
						fclose(fp);
						libssh2_sftp_unlink((LIBSSH2_SFTP*)_pSessionSFtp, (char*)sTargetName.c_str());
						goto halt_sftp_paste;
					}
					tProgress.Start();
				}				
				
				uLastSize = fread(buf, 1, sizeof(buf), fp);
				
				int nSize = 0, nSizePlus = 0;
				do
				{
					if (tProgress.isExit()) break;
						
					nSize = 0;
					if ((nSize = libssh2_sftp_write(pFtpOutFileHandle, buf+nSizePlus, uLastSize-nSizePlus)) == -1)
					{
						tProgress.End();
						String		sMsg; string sErrMsg = GetLastErrMsg();
						sMsg.Append(_("file writing failure. continue?"));
						if (!sErrMsg.empty()) sMsg.Append(" [%s]", sErrMsg.c_str()); 						
						if (YNBox(_("Error"), sMsg.c_str() , false)==false)
						{
							libssh2_sftp_close_handle(pFtpOutFileHandle);
							fclose(fp);
							libssh2_sftp_unlink((LIBSSH2_SFTP*)_pSessionSFtp, (char*)sTargetName.c_str());
							goto halt_sftp_paste;
						}
						tProgress.Start();
						break;
					}
					
					uCsize += nSize; uPsize += nSize; nSizePlus += nSize;
				}
				while( nSizePlus < uLastSize );
				
				if (tProgress.isExit()) continue;
				
				//libssh2_sftp_seek(pFtpOutFileHandle, uCsize);
				
				sCount2.Printf("%s/%s", 	toregular(uPsize).c_str(),
											toregular(uFileSize).c_str());
				
				tProgress.setRightStr(sCount2.c_str());
				if (src_stat.st_size && uCsize && uPsize && uFileSize)
					tProgress.setCount(	uCsize * 100 / src_stat.st_size,
										uPsize * 100 / uFileSize );
			}
		}
		else
		{
			tProgress.End();
			if (YNBox(_("Error"), _("File access error, continue?"), false) == false) break;
			tProgress.Start();
			continue;
		}
		
		LIBSSH2_SFTP_ATTRIBUTES	tAttrOut;
		libssh2_sftp_fstat(pFtpOutFileHandle, &tAttrOut);
		tAttrOut.permissions = permission;
		libssh2_sftp_fsetstat(pFtpOutFileHandle, &tAttrOut);
		libssh2_sftp_close_handle(pFtpOutFileHandle);
		fclose(fp);
	}
halt_sftp_paste:
	tProgress.End();
	return true;
}