Exemplo n.º 1
0
bool ParzeLink( FSPath& path, FSString& link )
{
	FSPath t( link );

	if ( !path.IsAbsolute() && !t.IsAbsolute() ) { return false; } //не абсолютный путь

	int first = 0;

	if ( t.IsAbsolute() )
	{
		path.Clear();
		path.PushStr( FSString( "" ) );
		first = 1;
	}

	for ( int i = first; i < t.Count(); i++ )
	{
		FSString p = *( t.GetItem( i ) );

		if ( p.IsDot() ) { continue; }

		if ( p.Is2Dot() )
		{
			if ( path.Count() > 1 ) { path.Pop(); }
		}
		else
		{
			path.PushStr( p );
		}
	}

	return true;
}
Exemplo n.º 2
0
bool FSGetApplPath(FSString &applPath, bool withPS/* = true*/)
{
 #if defined(WIN32) || defined(_WIN32_WCE)

	char    Temp[_MAX_PATH+1];
	::GetModuleFileNameA(NULL, Temp, _MAX_PATH);

	applPath = Temp;

	STRIndex_t pos = applPath.FindRAt(PATH_SEPARATOR_CHAR);
	if ( STRING_FOUND(pos) )
		applPath.Truncate( withPS ? pos + 1 : pos );

	return true;

#else

	UniString uniString;
	if ( FSGetApplPath(uniString, withPS) )
	{
		applPath = uniString;
	}

	return false;

#endif
}
FSArchNode* ArchGetParentDir( FSArchNode* CurrDir, FSPath& ItemPath, const FSStat& ItemStat )
{
	for ( int i = 0; i < ItemPath.Count() - 1; i++ )
	{
		FSString* Name = ItemPath.GetItem( i );

		if ( i == 0 && ( Name->IsDot() || Name->IsEmpty() ) )
		{
			// skip root dir
			continue;
		}

		FSArchNode* Dir = CurrDir->findByName( *Name );

		if ( Dir == nullptr )
		{
			FSStat Stat = ItemStat;
			Stat.mode = S_IFDIR;
			Stat.size = 0;
			Dir = CurrDir->Add( FSArchNode( Name->GetUtf8(), Stat ) );
		}

		CurrDir = Dir;
	}

	return CurrDir;
}
Exemplo n.º 4
0
FSTmpNode* FSTmpNode::findByFsPath(FSPath* fsPath, int fsPathLevel)
{
	FSString* curName = fsPath->GetItem(fsPathLevel);
	if (parentDir == 0 && fsPathLevel == fsPath->Count()-1 && (curName == 0 || curName->GetUnicode() == 0 || curName->GetUnicode()[0] == 0)) // request to find root node, and we are root
		return this;

	if (name.Cmp(*curName) == 0)
	{
		if (fsPath->Count() <= fsPathLevel)
		{   // exact match
			return this;
		}
		else
		{
			FSString* childName = fsPath->GetItem(fsPathLevel + 1);
			FSTmpNode* n = findByName(childName, false);
			if (n == 0)
				return 0;
			if (fsPath->Count() <= fsPathLevel + 2) // no further recursion
				return n;
			else if (n->nodeType == NODE_DIR) // recurse into subdir
				return n->findByFsPath(fsPath, fsPathLevel + 1);
			else
				return 0;
		}
	}
	else
		return 0;
}
Exemplo n.º 5
0
FSString FSSys::StrError( int err )
{
	sys_char_t buf[1024];
	FSString ret;
	ret.SetSys( sys_error_str( err, buf, 0x100 ) );
	return ret;
}
Exemplo n.º 6
0
void FSPath::Copy( const FSPath& a )
{
	cacheCs = -2;
	data.clear();

	for ( int i = 0 ; i < a.Count(); i++ )
	{
		FSString s;
		s.Copy( a.data.const_item( i ) );
		data.append( s );
	}
}
Exemplo n.º 7
0
FSString FSWin32Net::StrError( int err )
{
	if ( err == ERRNOSUPPORT )
	{
		return FSString( "Operation not supported by net fs" );
	}

	FSString ret;
	sys_char_t buf[1024];
	ret.SetSys( sys_error_str( err, buf, 0x100 ) );

	return ret;
}
Exemplo n.º 8
0
static void stripPathFromLastItem(FSPath& path)
{
	FSString* lastItem = path.GetItem(path.Count() - 1);
	if (lastItem)
	{
		const unicode_t* lastU = lastItem->GetUnicode();
		const unicode_t* lastDelim = unicode_strrchr(lastU, DIR_SPLITTER);
		if (lastDelim != 0)
		{
			path.SetItemStr(path.Count() - 1,FSString(lastDelim + 1));
		}
	}
}
Exemplo n.º 9
0
void FSPath::SetItemStr( int n, const FSString& str ) // n>=0 && n<=Count(); если n == Count то в конец добавляется еще один элемент
{
	if ( n < 0 || n > Count() ) { return; }

	cacheCs = -2;

	//чтоб не сработал эффект cptr
	FSString s;
	s.Copy( str );

	if ( n == Count() ) { data.append( s ); }
	else { data[n] = s; }
}
Exemplo n.º 10
0
	void Clear()
	{
		executed = false;
		errorString.Clear();
		srcList.clear();

		pathChanged = false;
//		uint64_t infoCount = 0;
		infoSrcUri.Clear();
		infoDstUri.Clear();
		progressChanged = false;
		infoSize = 0;
		infoProgress = 0;
	}
