@@ -595,6 +595,16 @@ import Foundation
595595 if let file = sftp_stat ( sftp_session, pathC) {
596596 defer { sftp_attributes_free ( file) }
597597
598+ var fullPath = path
599+ if fullPath. hasPrefix ( " / " ) == false {
600+ fullPath = try canonicalPath ( forPath: fullPath)
601+ }
602+
603+ if fullPath. hasPrefix ( " / " ) == false {
604+ // this should not happen
605+ throw error ( code: . file_not_found)
606+ }
607+
598608 var ownerS = " "
599609 var groupS = " "
600610
@@ -605,7 +615,7 @@ import Foundation
605615 groupS = stringWith ( buf: group) ?? " "
606616 }
607617
608- let item = MFTSftpItem ( name: path ,
618+ let item = MFTSftpItem ( name: fullPath ,
609619 size: file. pointee. size,
610620 uid: file. pointee. uid,
611621 gid: file. pointee. gid,
@@ -626,6 +636,32 @@ import Foundation
626636 throw error_sftp ( )
627637 }
628638 }
639+
640+ /// Return canonical (absolute) path for the given path
641+ /// - Parameters:
642+ /// - path: the path to canonicalize.
643+ /// - Returns: The canonical path.
644+ /// - Throws: NSError on error.
645+ public func canonicalPath( forPath path: String ) throws -> String {
646+
647+ if sftp_session == nil {
648+ throw error ( code: . no_session)
649+ }
650+
651+ let pathC = cString ( for: path)
652+ defer { pathC. deallocate ( ) }
653+
654+ if let file = sftp_canonicalize_path ( sftp_session, pathC) {
655+ defer { ssh_string_free_char ( file) }
656+ if let n = stringWith ( buf: file) {
657+ return n
658+ } else {
659+ throw error ( code: . file_not_found)
660+ }
661+ } else {
662+ throw error_sftp ( )
663+ }
664+ }
629665
630666 /// Resolve the target of the given symbolic link.
631667 /// - Parameters:
0 commit comments