Merge pull request #787 from wolfSSL/devin/1740666408-add-fatfs-test-action

FATFS improvements, test and Linux example
pull/789/head
David Garske 2025-03-07 06:32:22 -08:00 committed by GitHub
commit cea99e5e83
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 720 additions and 9 deletions

178
.github/workflows/test-fatfs.yml vendored 100644
View File

@ -0,0 +1,178 @@
name: Test FATFS Support
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
jobs:
get-fatfs:
runs-on: ubuntu-latest
steps:
- name: Set up cache key
id: cache-key
run: echo "CACHE_KEY=ff15a-cache" >> $GITHUB_ENV
- name: Download FF15a.zip
id: download
run: |
wget http://elm-chan.org/fsw/ff/arc/ff15a.zip -O ff15a.zip
- name: Cache the downloaded ZIP file
uses: actions/cache@v4
with:
path: ./ff15a.zip
key: ${{ env.CACHE_KEY }}
restore-keys: |
${{ env.CACHE_KEY }}
test-fatfs:
needs: get-fatfs
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Checking cache for FATFS
uses: actions/cache@v4
with:
path: ./ff15a.zip
key: ff15a-cache
fail-on-cache-miss: true
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential autoconf automake libtool pkg-config openssh-server dosfstools
- name: Clone wolfSSL
run: |
cd ..
git clone https://github.com/wolfSSL/wolfssl.git
cd wolfssl
./autogen.sh
- name: Configure and build wolfSSL
run: |
cd ../wolfssl
./configure --enable-wolfssh --enable-intelasm --disable-crl --disable-examples --disable-filesystem CFLAGS="-DNO_WOLFSSL_DIR"
make
sudo make install
sudo ldconfig
- name: Compile FATFS library
run: |
cd ide/Linux-FATFS
unzip ../../ff15a.zip
cp ffconf.h source/
make
- name: Configure and build wolfSSH with FATFS
run: |
./autogen.sh
export LD_LIBRARY_PATH=$(pwd)/ide/Linux-FATFS
./configure --enable-sftp CFLAGS="-DWOLFSSH_FATFS -Iide/Linux-FATFS/source -DSTDIN_FILENO=0 -DPRINTF=printf" LDFLAGS="-Lide/Linux-FATFS -lfatfs"
make
- name: Create test file
run: |
dd if=/dev/urandom of=test_file.bin bs=1M count=1
- name: Setup SSH server
run: |
sudo mkdir -p /run/sshd
sudo /usr/sbin/sshd
mkdir -p ~/.ssh
ssh-keygen -t rsa -f ~/.ssh/id_rsa -N ""
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
echo "Host localhost" > ~/.ssh/config
echo " StrictHostKeyChecking no" >> ~/.ssh/config
echo " UserKnownHostsFile=/dev/null" >> ~/.ssh/config
chmod 600 ~/.ssh/config
- name: Install expect
run: |
sudo apt-get update
sudo apt-get install -y expect
- name: Run wolfsftp client to get file
run: |
# Export the library path
export LD_LIBRARY_PATH=$(pwd)/ide/Linux-FATFS
# Get the full path to the test file
TEST_FILE_PATH=$(pwd)/test_file.bin
# Change to the sftpclient directory
cd examples/sftpclient
# Create the FATFS image file directly in the sftpclient directory
dd if=/dev/zero of=fatfs_image.img bs=1M count=32
mkdosfs fatfs_image.img
# Create a test user with a known password and add to the same group as the runner
sudo useradd -m testuser
echo "testuser:password123" | sudo chpasswd
sudo usermod -aG $(id -gn) testuser
# Make the test file accessible to testuser
chmod 644 ${TEST_FILE_PATH}
sudo chown testuser:$(id -gn) ${TEST_FILE_PATH}
# Configure SSH server to allow SFTP access
sudo sed -i 's/^#Subsystem\s\+sftp.*/Subsystem sftp \/usr\/lib\/openssh\/sftp-server/' /etc/ssh/sshd_config
sudo service ssh restart || sudo /etc/init.d/ssh restart || sudo /usr/sbin/sshd -t && sudo kill -HUP $(pgrep -f sshd)
# Create expect script to automate the wolfsftp client interaction
cat > /tmp/sftp_test.exp << EOF
#!/usr/bin/expect -f
set timeout 60
spawn ./wolfsftp -N -h localhost -p 22 -u testuser
expect "Password:"
send "password123\r"
expect "wolfSSH sftp>"
send "get ${TEST_FILE_PATH} test_file.bin\r"
expect "wolfSSH sftp>"
send "exit\r"
expect eof
EOF
chmod +x /tmp/sftp_test.exp
# Run the expect script
/tmp/sftp_test.exp
- name: Verify file in FATFS image
run: |
cd examples/sftpclient
sudo mkdir -p /mnt/fatfs
LOOPDEV=$(sudo losetup -f)
sudo losetup $LOOPDEV fatfs_image.img
sudo mount $LOOPDEV /mnt/fatfs
if [ -f /mnt/fatfs/test_file.bin ]; then
echo "File exists in FATFS image!"
ls -la /mnt/fatfs/
# Verify file contents match
if cmp -s ../../test_file.bin /mnt/fatfs/test_file.bin; then
echo "File contents match! FATFS test PASSED."
sudo umount /mnt/fatfs
sudo losetup -d $LOOPDEV
exit 0
else
echo "File contents do not match! FATFS test FAILED."
sudo umount /mnt/fatfs
sudo losetup -d $LOOPDEV
exit 1
fi
else
echo "File does not exist in FATFS image! FATFS test FAILED."
ls -la /mnt/fatfs/
sudo umount /mnt/fatfs
sudo losetup -d $LOOPDEV
exit 1
fi