Exemplo n.º 11
0
void FSPath::Copy(const FSPath& a, int elementCount)
{
	cacheCs = -2;
	data.clear();
	if (elementCount<0 || elementCount>a.Count())
		elementCount = a.Count();

	for (int i = 0; i < elementCount; i++)
	{
		FSString s;
		s.Copy(a.data.const_item(i));
		data.append(s);
	}

}
Exemplo n.º 12
0
FSArchNode* FSArchNode::findByName( const FSString& name, bool isRecursive )
{
	dbg_printf( "FSArchNodeDir::findByName name=%s\n", name.GetUtf8() );

	// first, try all nodes in current
	for ( FSArchNode& n : content )
	{
		dbg_printf( "FSArchNodeDir::findByName n.name=%s\n", n.name.GetUtf8() );

		if ( n.name.Cmp( ( FSString& ) name ) == 0 )
		{
			return &n;
		}
	}

	// only if not found in current dir, try inside subdirs
	if ( isRecursive )
	{
		for ( FSArchNode& n : content )
		{
			if ( n.IsDir() )
			{
				FSArchNode* pn = n.findByName( name, isRecursive );

				if ( pn )
				{
					return pn;
				}
			}
		}
	}

	return nullptr;
}
Exemplo n.º 13
0
int FSString::Cmp( FSString& a )
{
	if ( !_primary.str() ) { return ( !a._primary.str() ) ? 0 : -1; }

	if ( !a._primary.str() ) { return 1; }

	return CmpStr<const unicode_t>( GetUnicode(), a.GetUnicode() );
}
Exemplo n.º 14
0
FSArchNode* FSArchNode::findByFsPath( FSPath& fsPath, int fsPathLevel )
{
	FSString* curName = fsPath.GetItem( fsPathLevel );

	if ( parentDir == nullptr
	     && fsPathLevel == fsPath.Count() - 1
	     && ( curName == nullptr || curName->GetUnicode() == 0 || curName->GetUnicode()[0] == 0 ) )
	{
		// request to find root node, and we are root
		return this;
	}

	if ( name.Cmp( *curName ) == 0 )
	{
		if ( fsPath.Count() <= fsPathLevel )
		{
			// exact match
			return this;
		}

		FSString* childName = fsPath.GetItem( fsPathLevel + 1 );
		FSArchNode* n = findByName( *childName );

		if ( n == nullptr )
		{
			return nullptr;
		}

		if ( fsPath.Count() <= fsPathLevel + 2 )
		{
			// no further recursion
			return n;
		}

		if ( n->IsDir() )
		{
			// recurse into subdir
			return n->findByFsPath( fsPath, fsPathLevel + 1 );
		}
	}

	return nullptr;
}
Exemplo n.º 15
0
int FSSys::Symlink( FSPath& path, FSString& str, int* err, FSCInfo* info )
{
	if ( symlink( ( char* )str.Get( sys_charset_id ), ( char* )path.GetString( sys_charset_id ) ) )
	{
		SetError( err, errno );
		return -1;
	}

	return 0;
}
Exemplo n.º 16
0
    FSString::FSString(const FSString& rhs) : FSValue(rhs), buffer(0), strLength(0), bufferLength(0)
    {
        strLength = rhs.length();
        bufferLength = strLength + 1;
        buffer = new char[bufferLength];

        if (bufferLength > 0 && buffer == 0)
            throw FSAllocationException("Cannot allocate memory to copy an FSString.");

        strcpy(buffer, rhs.buffer);
    }
