int FSSftp::Stat ( FSPath& path, FSStat* st, int* err, FSCInfo* info ) { MutexLock lock( &mutex ); int ret = CheckSession( err, info ); if ( ret ) { return ret; } char* fullPath = ( char* ) path.GetString( _operParam.charset, '/' ); try { SftpAttr attr; int ret; WHILE_EAGAIN_( ret, libssh2_sftp_lstat( sftpSession, fullPath, &attr.attr ) ); CheckSFTP( ret ); if ( attr.IsLink() ) { char buf[4096]; int len; WHILE_EAGAIN_( len, libssh2_sftp_readlink( sftpSession, fullPath, buf, sizeof( buf ) ) ); if ( len < 0 ) { CheckSFTP( len ); }; st->link.Set( _operParam.charset, buf ); int ret; WHILE_EAGAIN_( ret, libssh2_sftp_stat( sftpSession, fullPath, &attr.attr ) ); if ( ret ) { attr.attr.permissions = 0; } } st->mode = attr.Permissions(); st->size = attr.Size(); st->uid = attr.Uid(); st->gid = attr.Gid(); st->mtime = attr.MTime(); } catch ( int e ) { st->mode = 0; if ( err ) { *err = e; } return ( e == -2 ) ? -2 : -1; } return 0; }
/* sftp获取文件属性 */ static int sftp_get_stat(protocol_data_t *protocol, char *filename, file_t *fileinfo) { LIBSSH2_SFTP_ATTRIBUTES attrs; if (protocol == NULL || protocol->protocol_data == NULL || filename == NULL || fileinfo == NULL) { return -1; } sftp_data_t *data = (sftp_data_t *)protocol->protocol_data; libssh2_sftp_lstat(data->sftp_session, filename, &attrs); fileinfo->filesize = attrs.filesize; fileinfo->permissions = attrs.permissions; fileinfo->uid = attrs.uid; fileinfo->gid = attrs.gid; fileinfo->mtime = attrs.mtime; fileinfo->atime = attrs.atime; return 0; }
int FSSftp::OpenCreate ( FSPath& path, bool overwrite, int mode, int flags, int* err, FSCInfo* info ) { MutexLock lock( &mutex ); int ret = CheckSession( err, info ); if ( ret ) { return ret; } int n = 0; try { if ( !overwrite ) { /* странная херня, при наличии файла с O_EXCL, выдает не EEXIST, а "прерван системный вызов" поэтому встанил эту дурацкую проверку на наличие */ LIBSSH2_SFTP_ATTRIBUTES attr; int ret; WHILE_EAGAIN_( ret, libssh2_sftp_lstat( sftpSession, ( char* )path.GetString( _operParam.charset, '/' ), &attr ) ); if ( !ret ) { if ( err ) { *err = EEXIST; } return -1; } } for ( n = 0; n < MAX_FILES; n++ ) if ( !fileTable[n] ) { break; } if ( n >= MAX_FILES ) { if ( err ) { *err = SSH_INTERROR_OUTOF; } return -1; } LIBSSH2_SFTP_HANDLE* fd = 0; while ( true ) { fd = libssh2_sftp_open( sftpSession, ( char* )path.GetString( _operParam.charset, '/' ), LIBSSH2_FXF_CREAT | LIBSSH2_FXF_WRITE | ( overwrite ? LIBSSH2_FXF_TRUNC : LIBSSH2_FXF_EXCL ), mode ); if ( fd ) { break; } CheckSFTPEagain(); WaitSocket( info ); } fileTable[n] = fd; } catch ( int e ) { if ( err ) { *err = e; } return ( e == -2 ) ? -2 : -1; } return n; }