View File

@ -1476,6 +1476,9 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
int main(int argc, char** argv)
{
#ifdef WOLFSSH_FATFS
FATFS fs;
#endif
func_args args;
args.argc = argc;
@ -1486,6 +1489,13 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
args.sftp_cb = NULL;
#endif
#ifdef WOLFSSH_FATFS
if (f_mount(&fs, "0:", 1) != FR_OK) {
fprintf(stderr, "Failed to mount filesystem\n");
return 1;
}
#endif
WSTARTTCP();
#ifdef DEBUG_WOLFSSH
@ -1499,6 +1509,10 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
wolfSSH_Cleanup();
#ifdef WOLFSSH_FATFS
f_mount(NULL, "0:", 1);
#endif
#if defined(WOLFSSH_SFTP) && !defined(NO_WOLFSSH_CLIENT)
return args.return_code;
#else

1
ide/Linux-FATFS/.gitignore vendored 100644
View File

@ -0,0 +1 @@
fatfs_image.img

View File

@ -0,0 +1,26 @@
# Compiler and flags
CC = gcc
CFLAGS = -g -Wall -O2 -fPIC -Isource
LDFLAGS = -shared
# Source files
SRCS = source/ff.c source/ffunicode.c fatfs_example.c
# Object files
OBJS = $(SRCS:.c=.o)
# Target library
TARGET = libfatfs.so
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $^
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(OBJS) $(TARGET)
.PHONY: all clean

View File

@ -0,0 +1,49 @@
# FATFS Linux Example
This is a FATFS example that uses a single file on the Linux filesystem as the
FATFS file system.
## Obtaining FATFS
You can download the source code from
[The FATFS download site](http://elm-chan.org/fsw/ff/archives.html). Extract it
into this directory.
The example has been tested against FATFS 0.15a
## Compiling Library
First copy the config file into the correct place:
```sh
cp ffconf.h source/
```
Then to compile the FATFS library simply run `make`.
## Setup filesystem
The single file used for FATFS should be generated using:
```sh
dd if=/dev/zero of=fatfs_image.img bs=1M count=32
mkdosfs fatfs_image.img
```
Note that this file will need to be local to wherever you execute anything using
the library.
## Compiling wolfSSH and wolfSSL
### wolfSSL
```sh
./configure --enable-wolfssh --enable-intelasm --disable-crl --disable-examples --disable-filesystem CFLAGS="-DNO_WOLFSSL_DIR"
```
### wolfSSH
```sh
LD_LIBRARY_PATH=ide/Linux-FATFS ./configure --enable-sftp CFLAGS="-DWOLFSSH_FATFS -Iide/Linux-FATFS/source -DSTDIN_FILENO=0 -DPRINTF=printf" LDFLAGS="-Lide/Linux-FATFS -lfatfs"
```

View File

@ -0,0 +1,135 @@
/* sftpclient.c
*
* Copyright (C) 2025 wolfSSL Inc.
*
* This file is part of wolfSSH.
*
* wolfSSH is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSH is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with wolfSSH. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "ff.h"
#include "diskio.h"
#define STORAGE_FILE_PATH "fatfs_image.img"
static FILE *storage_file = NULL;
/* Initialize the storage file */
DSTATUS disk_initialize(BYTE pdrv) {
if (pdrv != 0) return STA_NOINIT; /* Only support one drive (0) */
/* Open the storage file in read/write binary mode */
storage_file = fopen(STORAGE_FILE_PATH, "r+b");
if (!storage_file) {
perror("Failed to open storage file");
return STA_NODISK | STA_NOINIT;
}
return 0; /* Initialization successful */
}
/* Get the status of the storage file */
DSTATUS disk_status(BYTE pdrv) {
if (pdrv != 0) return STA_NOINIT; /* Only support one drive (0) */
if (!storage_file) return STA_NODISK;
return 0;
}
/* Read sectors from the storage file */
DRESULT disk_read(BYTE pdrv, BYTE* buff, LBA_t sector, UINT count) {
if (pdrv != 0) return RES_PARERR; /* Only support one drive (0) */
if (!storage_file) return RES_NOTRDY;
off_t offset = sector * FF_MIN_SS; /* Calculate the byte offset */
if (fseek(storage_file, offset, SEEK_SET) != 0) {
perror("Failed to seek in storage file");
return RES_ERROR;
}
size_t bytes_read = fread(buff, FF_MIN_SS, count, storage_file);
if (bytes_read != count) {
perror("Failed to read from storage file");
return RES_ERROR;
}
return RES_OK;
}
/* Write sectors to the storage file */
DRESULT disk_write(BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count) {
if (pdrv != 0) return RES_PARERR; /* Only support one drive (0) */
if (!storage_file) return RES_NOTRDY;
off_t offset = sector * FF_MIN_SS; /* Calculate the byte offset */
if (fseek(storage_file, offset, SEEK_SET) != 0) {
perror("Failed to seek in storage file");
return RES_ERROR;
}
size_t bytes_written = fwrite(buff, FF_MIN_SS, count, storage_file);
if (bytes_written != count) {
perror("Failed to write to storage file");
return RES_ERROR;
}
fflush(storage_file); /* Ensure data is written to disk */
return RES_OK;
}
/* Control the device */
DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void* buff) {
if (pdrv != 0) return RES_PARERR; /* Only support one drive (0) */
switch (cmd) {
case CTRL_SYNC:
/* Ensure all data is written to disk */
fflush(storage_file);
break;
case GET_SECTOR_SIZE:
*(WORD*)buff = FF_MIN_SS;
break;
case GET_BLOCK_SIZE:
*(DWORD*)buff = 1; /* One sector per block (minimum) */
break;
default:
return RES_PARERR;
}
return RES_OK;
}
/* Function to deinitialize the storage file */
DSTATUS disk_deinitialize(BYTE pdrv) {
if (pdrv != 0) return STA_NOINIT; /* Only support one drive (0) */
if (storage_file) {
fclose(storage_file);
storage_file = NULL;
}
return 0; /* Deinitialization successful */
}
/* FatFs disk I/O driver interface */
DSTATUS disk_status_(BYTE pdrv) { return disk_status(pdrv); }
DRESULT disk_read_(BYTE pdrv, BYTE* buff, LBA_t sector, UINT count) { return disk_read(pdrv, buff, sector, count); }
DRESULT disk_write_(BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count) { return disk_write(pdrv, buff, sector, count); }
DRESULT disk_ioctl_(BYTE pdrv, BYTE cmd, void* buff) { return disk_ioctl(pdrv, cmd, buff); }

View File

@ -0,0 +1,296 @@
/*---------------------------------------------------------------------------/
/ Configurations of FatFs Module
/---------------------------------------------------------------------------*/
#define FFCONF_DEF 5380 /* Revision ID */
/*---------------------------------------------------------------------------/
/ Function Configurations
/---------------------------------------------------------------------------*/
#define FF_FS_READONLY 0
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
/ and optional writing functions as well. */
#define FF_FS_MINIMIZE 0
/* This option defines minimization level to remove some basic API functions.
/
/ 0: Basic functions are fully enabled.
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
/ are removed.
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
/ 3: f_lseek() function is removed in addition to 2. */
#define FF_USE_FIND 0
/* This option switches filtered directory read functions, f_findfirst() and
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
#define FF_USE_MKFS 0
/* This option switches f_mkfs(). (0:Disable or 1:Enable) */
#define FF_USE_FASTSEEK 0
/* This option switches fast seek feature. (0:Disable or 1:Enable) */
#define FF_USE_EXPAND 0
/* This option switches f_expand(). (0:Disable or 1:Enable) */
#define FF_USE_CHMOD 0
/* This option switches attribute control API functions, f_chmod() and f_utime().
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
#define FF_USE_LABEL 0
/* This option switches volume label API functions, f_getlabel() and f_setlabel().
/ (0:Disable or 1:Enable) */
#define FF_USE_FORWARD 0
/* This option switches f_forward(). (0:Disable or 1:Enable) */
#define FF_USE_STRFUNC 0
#define FF_PRINT_LLI 0
#define FF_PRINT_FLOAT 0
#define FF_STRF_ENCODE 3
/* FF_USE_STRFUNC switches the string API functions, f_gets(), f_putc(), f_puts()
/ and f_printf().
/
/ 0: Disable. FF_PRINT_LLI, FF_PRINT_FLOAT and FF_STRF_ENCODE have no effect.
/ 1: Enable without LF - CRLF conversion.
/ 2: Enable with LF - CRLF conversion.
/
/ FF_PRINT_LLI = 1 makes f_printf() support long long argument and FF_PRINT_FLOAT = 1/2
/ makes f_printf() support floating point argument. These features want C99 or later.
/ When FF_LFN_UNICODE >= 1 with LFN enabled, string API functions convert the character
/ encoding in it. FF_STRF_ENCODE selects assumption of character encoding ON THE FILE
/ to be read/written via those functions.
/
/ 0: ANSI/OEM in current CP
/ 1: Unicode in UTF-16LE
/ 2: Unicode in UTF-16BE
/ 3: Unicode in UTF-8
*/
/*---------------------------------------------------------------------------/
/ Locale and Namespace Configurations
/---------------------------------------------------------------------------*/
#define FF_CODE_PAGE 932
/* This option specifies the OEM code page to be used on the target system.
/ Incorrect code page setting can cause a file open failure.
/
/ 437 - U.S.
/ 720 - Arabic
/ 737 - Greek
/ 771 - KBL
/ 775 - Baltic
/ 850 - Latin 1
/ 852 - Latin 2
/ 855 - Cyrillic
/ 857 - Turkish
/ 860 - Portuguese
/ 861 - Icelandic
/ 862 - Hebrew
/ 863 - Canadian French
/ 864 - Arabic
/ 865 - Nordic
/ 866 - Russian
/ 869 - Greek 2
/ 932 - Japanese (DBCS)
/ 936 - Simplified Chinese (DBCS)
/ 949 - Korean (DBCS)
/ 950 - Traditional Chinese (DBCS)
/ 0 - Include all code pages above and configured by f_setcp()
*/
#define FF_USE_LFN 2
#define FF_MAX_LFN 255
/* The FF_USE_LFN switches the support for LFN (long file name).
/
/ 0: Disable LFN. FF_MAX_LFN has no effect.
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
/ 2: Enable LFN with dynamic working buffer on the STACK.
/ 3: Enable LFN with dynamic working buffer on the HEAP.
/
/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN feature
/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
/ be in range of 12 to 255. It is recommended to be set 255 to fully support the LFN
/ specification.
/ When use stack for the working buffer, take care on stack overflow. When use heap
/ memory for the working buffer, memory management functions, ff_memalloc() and
/ ff_memfree() exemplified in ffsystem.c, need to be added to the project. */
#define FF_LFN_UNICODE 0
/* This option switches the character encoding on the API when LFN is enabled.
/
/ 0: ANSI/OEM in current CP (TCHAR = char)
/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
/ 2: Unicode in UTF-8 (TCHAR = char)
/ 3: Unicode in UTF-32 (TCHAR = DWORD)
/
/ Also behavior of string I/O functions will be affected by this option.
/ When LFN is not enabled, this option has no effect. */
#define FF_LFN_BUF 255
#define FF_SFN_BUF 12
/* This set of options defines size of file name members in the FILINFO structure
/ which is used to read out directory items. These values should be suffcient for
/ the file names to read. The maximum possible length of the read file name depends
/ on character encoding. When LFN is not enabled, these options have no effect. */
#define FF_FS_RPATH 2
/* This option configures support for relative path.
/
/ 0: Disable relative path and remove related API functions.
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
/ 2: f_getcwd() is available in addition to 1.
*/
/*---------------------------------------------------------------------------/
/ Drive/Volume Configurations
/---------------------------------------------------------------------------*/
#define FF_VOLUMES 1
/* Number of volumes (logical drives) to be used. (1-10) */
#define FF_STR_VOLUME_ID 0
#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
/ logical drive. Number of items must not be less than FF_VOLUMES. Valid
/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
/ not defined, a user defined volume string table is needed as:
/
/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
*/
#define FF_MULTI_PARTITION 0
/* This option switches support for multiple volumes on the physical drive.
/ By default (0), each logical drive number is bound to the same physical drive
/ number and only an FAT volume found on the physical drive will be mounted.
/ When this feature is enabled (1), each logical drive number can be bound to
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
/ will be available. */
#define FF_MIN_SS 512
#define FF_MAX_SS 512
/* This set of options configures the range of sector size to be supported. (512,
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
/ harddisk, but a larger value may be required for on-board flash memory and some
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is
/ configured for variable sector size mode and disk_ioctl() needs to implement
/ GET_SECTOR_SIZE command. */
#define FF_LBA64 0
/* This option switches support for 64-bit LBA. (0:Disable or 1:Enable)
/ To enable the 64-bit LBA, also exFAT needs to be enabled. (FF_FS_EXFAT == 1) */
#define FF_MIN_GPT 0x10000000
/* Minimum number of sectors to switch GPT as partitioning format in f_mkfs() and
/ f_fdisk(). 2^32 sectors maximum. This option has no effect when FF_LBA64 == 0. */
#define FF_USE_TRIM 0
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
/ To enable this feature, also CTRL_TRIM command should be implemented to
/ the disk_ioctl(). */
/*---------------------------------------------------------------------------/
/ System Configurations
/---------------------------------------------------------------------------*/
#define FF_FS_TINY 0
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
/ Instead of private sector buffer eliminated from the file object, common sector
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
#define FF_FS_EXFAT 0
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
#define FF_FS_NORTC 1
#define FF_NORTC_MON 11
#define FF_NORTC_MDAY 1
#define FF_NORTC_YEAR 2024
/* The option FF_FS_NORTC switches timestamp feature. If the system does not have
/ an RTC or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable the
/ timestamp feature. Every object modified by FatFs will have a fixed timestamp
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() need to be added
/ to the project to read current time form real-time clock. FF_NORTC_MON,
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
/ These options have no effect in read-only configuration (FF_FS_READONLY = 1). */
#define FF_FS_NOFSINFO 0
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/ option, and f_getfree() at the first time after volume mount will force
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/
/ bit0=0: Use free cluster count in the FSINFO if available.
/ bit0=1: Do not trust free cluster count in the FSINFO.
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
*/
#define FF_FS_LOCK 0
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
/ is 1.
/
/ 0: Disable file lock function. To avoid volume corruption, application program
/ should avoid illegal open, remove and rename to the open objects.
/ >0: Enable file lock function. The value defines how many files/sub-directories
/ can be opened simultaneously under file lock control. Note that the file
/ lock control is independent of re-entrancy. */
#define FF_FS_REENTRANT 0
#define FF_FS_TIMEOUT 1000
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
/ module itself. Note that regardless of this option, file access to different
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
/ and f_fdisk(), are always not re-entrant. Only file/directory access to
/ the same volume is under control of this featuer.
/
/ 0: Disable re-entrancy. FF_FS_TIMEOUT have no effect.
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
/ ff_mutex_create(), ff_mutex_delete(), ff_mutex_take() and ff_mutex_give(),
/ must be added to the project. Samples are available in ffsystem.c.
/
/ The FF_FS_TIMEOUT defines timeout period in unit of O/S time tick.
*/
/*--- End of configuration options ---*/

View File

@ -1479,7 +1479,8 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
wolfSSH_SFTP_buffer_data(&state->buffer),
wolfSSH_SFTP_buffer_size(&state->buffer));
break;
#if !defined(_WIN32_WCE) && !defined(WOLFSSH_ZEPHYR)
#if !defined(_WIN32_WCE) && !defined(WOLFSSH_ZEPHYR) && \
!defined(WOLFSSH_FATFS)
case WOLFSSH_FTP_SETSTAT:
ret = wolfSSH_SFTP_RecvSetSTAT(ssh, state->reqId,
wolfSSH_SFTP_buffer_data(&state->buffer),
@ -4689,6 +4690,10 @@ static int SFTP_GetAttributes(void* fs, const char* fileName,
FRESULT ret;
int sz = (int)WSTRLEN(fileName);
(void) fs;
(void) noFollow;
(void) heap;
ret = f_stat(fileName, &info);
if (ret != FR_OK)
return -1;
@ -5191,7 +5196,7 @@ int wolfSSH_SFTP_RecvLSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
}
#if !defined(USE_WINDOWS_API) && !defined(WOLFSSH_ZEPHYR) \
&& !defined(WOLFSSH_SFTP_SETMODE)
&& !defined(WOLFSSH_SFTP_SETMODE) && !defined(WOLFSSH_FATFS)
/* Set the files mode
* return WS_SUCCESS on success */
static int SFTP_SetMode(void* fs, char* name, word32 mode) {
@ -5204,7 +5209,7 @@ static int SFTP_SetMode(void* fs, char* name, word32 mode) {
#endif
#if !defined(USE_WINDOWS_API) && !defined(WOLFSSH_ZEPHYR) \
&& !defined(WOLFSSH_SFTP_SETMODEHANDLE)
&& !defined(WOLFSSH_SFTP_SETMODEHANDLE) && !defined(WOLFSSH_FATFS)
/* Set the files mode
* return WS_SUCCESS on success */
static int SFTP_SetModeHandle(void* fs, WFD handle, word32 mode) {
@ -5216,7 +5221,7 @@ static int SFTP_SetModeHandle(void* fs, WFD handle, word32 mode) {
}
#endif
#if !defined(_WIN32_WCE) && !defined(WOLFSSH_ZEPHYR)
#if !defined(_WIN32_WCE) && !defined(WOLFSSH_ZEPHYR) && !defined(WOLFSSH_FATFS)
/* sets a files attributes
* returns WS_SUCCESS on success */

View File

@ -101,7 +101,7 @@ extern "C" {
#endif
#endif /* !WOLFSSH_HANDLE */
#ifdef NO_FILESYSTEM
#if defined(NO_FILESYSTEM) && !defined(WOLFSSH_FATFS)
#define WS_DELIM '/'
#elif defined(WOLFSSL_NUCLEUS)
#include "storage/nu_storage.h"
@ -255,6 +255,7 @@ extern "C" {
#define WSEEK_SET 0
#define WSEEK_CUR 1
#define WSEEK_END 2
#define WFFLUSH(s) ((void)(s))
static inline int ff_fopen(WFILE** f, const char* filename,
const char* mode)
{
@ -264,11 +265,12 @@ extern "C" {
if (!f) {
return -1;
}
#ifdef WOLFSSH_XILFATFS
m = FA_CREATE_ALWAYS;
if (*f == 0) {
*f = WMALLOC(sizeof(FIL), NULL, 0);
}
#ifdef WOLFSSH_XILFATFS
m = FA_CREATE_ALWAYS;
#else
m = FA_CREATE_NEW;
#endif
@ -585,7 +587,8 @@ extern "C" {
#if (defined(WOLFSSH_SFTP) || \
defined(WOLFSSH_SCP) || defined(WOLFSSH_SSHD)) && \
!defined(NO_WOLFSSH_SERVER) && !defined(NO_FILESYSTEM)
!defined(NO_WOLFSSH_SERVER) && \
(!defined(NO_FILESYSTEM) || defined(WOLFSSH_FATFS))
#ifndef SIZEOF_OFF_T
/* if not using autoconf then make a guess on off_t size based on sizeof
@ -1192,7 +1195,7 @@ extern "C" {
#define WSTAT(fs,p,b) f_stat(p,b)
#define WLSTAT(fs,p,b) f_stat(p,b)
#define WREMOVE(fs,d) f_unlink((d))
#define WRENAME(fs,fd,o,n) f_rename((o),(n))
#define WRENAME(fs,o,n) f_rename((o),(n))
#define WMKDIR(fs, p, m) f_mkdir(p)
#define WFD int

View File

@ -52,6 +52,10 @@ extern "C" {
#define USE_WOLFSSH_MEMORY /* default memory handlers */
#endif /* WMALLOC_USER */
/* SFTP requires storehandle when fatfs is in use */
#ifdef WOLFSSH_FATFS
#define WOLFSSH_STOREHANDLE
#endif
#if defined (_WIN32)
#define USE_WINDOWS_API