Exemplo n.º 17
0
void OpenHomeDir( PanelWin* p )
{
#ifdef _WIN32
	std::vector<unicode_t> homeUri = GetHomeUriWin();

	if ( homeUri.data() )
	{
		const std::vector<clPtr<FS>> checkFS =
		{
			p->GetFSPtr(),
			g_MainWin->GetOtherPanel( p )->GetFSPtr()
		};

		FSPath path;
		clPtr<FS> fs = ParzeURI( homeUri.data(), path, checkFS );

		if ( fs.IsNull() )
		{
			char buf[4096];
			FSString name = homeUri.data();
			Lsnprintf( buf, sizeof( buf ), "bad home path: %s\n", name.GetUtf8() );
			NCMessageBox( g_MainWin, "Home", buf, true );
		}
		else
		{
			p->LoadPath( fs, path, 0, 0, PanelWin::SET );
		}
	}

#else
	const sys_char_t* home = (sys_char_t*) getenv( "HOME" );
	if ( !home )
	{
		return;
	}

	FSPath path( sys_charset_id, home );
	p->LoadPath( new FSSys(), path, 0, 0, PanelWin::SET );
#endif
}
Exemplo n.º 18
0
clPtr<FS> clArchPlugin::OpenFS( clPtr<FS> Fs, FSPath& Path ) const
{
	FSString Uri = Fs->Uri( Path );

	struct archive* Arch = ArchOpen( Uri.GetUtf8() );

	if ( Arch == nullptr )
	{
		return nullptr;
	}

	FSArchNode RootDir;
	RootDir.fsStat.mode = S_IFDIR;

	FSPath NodePath;
	struct archive_entry* entry = archive_entry_new2( Arch );

	int Res;

	while ( ( Res = archive_read_next_header2( Arch, entry ) ) == ARCHIVE_OK )
	{
		NodePath.Set( CS_UTF8, archive_entry_pathname( entry ) );

		FSString* ItemName = NodePath.GetItem( NodePath.Count() - 1 );

		if ( NodePath.Count() == 1 && ( ItemName->IsDot() || ItemName->IsEmpty() ) )
		{
			// skip root dir
			continue;
		}

		const mode_t Mode = archive_entry_mode( entry );
		const int64_t Size = archive_entry_size( entry );
		RootDir.entryOffset += Size;

		FSStat ItemStat;
		ItemStat.mode = S_ISREG( Mode ) ? Mode : S_IFDIR;
		ItemStat.size = Size;
		ItemStat.m_CreationTime = archive_entry_ctime( entry );
		ItemStat.m_LastAccessTime = archive_entry_atime( entry );
		ItemStat.m_LastWriteTime = archive_entry_mtime( entry );
		ItemStat.m_ChangeTime = ItemStat.m_LastWriteTime;

		FSArchNode* Dir = ArchGetParentDir( &RootDir, NodePath, ItemStat );
		FSArchNode* Item = Dir->Add( FSArchNode( ItemName->GetUtf8(), ItemStat ) );
		if (Item) {
			Item->entryOffset = archive_read_header_position( Arch );
		}
	}

	if ( Res != ARCHIVE_EOF )
	{
		dbg_printf( "Couldn't read archive entry: %s\n", archive_error_string( Arch ) );
	}

	archive_entry_free( entry );
	ArchClose( Arch );

	return new FSArch( RootDir, Uri );
}
Exemplo n.º 19
0
int FSArch::OpenRead( FSPath& path, int flags, int* err, FSCInfo* info )
{
	dbg_printf( "FSArch::Open\n" );

	FSArchNode* Node = m_RootDir.findByFsPath( path );

	if ( Node == nullptr )
	{
		FS::SetError( err, FSARCH_ERROR_FILE_NOT_FOUND );
		return -1;
	}

	struct archive* Arch = ArchOpen( m_Uri.GetUtf8() );

	if ( Arch == nullptr )
	{
		FS::SetError( err, FSARCH_ERROR_FILE_NOT_FOUND );
		return -1;
	}

	struct archive_entry* entry = archive_entry_new2( Arch );
	int Res;

	// seek to the entry
	while ( ( Res = archive_read_next_header2( Arch, entry ) ) == ARCHIVE_OK )
	{
		int64_t EntryOffset = archive_read_header_position( Arch );

		if ( EntryOffset == Node->entryOffset )
		{
			break;
		}
	}

	archive_entry_free( entry );

	if ( Res != ARCHIVE_OK )
	{
		ArchClose( Arch );
		
		dbg_printf( "Couldn't read archive entry: %s\n", archive_error_string( Arch ) );
		FS::SetError( err, FSARCH_ERROR_FILE_NOT_FOUND );
		return -1;
	}

	const int fd = g_NextArchFD++;
	m_OpenFiles[ fd ] = Arch;
	return fd;
}
Exemplo n.º 20
0
bool FileAttributesDlg( NCDialogParent* Parent, PanelWin* Panel )
{
	clFileAttributesWin Dialog( Parent, Panel );

	if ( Dialog.DoModal( ) == CMD_OK )
	{
		FSNode* Node = Dialog.GetNode();

		// apply changes
		if ( Node )
		{
			FSPath fspath;
			FSString URI = Dialog.GetURI();
			clPtr<FS> fs = ParzeURI( URI.GetUnicode(), fspath, {} );
			if ( fs )
			{
				int Err = 0;
				FSCInfo Info;
				fs->StatSetAttr( fspath, &Node->st, &Err, &Info );
				if ( Err != 0 )
				{
					throw_msg( "Error setting file attributes: %s", fs->StrError( Err ).GetUtf8() );
				}
				fs->SetFileTime( fspath, Node->GetCreationTime(), Node->GetLastAccessTime(), Node->GetLastWriteTime(), &Err, &Info );
				if ( Err != 0 )
				{
					throw_msg("Error setting file date & time: %s", fs->StrError(Err).GetUtf8());
				}
			}
		}

		return true;
	}

	return false;
}
Exemplo n.º 21
0
int FSSftp::Symlink  ( FSPath& path, FSString& str, int* err, FSCInfo* info )
{
	MutexLock lock( &mutex );
	int ret = CheckSession( err, info );

	if ( ret ) { return ret; }

	if ( sftp_symlink( sftpSession, ( char* )str.Get( _operParam.charset ),  ( char* )path.GetString( _operParam.charset ) ) )
	{
		if ( err ) { *err = sftp_get_error( sftpSession ); }

		return -1;
	}

	return 0;

}
Exemplo n.º 22
0
int FSString::CmpNoCase( FSString& par )
{
	if ( !_primary.str() ) { return ( !par._primary.str() ) ? 0 : -1; }

	if ( !par._primary.str() ) { return 1; }

	const unicode_t* a = GetUnicode();
	const unicode_t* b = par.GetUnicode();
	unicode_t au = 0;
	unicode_t bu = 0;

	for ( ; *a; a++, b++ )
	{
		au = UnicodeLC( *a );
		bu = UnicodeLC( *b );

		if ( au != bu ) { break; }
	};

	return ( *a ? ( *b ? ( au < bu ? -1 : ( au == bu ? 0 : 1 ) ) : 1 ) : ( *b ? -1 : 0 ) );
}
Exemplo n.º 23
0
int FSSftp::Symlink  ( FSPath& path, FSString& str, int* err, FSCInfo* info )
{
	MutexLock lock( &mutex );
	int ret = CheckSession( err, info );

	if ( ret ) { return ret; }

	try
	{
		int ret;
		WHILE_EAGAIN_( ret, libssh2_sftp_symlink( sftpSession, ( char* )str.Get( _operParam.charset ),  ( char* )path.GetString( _operParam.charset, '/' ) ) );
		CheckSFTP( ret );
	}
	catch ( int e )
	{
		if ( err ) { *err = e; }

		return ( e == -2 ) ? -2 : -1;
	}

	return 0;
}
Exemplo n.º 24
0
void _DeleteFolderAndFiles(const char *dirName)
{
	FSString	fsString;

	DIR	*dirp = NULL;
	dirp = opendir(dirName);
	if ( dirp == NULL ) return;
	
	struct dirent *dp;
	while ((dp = readdir(dirp)) != NULL)
	{
	//	printf("%s\n", dp->d_name);
		if ( dp->d_type == DT_REG )
		{
			fsString = dirName;
			fsString.Append(PATH_SEPARATOR_CHAR);
			fsString.Append( dp->d_name);
			
			remove(fsString.GetString());
		}
		else if (dp->d_type == DT_DIR )
		{
			if (strcmp(dp->d_name, ".") == 0 ) continue;
			if (strcmp(dp->d_name, "..") == 0 ) continue;
			
			fsString = dirName;
			fsString.Append(PATH_SEPARATOR_CHAR);
			fsString.Append( dp->d_name);
			
			_DeleteFolderAndFiles(fsString.GetString());
		}
	}
	closedir(dirp);

	rmdir(dirName);
}
Exemplo n.º 25
0
void OperRDThread::Run()
{
	if ( !fs.Ptr() ) { return; }

	int n = 8;
	int ret_err;

	int havePostponedStatError = 0;
	FSString postponedStrError;

	while ( true )
	{
		if ( !( fs->Flags() & FS::HAVE_SYMLINK ) )
		{
			break;
		}

		FSStat st;

		// if path is inaccessible, try .. path. Throw the exception later
		// This makes panel at least having some valid folder
		while ( fs->Stat( path, &st, &ret_err, Info() ) )
		{
			havePostponedStatError = 1;
			postponedStrError = fs->StrError( ret_err );

			if ( !path.IsAbsolute() || path.Count() <= 1 || !path.Pop() )
			{
				throw_msg( "%s", postponedStrError.GetUtf8() );
			}
		}

		// yell immediately if the path is inaccessible (orig behavior)
		//if (fs->Stat(path, &st, &ret_err, Info()))
		// throw_msg("%s", fs->StrError(ret_err).GetUtf8());

		if ( !st.IsLnk() )
		{
			break;
		}

		n--;

		if ( n < 0 )
		{
			throw_msg( "too many symbolic links '%s'", path.GetUtf8() );
		}

		path.Pop();

		if ( !ParzeLink( path, st.link ) )
		{
			throw_msg( "invalid symbolic link '%s'", path.GetUtf8() );
		}
	}

	clPtr<FSList> list = new FSList;

	int havePostponedReadError = 0;

	// if directory is not readable, try .. path. Throw the exception later
	// "Stat" call above does not catch this: it checks only folder existence, but not accessibilly
	while ( fs->ReadDir( list.ptr(), path, &ret_err, Info() ) )
	{
		havePostponedReadError = 1;
		postponedStrError = fs->StrError( ret_err );

		if ( !path.IsAbsolute() || path.Count() <= 1 || !path.Pop() )
		{
			throw_msg( "%s", postponedStrError.GetUtf8() );
		}
	}

	// yell immediately if the dir is unreadable (orig behavior)
	//int ret = fs->ReadDir(list.ptr(), path, &ret_err, Info());
	//if (ret)
	// throw_msg("%s", fs->StrError(ret_err).GetUtf8());

	FSStatVfs vst;
	fs->StatVfs( path, &vst, &ret_err, Info() );

	MutexLock lock( Node().GetMutex() ); //!!!

	if ( Node().NBStopped() ) { return; }

	OperRDData* data = ( ( OperRDData* )Node().Data() );
	data->list = list;
	data->path = path;
	data->executed = true;
	data->vst = vst;

	if ( havePostponedReadError || havePostponedStatError )
	{
		data->nonFatalErrorString = postponedStrError;
	}
}
Exemplo n.º 26
0
int FSSftp::CheckSession( int* err, FSCInfo* info )
{
	if ( sshSession ) { return 0; }

	try
	{
		sshSession = ssh_new();

		if ( !sshSession ) { throw int( SSH_INTERROR_X3 ); }

		if ( ssh_options_set( sshSession, SSH_OPTIONS_HOST, unicode_to_utf8( _operParam.server.Data() ).ptr() ) )
		{
			throw int( SSH_INTERROR_X3 );
		}

		int port = _operParam.port;

		if ( ssh_options_set( sshSession, SSH_OPTIONS_PORT, &port ) )
		{
			throw int( SSH_INTERROR_X3 );
		}


		FSString userName = "";

		if ( _operParam.user.Data()[0] )
		{
			userName = _operParam.user.Data();
		}
		else
		{
			char* ret = getenv( "LOGNAME" );

			if ( ret )
			{
				userName = FSString( sys_charset_id, ret );
				_operParam.user = userName.GetUnicode();

				MutexLock infoLock( &infoMutex );
				_infoParam.user = userName.GetUnicode();
			}
		};

		if ( ssh_options_set( sshSession, SSH_OPTIONS_USER, ( char* )userName.Get( _operParam.charset ) ) ) //есть сомнения, что надо все таки в utf8
		{
			throw int( SSH_INTERROR_X3 );
		}

		if ( ssh_connect( sshSession ) != SSH_OK )
		{
			throw int( SSH_INTERROR_CONNECT );
		}


		int method = ssh_userauth_list( sshSession, 0 );

		int ret;


		static unicode_t userSymbol = '@';

		if ( method & SSH_AUTH_METHOD_PASSWORD )
		{
			FSPromptData data;
			data.visible = false;
			data.prompt = utf8_to_unicode( "Password:"******"SFTP_" ).ptr(),
			        carray_cat<unicode_t>( userName.GetUnicode(), &userSymbol, _operParam.server.Data() ).ptr(),
			        &data, 1 ) ) { throw int( SSH_INTERROR_STOPPED ); }

			ret = ssh_userauth_password( sshSession,
			                             ( char* )FSString( _operParam.user.Data() ).Get( _operParam.charset ),
			                             ( char* )FSString( data.prompt.Data() ).Get( _operParam.charset ) );
		}

		if ( ret != SSH_AUTH_SUCCESS &&
		     ( method & SSH_AUTH_METHOD_INTERACTIVE ) != 0 )
		{
			while ( true )
			{
				ret = ssh_userauth_kbdint( sshSession, 0, 0 );

				if ( ret != SSH_AUTH_INFO ) { break; }

				const char* instruction = ssh_userauth_kbdint_getinstruction( sshSession );

				if ( !instruction ) { instruction = ""; }

				int n = ssh_userauth_kbdint_getnprompts( sshSession );

				if ( n <= 0 ) { continue; }

				std::vector<FSPromptData> pData( n );
				int i;

				for ( i = 0; i < n; i++ )
				{
					char echo;
					const char* prompt = ssh_userauth_kbdint_getprompt( sshSession, i, &echo );

					if ( !prompt ) { break; }

					pData[i].visible = echo != 0;
					pData[i].prompt = utf8_to_unicode( prompt ).ptr();
				}

				if ( !info ) { throw int( SSH_INTERROR_AUTH ); }

				if ( !info->Prompt(
				        utf8_to_unicode( "SFTP" ).ptr(),
				        carray_cat<unicode_t>( userName.GetUnicode(), &userSymbol, _operParam.server.Data() ).ptr(),
				        pData.ptr(), n ) ) { throw int( SSH_INTERROR_STOPPED ); }

				for ( i = 0; i < n; i++ )
				{
					if ( ssh_userauth_kbdint_setanswer( sshSession, i, ( char* )FSString( pData[i].prompt.Data() ).Get( _operParam.charset ) ) < 0 )
					{
						throw int( SSH_INTERROR_AUTH );
					}
				}
			}
		}

		if ( ret != SSH_AUTH_SUCCESS )
		{
			if ( ret == SSH_AUTH_PARTIAL )
			{
				throw int( SSH_INTERROR_UNSUPPORTED_AUTH );
			}
			else
			{
				throw int( SSH_INTERROR_AUTH );
			}
		}

		sftpSession = sftp_new( sshSession );

		if ( !sftpSession ) { throw int( SSH_INTERROR_FATAL ); }

		if ( sftp_init( sftpSession ) != SSH_OK ) { throw int( SSH_INTERROR_FATAL ); }

	}
	catch ( int e )
	{
		if ( err ) { *err = e; }

		if ( sftpSession ) { sftp_free( sftpSession ); }

		if ( sshSession ) { ssh_free( sshSession ); }

		sshSession = 0;
		sftpSession = 0;
		return ( e == SSH_INTERROR_STOPPED ) ? -2 : -1;
	}

	return 0;
}
Exemplo n.º 27
0
FSString FSSftp::StrError( int err )
{
	const char* s = "";

	if ( err < -500 )
	{
		switch ( err + 1000 )
		{
			case LIBSSH2_ERROR_SOCKET_NONE:
				s = "LIBSSH2_ERROR_SOCKET_NONE";
				break;

			case LIBSSH2_ERROR_BANNER_RECV:
				s = "LIBSSH2_ERROR_BANNER_RECV";
				break;

			case LIBSSH2_ERROR_BANNER_SEND:
				s = "LIBSSH2_ERROR_BANNER_SEND";
				break;

			case LIBSSH2_ERROR_INVALID_MAC:
				s = "LIBSSH2_ERROR_INVALID_MAC";
				break;

			case LIBSSH2_ERROR_KEX_FAILURE:
				s = "LIBSSH2_ERROR_KEX_FAILURE";
				break;

			case LIBSSH2_ERROR_ALLOC:
				s = "LIBSSH2_ERROR_ALLOC";
				break;

			case LIBSSH2_ERROR_SOCKET_SEND:
				s = "LIBSSH2_ERROR_SOCKET_SEND";
				break;

			case LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE:
				s = "LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE";
				break;

			case LIBSSH2_ERROR_TIMEOUT:
				s = "LIBSSH2_ERROR_TIMEOUT";
				break;

			case LIBSSH2_ERROR_HOSTKEY_INIT:
				s = "LIBSSH2_ERROR_HOSTKEY_INIT";
				break;

			case LIBSSH2_ERROR_HOSTKEY_SIGN:
				s = "LIBSSH2_ERROR_HOSTKEY_SIGN";
				break;

			case LIBSSH2_ERROR_DECRYPT:
				s = "LIBSSH2_ERROR_DECRYPT";
				break;

			case LIBSSH2_ERROR_SOCKET_DISCONNECT:
				s = "LIBSSH2_ERROR_SOCKET_DISCONNECT";
				break;

			case LIBSSH2_ERROR_PROTO:
				s = "LIBSSH2_ERROR_PROTO";
				break;

			case LIBSSH2_ERROR_PASSWORD_EXPIRED:
				s = "LIBSSH2_ERROR_PASSWORD_EXPIRED";
				break;

			case LIBSSH2_ERROR_FILE:
				s = "LIBSSH2_ERROR_FILE";
				break;

			case LIBSSH2_ERROR_METHOD_NONE:
				s = "LIBSSH2_ERROR_METHOD_NONE";
				break;

			case LIBSSH2_ERROR_AUTHENTICATION_FAILED:
				s = "Authentication failed";
				break;

			case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
				s = "LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED";
				break;

			case LIBSSH2_ERROR_CHANNEL_OUTOFORDER:
				s = "LIBSSH2_ERROR_CHANNEL_OUTOFORDER";
				break;

			case LIBSSH2_ERROR_CHANNEL_FAILURE:
				s = "LIBSSH2_ERROR_CHANNEL_FAILURE";
				break;

			case LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED:
				s = "LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED";
				break;

			case LIBSSH2_ERROR_CHANNEL_UNKNOWN:
				s = "LIBSSH2_ERROR_CHANNEL_UNKNOWN";
				break;

			case LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED:
				s = "LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED";
				break;

			case LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED:
				s = "LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED";
				break;

			case LIBSSH2_ERROR_CHANNEL_CLOSED:
				s = "LIBSSH2_ERROR_CHANNEL_CLOSED";
				break;

			case LIBSSH2_ERROR_CHANNEL_EOF_SENT:
				s = "LIBSSH2_ERROR_CHANNEL_EOF_SENT";
				break;

			case LIBSSH2_ERROR_SCP_PROTOCOL:
				s = "LIBSSH2_ERROR_SCP_PROTOCOL";
				break;

			case LIBSSH2_ERROR_ZLIB:
				s = "LIBSSH2_ERROR_ZLIB";
				break;

			case LIBSSH2_ERROR_SOCKET_TIMEOUT:
				s = "LIBSSH2_ERROR_SOCKET_TIMEOUT";
				break;

			case LIBSSH2_ERROR_SFTP_PROTOCOL:
				s = "LIBSSH2_ERROR_SFTP_PROTOCOL";
				break;

			case LIBSSH2_ERROR_REQUEST_DENIED:
				s = "LIBSSH2_ERROR_REQUEST_DENIED";
				break;

			case LIBSSH2_ERROR_METHOD_NOT_SUPPORTED:
				s = "LIBSSH2_ERROR_METHOD_NOT_SUPPORTED";
				break;

			case LIBSSH2_ERROR_INVAL:
				s = "LIBSSH2_ERROR_INVAL";
				break;

			case LIBSSH2_ERROR_INVALID_POLL_TYPE:
				s = "LIBSSH2_ERROR_INVALID_POLL_TYPE";
				break;

			case LIBSSH2_ERROR_PUBLICKEY_PROTOCOL:
				s = "LIBSSH2_ERROR_PUBLICKEY_PROTOCOL";
				break;

			case LIBSSH2_ERROR_EAGAIN:
				s = "LIBSSH2_ERROR_EAGAIN";
				break;

			case LIBSSH2_ERROR_BUFFER_TOO_SMALL:
				s = "LIBSSH2_ERROR_BUFFER_TOO_SMALL";
				break;

			case LIBSSH2_ERROR_BAD_USE:
				s = "LIBSSH2_ERROR_BAD_USE";
				break;

			case LIBSSH2_ERROR_COMPRESS:
				s = "LIBSSH2_ERROR_COMPRESS";
				break;

			case LIBSSH2_ERROR_OUT_OF_BOUNDARY:
				s = "LIBSSH2_ERROR_OUT_OF_BOUNDARY";
				break;

			case LIBSSH2_ERROR_AGENT_PROTOCOL:
				s = "LIBSSH2_ERROR_AGENT_PROTOCOL";
				break;

			case LIBSSH2_ERROR_SOCKET_RECV:
				s = "LIBSSH2_ERROR_SOCKET_RECV";
				break;

			case LIBSSH2_ERROR_ENCRYPT:
				s = "LIBSSH2_ERROR_ENCRYPT";
				break;

			case LIBSSH2_ERROR_BAD_SOCKET:
				s = "LIBSSH2_ERROR_BAD_SOCKET";
				break;

			default:
				s = "LIBSSH2_ERROR_???";
				break;
		}

	}
	else
	{
		switch ( err )
		{
			case SSH_INTERROR_NOTSUPPORT:
				s = "not supported operation";
				break;

			case SSH_INTERROR_X3:
				s = "X3";
				break;

			case SSH_INTERROR_CONNECT:
				s = "connection failed";
				break;

			case SSH_INTERROR_AUTH:
				s = "authorization failed";
				break;

			case SSH_INTERROR_FATAL:
				s = "fatal ssh error";
				break;

			case SSH_INTERROR_STOPPED:
				s = "Process stopped";
				break;

			default:
				if ( err >= 0 )
				{
					sys_char_t buf[0x100];
					FSString str;
					str.SetSys( sys_error_str( err, buf, 0x100 ) );
					return str;
				}

				char buf[0x100];
				snprintf( buf, sizeof( buf ), "err : %i ???", err );
				FSString str( CS_UTF8, buf );
				return str;
		}
	}

	return FSString( CS_UTF8, s );
}
Exemplo n.º 28
0
int FSSftp::CheckSession( int* err, FSCInfo* info )
{

	if ( sshSession ) { return 0; }

	try
	{

		unsigned ip;
		int e;

		if ( !GetHostIp( unicode_to_utf8( _operParam.server.Data() ).data(), &ip, &e ) )
		{
			throw int( e );
		}

		_sock.Create();
		_sock.Connect( ntohl( ip ), _operParam.port );

		sshSession = libssh2_session_init();

		if ( !sshSession ) { throw int( SSH_INTERROR_X3 ); }

		libssh2_session_set_blocking( sshSession, 0 );

		WHILE_EAGAIN_( e, libssh2_session_handshake( sshSession, _sock.Id() ) );

		if ( e ) { throw int( e - 1000 ); }

		FSString userName = "";

		if ( _operParam.user.Data()[0] )
		{
			userName = _operParam.user.Data();
		}
		else
		{
#ifndef _WIN32
			char* ret = getenv( "LOGNAME" );

			if ( ret )
			{
				userName = FSString( sys_charset_id, ret );
				_operParam.user = userName.GetUnicode();

				MutexLock infoLock( &infoMutex );
				_infoParam.user = userName.GetUnicode();
			}

#endif
		};

		char* authList = 0;

		char* charUserName = ( char* )userName.Get( _operParam.charset );

		while ( true )
		{
			authList = libssh2_userauth_list( sshSession, charUserName, strlen( charUserName ) );

			if ( authList ) { break; }

			CheckSessionEagain();
			WaitSocket( info );
		}


		//publickey,password,keyboard-interactive
		static const char passId[] = "password";
		static const char kInterId[] = "keyboard-interactive";


		static unicode_t userSymbol = '@';

		while ( true )
		{
			if ( !strncmp( authList, passId, strlen( passId ) ) )
			{
				FSPromptData data;
				data.visible = false;
				data.prompt = utf8_to_unicode( "Password:"******"SFTP_" ).data(),
				        carray_cat<unicode_t>( userName.GetUnicode(), &userSymbol, _operParam.server.Data() ).data(),
				        &data, 1 ) ) { throw int( SSH_INTERROR_STOPPED ); }

				int ret;
				WHILE_EAGAIN_( ret, libssh2_userauth_password( sshSession,
				                                               ( char* )FSString( _operParam.user.Data() ).Get( _operParam.charset ),
				                                               ( char* )FSString( data.prompt.Data() ).Get( _operParam.charset ) ) );

				if ( ret ) { throw int( ret - 1000 ); }

				break; //!!!
			}
			else if ( !strncmp( authList, kInterId, strlen( kInterId ) ) )
			{
				MutexLock lock( &kbdIntMutex );
				kbdIntInfo = info;
				kbdIntParam = &_operParam;

				int ret;
				WHILE_EAGAIN_( ret,
				               libssh2_userauth_keyboard_interactive( sshSession,
				                                                      ( char* )FSString( _operParam.user.Data() ).Get( _operParam.charset ),
				                                                      KbIntCallback )
				             );

				if ( ret ) { throw int( ret - 1000 ); }

				break; //!!!
			}

			char* s = authList;

			while ( *s && *s != ',' ) { s++; }

			if ( !*s ) { break; }

			authList = s + 1;
		};


		while ( true )
		{
			sftpSession = libssh2_sftp_init( sshSession );

			if ( sftpSession ) { break; }

			if ( !sftpSession )
			{
				int e = libssh2_session_last_errno( sshSession );

				if ( e != LIBSSH2_ERROR_EAGAIN ) { throw int( e - 1000 ); }
			}

			WaitSocket( info );
		}

		return 0;

	}
	catch ( int e )
	{
		if ( err ) { *err = e; }

		//if (sftpSession) ??? похоже закрытие сессии все решает
		if ( sshSession ) { libssh2_session_free( sshSession ); }

		sshSession = 0;
		sftpSession = 0;
		_sock.Close( false );
		return ( e == -2 ) ? -2 : -1;
	}

}