@@ -395,6 +395,7 @@ static int SendPacketType(WOLFSSH* ssh, byte type, byte* buf, word32 bufSz);
395395static int SFTP_ParseAtributes_buffer (WOLFSSH * ssh , WS_SFTP_FILEATRB * atr ,
396396 byte * buf , word32 * idx , word32 maxIdx );
397397static WS_SFTPNAME * wolfSSH_SFTPNAME_new (void * heap );
398+ static int SFTP_CreateLongName (WS_SFTPNAME * name );
398399
399400
400401static byte * wolfSSH_SFTP_buffer_data (WS_SFTP_BUFFER * buffer )
@@ -1755,6 +1756,105 @@ int wolfSSH_SFTP_RecvMKDIR(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
17551756}
17561757
17571758
1759+ #ifdef WOLFSSH_FATFS
1760+ #ifndef WOLFSSH_FATFS_MAX_FILES
1761+ #define WOLFSSH_FATFS_MAX_FILES 32
1762+ #endif
1763+
1764+
1765+ struct fd_entry {
1766+ FIL f ;
1767+ int used ;
1768+ };
1769+
1770+ static struct fd_entry fd_pool [WOLFSSH_FATFS_MAX_FILES ] = { };
1771+
1772+ int ff_open (const char * fname , int flag , int perm )
1773+ {
1774+ int i ;
1775+ BYTE mode ;
1776+ (void )perm ;
1777+ PRINTF ("\r\nfatFS open: %s" , fname );
1778+
1779+ if (flag & WOLFSSH_O_RDONLY ) {
1780+ mode = FA_READ ;
1781+
1782+ } else if (flag & WOLFSSH_O_RDWR ) {
1783+ if ((flag & WOLFSSH_O_CREAT ) &&
1784+ (flag & WOLFSSH_O_TRUNC )) {
1785+ mode = FA_READ | FA_WRITE | FA_CREATE_ALWAYS ;
1786+
1787+ } else if ((flag & WOLFSSH_O_CREAT ) &&
1788+ (flag & WOLFSSH_O_APPEND )) {
1789+ mode = FA_READ | FA_WRITE | FA_CREATE_NEW | FA_OPEN_APPEND ;
1790+
1791+ } else {
1792+ mode = AM_ARC ;
1793+ }
1794+ } else if (flag & WOLFSSH_O_WRONLY ) {
1795+ if ((flag & WOLFSSH_O_CREAT ) &&
1796+ (flag & WOLFSSH_O_TRUNC )) {
1797+ mode = FA_READ | FA_CREATE_ALWAYS | FA_WRITE ;
1798+ } else if ((flag & WOLFSSH_O_CREAT ) &&
1799+ (flag & WOLFSSH_O_APPEND )) {
1800+ mode = FA_READ | FA_WRITE | FA_CREATE_NEW | FA_OPEN_APPEND ;
1801+ }
1802+ } else {
1803+ return -1 ;
1804+ }
1805+
1806+
1807+ for (i = 0 ; i < WOLFSSH_FATFS_MAX_FILES ; i ++ ) {
1808+ if (fd_pool [i ].used == 0 ) {
1809+ if (f_open (& (fd_pool [i ].f ), fname , mode ) == FR_OK ) {
1810+ fd_pool [i ].used = 1 ;
1811+ PRINTF ("\r\nfatFS open success: %d" , i );
1812+ return i ;
1813+
1814+ } else {
1815+ return -1 ;
1816+ }
1817+ }
1818+ }
1819+ return -1 ;
1820+ }
1821+
1822+ int ff_close (int fd )
1823+ {
1824+ f_close (& fd_pool [fd ].f );
1825+ if (fd_pool [fd ].used )
1826+ fd_pool [fd ].used = 0 ;
1827+ return 0 ;
1828+ }
1829+
1830+ int ff_pwrite (int fd , const byte * buffer , int sz )
1831+ {
1832+ FIL * f = & fd_pool [fd ].f ;
1833+ FRESULT ret ;
1834+ unsigned int rsz ;
1835+ if (fd_pool [fd ].used == 0 )
1836+ return -1 ;
1837+ ret = f_write (f , buffer , sz , & rsz );
1838+ if (ret != FR_OK )
1839+ return -1 ;
1840+ return rsz ;
1841+ }
1842+ int ff_pread (int fd , byte * buffer , int sz )
1843+ {
1844+ FIL * f = & fd_pool [fd ].f ;
1845+ FRESULT ret ;
1846+ unsigned int rsz ;
1847+ if (fd_pool [fd ].used == 0 )
1848+ return -1 ;
1849+ ret = f_read (f , buffer , sz , & rsz );
1850+ if (ret != FR_OK )
1851+ return -1 ;
1852+ return rsz ;
1853+ }
1854+
1855+
1856+ #endif /* WOLFSSH_FATFS */
1857+
17581858/* Handles packet to open a file
17591859 *
17601860 * returns WS_SUCCESS on success
@@ -2678,6 +2778,87 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out,
26782778 return WS_SUCCESS ;
26792779}
26802780
2781+ #elif defined(WOLFSSH_FATFS )
2782+
2783+ /* helper function that gets file information from reading directory
2784+ *
2785+ * returns WS_SUCCESS on success
2786+ */
2787+ static int wolfSSH_SFTPNAME_readdir (WOLFSSH * ssh , WDIR * dir , WS_SFTPNAME * out ,
2788+ char * dirName )
2789+ {
2790+ FILINFO f ;
2791+ FILINFO * dp ;
2792+ int sz ;
2793+
2794+ if (dir == NULL || ssh == NULL || out == NULL ) {
2795+ return WS_BAD_ARGUMENT ;
2796+ }
2797+ dp = & f ;
2798+
2799+ if (f_readdir (dir , dp ) != FR_OK ) {
2800+ return WS_FATAL_ERROR ;
2801+ }
2802+ sz = (int )WSTRLEN (dp -> fname );
2803+ out -> fName = (char * )WMALLOC (sz + 1 , out -> heap , DYNTYPE_SFTP );
2804+ if (out -> fName == NULL ) {
2805+ return WS_MEMORY_E ;
2806+ }
2807+
2808+ WMEMCPY (out -> fName , dp -> fname , sz );
2809+ out -> fName [sz ] = '\0' ;
2810+ out -> fSz = sz ;
2811+
2812+ /* attempt to get file attributes. Could be directory or have none */
2813+ {
2814+ char * buf ;
2815+ int bufSz ;
2816+ int tmpSz ;
2817+
2818+ bufSz = out -> fSz + (int )WSTRLEN (dirName ) + sizeof (WS_DELIM );
2819+ buf = (char * )WMALLOC (bufSz + 1 , out -> heap , DYNTYPE_SFTP );
2820+ if (buf == NULL ) {
2821+ WFREE (out -> fName , out -> heap , DYNTYPE_SFTP );
2822+ return WS_MEMORY_E ;
2823+ }
2824+ buf [0 ] = '\0' ;
2825+ WSTRNCAT (buf , dirName , bufSz + 1 );
2826+ tmpSz = (int )WSTRLEN (buf );
2827+
2828+ /* add delimiter between path and file/dir name */
2829+ if (tmpSz + 1 < bufSz ) {
2830+ buf [tmpSz ] = WS_DELIM ;
2831+ buf [tmpSz + 1 ] = '\0' ;
2832+ }
2833+ WSTRNCAT (buf , out -> fName , bufSz + 1 );
2834+ if (XSTRLEN (out -> fName ) == 0 ) {
2835+ WFREE (buf , out -> heap , DYNTYPE_SFTP );
2836+ return WS_EOF ;
2837+ }
2838+ if (wolfSSH_CleanPath (ssh , buf ) < 0 ) {
2839+ WFREE (buf , out -> heap , DYNTYPE_SFTP );
2840+ return WS_FATAL_ERROR ;
2841+ }
2842+
2843+ if (SFTP_GetAttributes (ssh -> fs , buf , & out -> atrb , 0 , ssh -> ctx -> heap )
2844+ != WS_SUCCESS ) {
2845+ WLOG (WS_LOG_SFTP , "Unable to get attribute values for %s" ,
2846+ out -> fName );
2847+ WFREE (buf , out -> heap , DYNTYPE_SFTP );
2848+ return WS_FATAL_ERROR ;
2849+ }
2850+ WFREE (buf , out -> heap , DYNTYPE_SFTP );
2851+ }
2852+
2853+ /* Use attributes and fName to create long name */
2854+ if (SFTP_CreateLongName (out ) != WS_SUCCESS ) {
2855+ WLOG (WS_LOG_DEBUG , "Error creating long name for %s" , out -> fName );
2856+ WFREE (out -> fName , out -> heap , DYNTYPE_SFTP );
2857+ return WS_FATAL_ERROR ;
2858+ }
2859+ return WS_SUCCESS ;
2860+ }
2861+
26812862#else
26822863
26832864/* helper function that gets file information from reading directory
@@ -4200,6 +4381,121 @@ int SFTP_GetAttributes_Handle(WOLFSSH* ssh, byte* handle, int handleSz,
42004381 return WS_SUCCESS ;
42014382}
42024383
4384+ #elif defined(WOLFSSH_FATFS )
4385+
4386+ /* FatFs has its own structure for file attributes */
4387+
4388+ static int SFTP_GetAttributes (void * fs , const char * fileName ,
4389+ WS_SFTP_FILEATRB * atr , byte link , void * heap )
4390+ {
4391+ FILINFO info ;
4392+ FRESULT ret ;
4393+ int sz = (int )WSTRLEN (fileName );
4394+
4395+ ret = f_stat (fileName , & info );
4396+ if (ret != FR_OK )
4397+ return -1 ;
4398+ WMEMSET (atr , 0 , sizeof (WS_SFTP_FILEATRB ));
4399+ if (sz > 2 && fileName [sz - 2 ] == ':' ) {
4400+ atr -> flags |= WOLFSSH_FILEATRB_PERM ;
4401+ atr -> per |= 0x4000 ;
4402+ return WS_SUCCESS ;
4403+ }
4404+
4405+ /* handle case of "/" */
4406+ if (sz < 3 && fileName [0 ] == WS_DELIM ) {
4407+ atr -> flags |= WOLFSSH_FILEATRB_PERM ;
4408+ atr -> per |= 0x4000 ;
4409+ return WS_SUCCESS ;
4410+ }
4411+
4412+ if (ret != FR_OK ) {
4413+ return WS_BAD_FILE_E ;
4414+ }
4415+
4416+ atr -> flags |= WOLFSSH_FILEATRB_SIZE ;
4417+ atr -> sz [0 ] = (word32 )(info .fsize );
4418+ atr -> sz [1 ] = (word32 )(0 );
4419+
4420+ /* get additional attributes */
4421+ {
4422+ byte atrib = info .fattrib ;
4423+ atr -> flags |= WOLFSSH_FILEATRB_PERM ;
4424+ if (atrib & AM_DIR ) {
4425+ atr -> per |= 0x41ED ; /* 755 with directory */
4426+ }
4427+ else {
4428+ atr -> per |= 0x8000 ;
4429+ }
4430+ if ((atrib & AM_ARC ) == AM_ARC ) {
4431+ atr -> per |= 0x1ED ; /* octal 755 */
4432+ }
4433+ if ((atrib & AM_SYS ) || (atrib & AM_RDO )) {
4434+ atr -> per |= 0x124 ; /* octal 444 */
4435+ }
4436+ }
4437+
4438+ #ifndef NO_WOLFSSH_MKTIME
4439+ /* get file times */
4440+ atr -> flags |= WOLFSSH_FILEATRB_TIME ;
4441+ atr -> atime = info .fdate ;
4442+ atr -> mtime = info .fdate ;
4443+ #endif /* NO_WOLFSSH_MKTIME */
4444+ return WS_SUCCESS ;
4445+ }
4446+
4447+ static int SFTP_GetAttributes_Handle (WOLFSSH * ssh , byte * handle , int handleSz ,
4448+ WS_SFTP_FILEATRB * atr )
4449+ {
4450+ FILINFO info ;
4451+ WS_HANDLE_LIST * cur ;
4452+
4453+ if (handle == NULL || atr == NULL ) {
4454+ return WS_FATAL_ERROR ;
4455+ }
4456+
4457+ cur = SFTP_GetHandleNode (ssh , handle , handleSz );
4458+ if (cur == NULL ) {
4459+ WLOG (WS_LOG_SFTP , "Unknown handle" );
4460+ return WS_BAD_FILE_E ;
4461+ }
4462+
4463+ if (f_stat (cur -> name , & info ) != FR_OK ) {
4464+ return WS_FATAL_ERROR ;
4465+ }
4466+
4467+ WMEMSET (atr , 0 , sizeof (WS_SFTP_FILEATRB ));
4468+
4469+ atr -> flags |= WOLFSSH_FILEATRB_SIZE ;
4470+ atr -> sz [0 ] = (word32 )(info .fsize );
4471+ atr -> sz [1 ] = (word32 )(0 );
4472+
4473+ {
4474+ byte atrib = info .fattrib ;
4475+ atr -> flags |= WOLFSSH_FILEATRB_PERM ;
4476+ if (atrib & AM_DIR ) {
4477+ atr -> per |= 0x41ED ; /* 755 with directory */
4478+ }
4479+ else {
4480+ atr -> per |= 0x8000 ;
4481+ }
4482+ if ((atrib & AM_ARC ) == AM_ARC ) {
4483+ atr -> per |= 0x1ED ; /* octal 755 */
4484+ }
4485+ if ((atrib & AM_RDO ) || (atrib & AM_SYS )) {
4486+ atr -> per |= 0x124 ; /* octal 444 */
4487+ }
4488+ }
4489+
4490+ #ifndef NO_WOLFSSH_MKTIME
4491+ /* get file times */
4492+ atr -> flags |= WOLFSSH_FILEATRB_TIME ;
4493+ atr -> atime = info .ftime ;
4494+ atr -> mtime = info .ftime ;
4495+ #endif /* NO_WOLFSSH_MKTIME */
4496+ return WS_SUCCESS ;
4497+ }
4498+
42034499#elif defined(WOLFSSH_USER_FILESYSTEM )
42044500 /* User-defined I/O support */
42054501
0 commit comments