From ae58bc6bccf4538263d75f9f3183bdee92e1d69b Mon Sep 17 00:00:00 2001 From: Philipp Toelke Date: Wed, 23 Apr 2014 20:02:42 +0200 Subject: [PATCH] Add API-Code and README --- README.md | 22 +++++++-- vfs.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ vfs.h | 85 +++++++++++++++++++++++++++++++++++ 3 files changed, 234 insertions(+), 3 deletions(-) create mode 100644 vfs.c create mode 100644 vfs.h diff --git a/README.md b/README.md index 15bd139..2ec759c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,20 @@ -lwip-ftpd -========= - FTP server for lwip and tinyfatfs +================================= + +This repository contains the ftp-server for lwip Copyright (c) 2002 Florian +Schulze and an API translation layer Copyright (c) 2013 Philipp Tölke. + +The translation layer translates between the vfs-API the ftp server uses and +the well known tinyfatfs by ChaN, which can be downloaded at +http://elm-chan.org/fsw/ff/00index_e.html . + +The translation-layer + +* is not reentrant and it is possible that multiple + concurrent ftp-connections are *not* supported. +* relies on malloc(). It would be easy to change this to use a pooled allocator +* does not use long filenames for any function apart from getcwd(). + +All code in this repository is licensed under a 3-clause BSD license + +Patches, comments and pull-requests are wellcome. diff --git a/vfs.c b/vfs.c new file mode 100644 index 0000000..1b2e313 --- /dev/null +++ b/vfs.c @@ -0,0 +1,130 @@ +/* Copyright (c) 2013, Philipp Tölke + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "vfs.h" +#include +#include +#include + +/* dirent that will be given to callers; + * note: both APIs assume that only one dirent ever exists + */ +vfs_dirent_t dir_ent; + +/* This file object is returned when the filesystem is opened */ +FIL guard_for_the_whole_fs; + +int vfs_read (void* buffer, int dummy, int len, vfs_file_t* file) { + unsigned int bytesread; + FRESULT r = f_read(file, buffer, len, &bytesread); + if (r != FR_OK) return 0; + return bytesread; +} + +vfs_dirent_t* vfs_readdir(vfs_dir_t* dir) { + FILINFO fi; + fi.lfname = NULL; + FRESULT r = f_readdir(dir, &fi); + if (r != FR_OK) return NULL; + if (fi.fname[0] == 0) return NULL; + memcpy(dir_ent.name, fi.fname, sizeof(fi.fname)); + return &dir_ent; +} + +int vfs_stat(vfs_t* vfs, const char* filename, vfs_stat_t* st) { + FILINFO f; + f.lfname = NULL; + if (FR_OK != f_stat(filename, &f)) { + return 1; + } + st->st_size = f.fsize; + st->st_mode = f.fattrib; + st->st_mtime.date = f.fdate; + st->st_mtime.time = f.ftime; + return 0; +} + +void vfs_close(vfs_t* vfs) { + if (vfs != &guard_for_the_whole_fs) { + f_close(vfs); + } +} + +int vfs_write (void* buffer, int dummy, int len, vfs_file_t* file) { + unsigned int byteswritten; + FRESULT r = f_write(file, buffer, len, &byteswritten); + if (r != FR_OK) return 0; + return byteswritten; +} + +vfs_t* vfs_openfs() { + return &guard_for_the_whole_fs; +} + +vfs_file_t* vfs_open(vfs_t* vfs, const char* filename, const char* mode) { + vfs_file_t *f = malloc(sizeof(vfs_file_t)); + BYTE flags = 0; + while (*mode != '\0') { + if (*mode == 'r') flags |= FA_READ; + if (*mode == 'w') flags |= FA_WRITE | FA_CREATE_ALWAYS; + mode++; + } + FRESULT r = f_open(f, filename, flags); + if (FR_OK != r) { + free(f); + return NULL; + } + return f; +} + +char* vfs_getcwd(vfs_t* vfs, void* dummy1, int dummy2) { + char* cwd = malloc(255); + FRESULT r = f_getcwd(cwd, 255); + if (r != FR_OK) { + free(cwd); + return NULL; + } + return cwd; +} + +vfs_dir_t* vfs_opendir(vfs_t* vfs, const char* path) { + vfs_dir_t* dir = malloc(sizeof *dir); + FRESULT r = f_opendir(dir, path); + if (FR_OK != r) { + free(dir); + return NULL; + } + return dir; +} + +void vfs_closedir(vfs_dir_t* dir) { + free(dir); +} + +struct tm dummy; +struct tm* gmtime(time_t* c_t) { + return &dummy; +} diff --git a/vfs.h b/vfs.h new file mode 100644 index 0000000..c17a654 --- /dev/null +++ b/vfs.h @@ -0,0 +1,85 @@ +/* Copyright (c) 2013, Philipp Tölke + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef INCLUDE_VFS_H +#define INCLUDE_VFS_H + +#include +#include + +#define vfs_load_plugin(x) +#define bcopy(src, dest, len) memmove(dest, src, len) + + +typedef struct { + short date; + short time; +} time_t; +typedef DIR vfs_dir_t; +typedef FIL vfs_file_t; +typedef struct { + int st_size; + char st_mode; + time_t st_mtime; +} vfs_stat_t; +typedef struct { + char name[13]; +} vfs_dirent_t; +typedef FIL vfs_t; + +struct tm { + int tm_year; + int tm_mon; + int tm_mday; + int tm_hour; + int tm_min; +}; + +#define time(x) +#define vfs_eof f_eof +#define VFS_ISDIR(st_mode) ((st_mode) & AM_DIR) +#define VFS_ISREG(st_mode) !((st_mode) & AM_DIR) +#define vfs_rename(vfs, from, to) f_rename(from, to) +#define VFS_IRWXU 0 +#define VFS_IRWXG 0 +#define VFS_IRWXO 0 +#define vfs_mkdir(vfs, name, mode) f_mkdir(name) +#define vfs_rmdir(vfs, name) f_unlink(name) +#define vfs_remove(vfs, name) f_unlink(name) +#define vfs_chdir(vfs, dir) f_chdir(dir) +char* vfs_getcwd(vfs_t* vfs, void*, int dummy); +int vfs_read (void* buffer, int dummy, int len, vfs_file_t* file); +int vfs_write (void* buffer, int dummy, int len, vfs_file_t* file); +vfs_dirent_t* vfs_readdir(vfs_dir_t* dir); +vfs_file_t* vfs_open(vfs_t* vfs, const char* filename, const char* mode); +vfs_t* vfs_openfs(); +void vfs_close(vfs_t* vfs); +int vfs_stat(vfs_t* vfs, const char* filename, vfs_stat_t* st); +void vfs_closedir(vfs_dir_t* dir); +vfs_dir_t* vfs_opendir(vfs_t* vfs, const char* path); +struct tm* gmtime(time_t *c_t); + +#endif /* INCLUDE_VFS_H */