FTP lib got added again in correct version

pull/14/head
Peter Buchegger 2020-11-05 23:25:59 +01:00
rodzic b658ed2ed6
commit 75024a2617
30 zmienionych plików z 1 dodań i 1386 usunięć

Wyświetl plik

@ -1,5 +0,0 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

Wyświetl plik

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2020 Peter Buchegger
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Wyświetl plik

@ -1,34 +0,0 @@
# ESP-FTP-Server-Lib
This library will provide a simple and modern FTP server for your ESP32 or ESP8266 device.
You can setup multiple users and mutliple filesystems (SD-Card, MMC-Card or/and SPIFFS).
## Examples
In the example folder you can find a very simple usage of the FTP server. You just need to setup the users, add the filesystems which you want to use, and call the handle function in the loop.
## Known Commands to the server
Currently all kind of simple commands are known to the server:
* CDUP
* CWD
* DELE
* LISST
* MKD
* PORT
* PWD
* RETR
* RMD
* RNFR
* RNTO
* STOR
* TYPE
* SYST
* QUIT
* ABOR
## What is still missing / TODO
Some commands are still missing, if you need them create a ticket :)
Currently just the active mode is supported. For the passive mode you need to wait until version 1.0.0.

Wyświetl plik

@ -1,11 +0,0 @@
name=ESP-FTP-Server-Lib
version=0.9.3
author=Peter Buchegger <peter@pbuchegger.at>
maintainer=Peter Buchegger <peter@pbuchegger.at>
sentence=Simple and modern FTP server for ESP devices.
paragraph=With this library you can run a simple and modern FTP server on your ESP32 or ESP8266. You can mount multiple filesystems like SD-Card, MMC-Card or SPIFFS at the same time.
category=Communication
url=https://github.com/peterus/ESP-FTP-Server-Lib
architectures=esp8266,esp32,arduino-esp32
includes=ESP-FTP-Server-Lib.h
depends=

Wyświetl plik

@ -1,9 +0,0 @@
[env:ttgo-lora32-v1]
platform = espressif32
board = ttgo-lora32-v1
framework = arduino
test_build_project_src = yes
monitor_speed = 115200
check_flags =
cppcheck: --suppress=*:*.pio\* --suppress=unusedFunction

Wyświetl plik

@ -1,19 +0,0 @@
#ifndef CDUP_H_
#define CDUP_H_
#include <WiFiClient.h>
#include "../FTPCommand.h"
class CDUP : public FTPCommand
{
public:
explicit CDUP(WiFiClient * const Client) : FTPCommand("CDUP", 0, Client) {}
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
{
WorkDirectory.goPathUp();
SendResponse(250, "Ok. Current directory is " + WorkDirectory.getPath());
}
};
#endif

Wyświetl plik

@ -1,37 +0,0 @@
#ifndef CWD_H_
#define CWD_H_
#include <WiFiClient.h>
#include "../FTPCommand.h"
class CWD : public FTPCommand
{
public:
explicit CWD(WiFiClient * const Client, FTPFilesystem * const Filesystem) : FTPCommand("CWD", 1, Client, Filesystem) {}
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
{
FTPPath path = WorkDirectory;
Serial.println(Line[1]);
if(Line[1] == "..")
{
path.goPathUp();
}
else
{
path.changePath(Line[1]);
}
File dir = _Filesystem->open(path.getPath());
if(dir.isDirectory())
{
WorkDirectory = path;
SendResponse(250, "Ok. Current directory is " + WorkDirectory.getPath());
}
else
{
SendResponse(550, "Directory does not exist");
}
}
};
#endif

Wyświetl plik

@ -1,31 +0,0 @@
#ifndef DELE_H_
#define DELE_H_
#include <WiFiClient.h>
#include "../FTPCommand.h"
class DELE : public FTPCommand
{
public:
explicit DELE(WiFiClient * const Client, FTPFilesystem * const Filesystem) : FTPCommand("DELE", 1, Client, Filesystem) {}
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
{
String filepath = WorkDirectory.getFilePath(Line[1]);
if(!_Filesystem->exists(filepath))
{
SendResponse(550, "File " + filepath + " not found");
return;
}
if(_Filesystem->remove(filepath))
{
SendResponse(250, " Deleted \"" + filepath + "\"");
}
else
{
SendResponse(450, "Can't delete \"" + filepath + "\"");
}
}
};
#endif

Wyświetl plik

@ -1,58 +0,0 @@
#ifndef LIST_H_
#define LIST_H_
#include <WiFiClient.h>
#include "../FTPCommand.h"
#include "../common.h"
class LIST : public FTPCommand
{
public:
explicit LIST(WiFiClient * const Client, FTPFilesystem * const Filesystem, IPAddress * DataAddress, int * DataPort)
: FTPCommand("LIST", 1, Client, Filesystem, DataAddress, DataPort)
{}
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
{
if(!ConnectDataConnection())
{
return;
}
File dir = _Filesystem->open(WorkDirectory.getPath());
if(!dir || !dir.isDirectory())
{
CloseDataConnection();
SendResponse(550, "Can't open directory " + WorkDirectory.getPath());
return;
}
int cnt = 0;
File f = dir.openNextFile();
while(f)
{
String filename = f.name();
filename.remove(0, filename.lastIndexOf('/') + 1);
if(f.isDirectory())
{
data_print("drwxr-xr-x");
}
else
{
data_print("-rw-r--r--");
}
String filesize = String(f.size());
data_print(" 1 owner group ");
int fill_cnt = 13 - filesize.length();
for(int i = 0; i < fill_cnt; i++)
{
data_print(" ");
}
data_println(filesize + " Jan 01 1970 " + filename);
cnt++;
f = dir.openNextFile();
}
CloseDataConnection();
SendResponse(226, String(cnt) + " matches total");
}
};
#endif

Wyświetl plik

@ -1,31 +0,0 @@
#ifndef MKD_H_
#define MKD_H_
#include <WiFiClient.h>
#include "../FTPCommand.h"
class MKD : public FTPCommand
{
public:
explicit MKD(WiFiClient * const Client, FTPFilesystem * const Filesystem) : FTPCommand("MKD", 1, Client, Filesystem) {}
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
{
String filepath = WorkDirectory.getFilePath(Line[1]);
if(_Filesystem->exists(filepath))
{
SendResponse(521, "Can't create \"" + filepath + "\", Directory exists");
return;
}
if(_Filesystem->mkdir(filepath))
{
SendResponse(257, "\"" + filepath + "\" created");
}
else
{
SendResponse(550, "Can't create \"" + filepath + "\"");
}
}
};
#endif

Wyświetl plik

@ -1,27 +0,0 @@
#ifndef PORT_H_
#define PORT_H_
#include <WiFiClient.h>
#include "../FTPCommand.h"
#include "../common.h"
class PORT : public FTPCommand
{
public:
explicit PORT(WiFiClient * const Client, IPAddress * DataAddress, int * DataPort)
: FTPCommand("PORT", 1, Client, 0, DataAddress, DataPort)
{}
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
{
std::vector<String> connection_details = Split<std::vector<String>>(Line[1], ',');
for(int i = 0; i < 4; i++)
{
(*_DataAddress)[i] = connection_details[i].toInt();
}
*_DataPort = connection_details[4].toInt() * 256 + connection_details[5].toInt();
SendResponse(200, "PORT command successful");
}
};
#endif

Wyświetl plik

@ -1,18 +0,0 @@
#ifndef PWD_H_
#define PWD_H_
#include <WiFiClient.h>
#include "../FTPCommand.h"
class PWD : public FTPCommand
{
public:
explicit PWD(WiFiClient * const Client) : FTPCommand("PWD", 0, Client) {}
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
{
SendResponse(257, "\"" + WorkDirectory.getPath() + "\" is your current directory");
}
};
#endif

Wyświetl plik

@ -1,55 +0,0 @@
#ifndef RETR_H_
#define RETR_H_
#include <WiFiClient.h>
#include "../FTPCommand.h"
#include "../common.h"
#define FTP_BUF_SIZE 4096
class RETR : public FTPCommandTransfer
{
public:
explicit RETR(WiFiClient * const Client, FTPFilesystem * const Filesystem, IPAddress * DataAddress, int * DataPort)
: FTPCommandTransfer("RETR", 1, Client, Filesystem, DataAddress, DataPort)
{}
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
{
if(trasferInProgress())
{
return;
}
if(!ConnectDataConnection())
{
return;
}
String path = WorkDirectory.getFilePath(Line[1]);
_file = _Filesystem->open(path);
if(!_file || _file.isDirectory())
{
CloseDataConnection();
SendResponse(550, "Can't open " + path);
return;
}
workOnData();
}
void workOnData() override
{
uint8_t buffer[FTP_BUF_SIZE];
size_t nb = _file.read(buffer, FTP_BUF_SIZE);
if(nb > 0)
{
data_send(buffer, nb);
return;
}
CloseDataConnection();
SendResponse(226, "File successfully transferred");
_file.close();
}
private:
};
#endif

Wyświetl plik

@ -1,31 +0,0 @@
#ifndef RMD_H_
#define RMD_H_
#include <WiFiClient.h>
#include "../FTPCommand.h"
class RMD : public FTPCommand
{
public:
explicit RMD(WiFiClient * const Client, FTPFilesystem * const Filesystem) : FTPCommand("RMD", 1, Client, Filesystem) {}
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
{
String filepath = WorkDirectory.getFilePath(Line[1]);
if(!_Filesystem->exists(filepath))
{
SendResponse(550, "Folder " + filepath + " not found");
return;
}
if(_Filesystem->rmdir(filepath))
{
SendResponse(250, " Deleted \"" + filepath + "\"");
}
else
{
SendResponse(450, "Can't delete \"" + filepath + "\"");
}
}
};
#endif

Wyświetl plik

@ -1,67 +0,0 @@
#ifndef RNFR_H_
#define RNFR_H_
#include <WiFiClient.h>
#include "../FTPCommand.h"
class RNFR_RNTO : public FTPCommand
{
public:
explicit RNFR_RNTO(WiFiClient * const Client, FTPFilesystem * const Filesystem) : FTPCommand("RN", 1, Client, Filesystem), _fromSet(false) {}
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
{
if(Line[0] == "RNFR")
{
from(WorkDirectory, Line);
}
else if(Line[0] == "RNTO")
{
to(WorkDirectory, Line);
}
}
void from(const FTPPath & WorkDirectory, const std::vector<String> & Line)
{
String filepath = WorkDirectory.getFilePath(Line[1]);
if(!_Filesystem->exists(filepath))
{
SendResponse(550, "File " + Line[1] + " not found");
return;
}
_fromSet = true;
_from = filepath;
SendResponse(350, "RNFR accepted - file exists, ready for destination");
}
void to(const FTPPath & WorkDirectory, const std::vector<String> & Line)
{
if(!_fromSet)
{
SendResponse(503, "Need RNFR before RNTO");
return;
}
String filepath = WorkDirectory.getFilePath(Line[1]);
if(_Filesystem->exists(filepath))
{
SendResponse(553, "File " + Line[1] + " already exists");
return;
}
if(_Filesystem->rename(_from, filepath))
{
SendResponse(250, "File successfully renamed or moved");
}
else
{
SendResponse(451, "Rename/move failure");
}
_fromSet = false;
_from = "";
}
private:
bool _fromSet;
String _from;
};
#endif

Wyświetl plik

@ -1,55 +0,0 @@
#ifndef STOR_H_
#define STOR_H_
#include <WiFiClient.h>
#include "../FTPCommand.h"
#include "../common.h"
#define FTP_BUF_SIZE 4096
class STOR : public FTPCommandTransfer
{
public:
explicit STOR(WiFiClient * const Client, FTPFilesystem * const Filesystem, IPAddress * DataAddress, int * DataPort)
: FTPCommandTransfer("STOR", 1, Client, Filesystem, DataAddress, DataPort)
{}
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
{
if(trasferInProgress())
{
return;
}
if(!ConnectDataConnection())
{
return;
}
String path = WorkDirectory.getFilePath(Line[1]);
_file = _Filesystem->open(path, "w");
if(!_file)
{
CloseDataConnection();
SendResponse(451, "Can't open/create " + path);
return;
}
workOnData();
}
void workOnData() override
{
uint8_t buffer[FTP_BUF_SIZE];
int nb = data_read(buffer, FTP_BUF_SIZE);
if(nb > 0)
{
_file.write(buffer, nb);
return;
}
CloseDataConnection();
SendResponse(226, "File successfully transferred");
_file.close();
}
private:
};
#endif

Wyświetl plik

@ -1,28 +0,0 @@
#ifndef TYPE_H_
#define TYPE_H_
#include <WiFiClient.h>
#include "../FTPCommand.h"
class TYPE : public FTPCommand
{
public:
explicit TYPE(WiFiClient * const Client) : FTPCommand("TYPE", 1, Client) {}
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
{
if(Line[1] == "A")
{
SendResponse(200, "TYPE is now ASCII");
return;
}
else if(Line[1] == "I")
{
SendResponse(200, "TYPE is now 8-bit binary");
return;
}
SendResponse(504, "Unknow TYPE");
}
};
#endif

Wyświetl plik

@ -1,56 +0,0 @@
#include "ESP-FTP-Server-Lib.h"
FTPServer::FTPServer()
: _Server(FTP_CTRL_PORT, 1)
{
}
FTPServer::~FTPServer()
{
}
void FTPServer::addUser(const String & Username, const String & Password)
{
FTPUser user(Username, Password);
_UserList.push_back(user);
}
void FTPServer::addUser(const FTPUser & User)
{
_UserList.push_back(User);
}
void FTPServer::addFilesystem(String Name, FS * const Filesystem)
{
_Filesystem.addFilesystem(Name, Filesystem);
}
bool FTPServer::begin()
{
_Server.begin();
return true;
}
bool isNotConnected(const std::shared_ptr<FTPConnection> & con)
{
return !con->connected();
}
void FTPServer::handle()
{
if(_Server.hasClient())
{
std::shared_ptr<FTPConnection> connection = std::shared_ptr<FTPConnection>(new FTPConnection(_Server.available(), _UserList, _Filesystem));
_Connections.push_back(connection);
}
for(std::shared_ptr<FTPConnection> con: _Connections)
{
con->handle();
}
_Connections.remove_if(isNotConnected);
}
size_t FTPServer::countConnections() const
{
return _Connections.size();
}

Wyświetl plik

@ -1,38 +0,0 @@
#ifndef ESP_FTP_LIB_H_
#define ESP_FTP_LIB_H_
#include <list>
#include <Arduino.h>
#include "FTPUser.h"
#include "FTPConnection.h"
#include "FTPFilesystem.h"
class FTPServer
{
public:
FTPServer();
virtual ~FTPServer();
void addUser(const String & Username, const String & Password);
void addUser(const FTPUser & User);
void addFilesystem(String Name, FS * const Filesystem);
bool begin();
void handle();
size_t countConnections() const;
private:
WiFiServer _Server;
std::list<FTPUser> _UserList;
std::list<std::shared_ptr<FTPConnection>> _Connections;
FTPFilesystem _Filesystem;
};
#define FTP_DEBUG(txt) Serial.print("[DEBUG] "); Serial.println(txt)
#endif

Wyświetl plik

@ -1,133 +0,0 @@
#ifndef FTP_COMMAND_H_
#define FTP_COMMAND_H_
#include <WiFiClient.h>
#include <Arduino.h>
#include "FTPPath.h"
#include "FTPFilesystem.h"
class FTPCommand
{
public:
FTPCommand(String Name, int ExpectedArgumentCnt, WiFiClient * const Client, FTPFilesystem * const Filesystem = 0, IPAddress * DataAddress = 0, int * DataPort = 0)
: _Name(Name), _ExpectedArgumentCnt(ExpectedArgumentCnt),
_Filesystem(Filesystem),
_DataAddress(DataAddress), _DataPort(DataPort), _Client(Client), _DataConnection(0) {}
virtual ~FTPCommand() {}
String getName() const
{
return _Name;
}
virtual void run(FTPPath & WorkDirectory, const std::vector<String> & Line) = 0;
void SendResponse(int Code, String Text)
{
_Client->print(Code);
_Client->print(" ");
_Client->println(Text);
}
bool ConnectDataConnection()
{
if(_DataConnection == 0)
{
_DataConnection = new WiFiClient();
}
if(_DataConnection->connected())
{
_DataConnection->stop();
}
_DataConnection->connect(*_DataAddress, *_DataPort);
if(!_DataConnection->connected())
{
_DataConnection->stop();
SendResponse(425, "No data connection");
return false;
}
SendResponse(150, "Accepted data connection");
return true;
}
void data_print(String str)
{
if(_DataConnection == 0 || !_DataConnection->connected())
{
return;
}
_DataConnection->print(str);
}
void data_println(String str)
{
if(_DataConnection == 0 || !_DataConnection->connected())
{
return;
}
_DataConnection->println(str);
}
void data_send(uint8_t * c, size_t l)
{
if(_DataConnection == 0 || !_DataConnection->connected())
{
return;
}
_DataConnection->write(c, l);
}
int data_read(uint8_t * c, size_t l)
{
if(_DataConnection == 0 || !_DataConnection->connected())
{
return 0;
}
return _DataConnection->readBytes(c, l);
}
void CloseDataConnection()
{
_DataConnection->stop();
}
protected:
String _Name;
int _ExpectedArgumentCnt;
FTPFilesystem * const _Filesystem;
IPAddress * const _DataAddress;
int * const _DataPort;
private:
WiFiClient * const _Client;
WiFiClient * _DataConnection;
};
class FTPCommandTransfer : public FTPCommand
{
public:
FTPCommandTransfer(String Name, int ExpectedArgumentCnt, WiFiClient * const Client, FTPFilesystem * const Filesystem = 0, IPAddress * DataAddress = 0, int * DataPort = 0)
: FTPCommand(Name, ExpectedArgumentCnt, Client, Filesystem, DataAddress, DataPort) {}
virtual void workOnData() = 0;
bool trasferInProgress()
{
return _file;
}
void abort()
{
if(_file)
{
CloseDataConnection();
SendResponse(426, "Transfer aborted");
_file.close();
}
}
protected:
File _file;
};
#endif

Wyświetl plik

@ -1,207 +0,0 @@
#include "ESP-FTP-Server-Lib.h"
#include "common.h"
#include "Commands/CDUP.h"
#include "Commands/CWD.h"
#include "Commands/DELE.h"
#include "Commands/LIST.h"
#include "Commands/MKD.h"
#include "Commands/PORT.h"
#include "Commands/PWD.h"
#include "Commands/RETR.h"
#include "Commands/RMD.h"
#include "Commands/RNFR_RNTO.h"
#include "Commands/STOR.h"
#include "Commands/TYPE.h"
FTPConnection::FTPConnection(const WiFiClient & Client, std::list<FTPUser> & UserList, FTPFilesystem & Filesystem)
: _ClientState(Idle), _Client(Client), _Filesystem(Filesystem), _UserList(UserList), _AuthUsername("")
{
std::shared_ptr<FTPCommandTransfer> retr = std::shared_ptr<FTPCommandTransfer>(new RETR(&_Client, &_Filesystem, &_DataAddress, &_DataPort));
std::shared_ptr<FTPCommandTransfer> stor = std::shared_ptr<FTPCommandTransfer>(new STOR(&_Client, &_Filesystem, &_DataAddress, &_DataPort));
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new CDUP(&_Client)));
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new CWD(&_Client, &_Filesystem)));
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new DELE(&_Client, &_Filesystem)));
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new LIST(&_Client, &_Filesystem, &_DataAddress, &_DataPort)));
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new MKD(&_Client, &_Filesystem)));
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new PORT(&_Client, &_DataAddress, &_DataPort)));
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new PWD(&_Client)));
_FTPCommands.push_back(retr);
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new RMD(&_Client, &_Filesystem)));
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new RNFR_RNTO(&_Client, &_Filesystem)));
_FTPCommands.push_back(stor);
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new TYPE(&_Client)));
_FTPCommandsTransfer.push_back(retr);
_FTPCommandsTransfer.push_back(stor);
Serial.print("New Connection from ");
Serial.print(_Client.remoteIP());
Serial.print(":");
Serial.println(_Client.remotePort());
_Client.println("220--- Welcome to FTP Server for ESP32 ---");
_Client.println("220--- By Peter Buchegger ---");
_Client.println("220 -- Version 0.1 ---");
}
FTPConnection::~FTPConnection()
{
Serial.println("Connection closed!");
}
bool FTPConnection::readUntilLineEnd()
{
while(_Client.available())
{
char c = _Client.read();
if(c == '\n')
{
_LineSplited = Split<std::vector<String>>(_Line, ' ');
return true;
}
if(c >= 32 && c < 127)
{
_Line += c;
}
}
return false;
}
bool FTPConnection::handle()
{
if(!_Client.connected())
{
return false;
}
for(std::shared_ptr<FTPCommandTransfer> cmd: _FTPCommandsTransfer)
{
if(cmd->trasferInProgress())
{
cmd->workOnData();
}
}
if(!readUntilLineEnd())
{
return true;
}
// we have a new command in the queue:
Serial.println(_Line);
String command = _LineSplited[0];
// This commands are always possible:
if(command == "SYST")
{
_Client.println("215 UNIX Type: L8");
_Line = "";
return true;
}
else if(command == "QUIT")
{
_Client.println("221 Goodbye");
_Client.stop();
_Line = "";
return true;
}
else if(command == "ABOR")
{
for(std::shared_ptr<FTPCommandTransfer> cmd: _FTPCommandsTransfer)
{
cmd->abort();
}
_Client.println("226 Data connection closed");
_Line = "";
return true;
}
// Logged in?
switch (_ClientState)
{
case Idle:
if(command == "USER")
{
c_USER();
}
break;
case UsernamePass:
if(command == "PASS")
{
c_PASS();
}
break;
case AuthPass:
{
std::vector<std::shared_ptr<FTPCommand>>::iterator cmdIter = std::find_if(_FTPCommands.begin(), _FTPCommands.end(), [&](std::shared_ptr<FTPCommand> cmd)
{
if(command == cmd->getName() || (cmd->getName() == "RN" && (command == "RNFR" || command == "RNTO")))
{
return true;
}
return false;
}
);
if(cmdIter != _FTPCommands.end())
{
(*cmdIter)->run(_WorkDirectory, _LineSplited);
_Line = "";
return true;
}
}
default:
_Client.println("500 Unknow command");
break;
}
_Line = "";
return true;
}
bool FTPConnection::connected()
{
return _Client.connected();
}
void FTPConnection::c_USER()
{
String username = _LineSplited[1];
std::list<FTPUser>::iterator userIter = std::find_if(_UserList.begin(), _UserList.end(), [&](const FTPUser & user)
{
if(username == user.Username)
{
return true;
}
return false;
}
);
if(userIter != _UserList.end())
{
_AuthUsername = username;
_Client.println("331 OK. Password required");
_ClientState = UsernamePass;
return;
}
_Client.println("530 user not found");
}
void FTPConnection::c_PASS()
{
String password = _LineSplited[1];
String username = _AuthUsername;
std::list<FTPUser>::iterator _user = std::find_if(_UserList.begin(), _UserList.end(), [&](const FTPUser & user)
{
if(username == user.Username && password == user.Password)
{
return true;
}
return false;
}
);
if(_user != _UserList.end())
{
_Client.println("230 OK.");
_ClientState = AuthPass;
return;
}
_Client.println("530 passwort not correct");
}

Wyświetl plik

@ -1,59 +0,0 @@
#ifndef FTP_CONNECTION_H_
#define FTP_CONNECTION_H_
#include <vector>
#include <WiFiServer.h>
#include "FTPPath.h"
#include "FTPCommand.h"
#define FTP_CTRL_PORT 21
#define FTP_USER_TIME_OUT 5
#define FTP_CMD_SIZE 255 + 8 // max size of a command
#define FTP_DIRNAME_SIZE 255 + 8 // max size of a directory name
#define FTP_FILENAME_SIZE 255 // max size of a file name
class FTPConnection
{
public:
FTPConnection(const WiFiClient & Client, std::list<FTPUser> & UserList, FTPFilesystem & Filesystem);
virtual ~FTPConnection();
bool readUntilLineEnd();
bool handle();
bool connected();
private:
enum ClientState
{
Idle,
UsernamePass,
AuthPass,
};
void c_USER();
void c_PASS();
ClientState _ClientState;
WiFiClient _Client;
FTPFilesystem & _Filesystem;
String _FilePath;
String _Line;
std::vector<String> _LineSplited;
std::list<FTPUser> & _UserList;
String _AuthUsername;
IPAddress _DataAddress;
int _DataPort;
FTPPath _WorkDirectory;
std::vector<std::shared_ptr<FTPCommand>> _FTPCommands;
std::vector<std::shared_ptr<FTPCommandTransfer>> _FTPCommandsTransfer;
};
#endif

Wyświetl plik

@ -1,120 +0,0 @@
#include "FTPFilesystem.h"
#include "common.h"
FTPFilesystem::FTPFilesystem()
{
}
FTPFilesystem::~FTPFilesystem()
{
}
void FTPFilesystem::addFilesystem(String Name, FS * const Filesystem)
{
_Filesystems[Name] = Filesystem;
}
void FTPFilesystem::clearFilesystemList()
{
_Filesystems.clear();
}
File FTPFilesystem::open(const String & path, const char* mode)
{
if(path == "/")
{
std::shared_ptr<FTPFileImpl> root = std::shared_ptr<FTPFileImpl>(new FTPFileImpl("/"));
for(auto const & f: _Filesystems)
{
root->addFilesystem(f.first);
}
return File(root);
}
FS * fs = getFilesystem(path);
return fs->open(getPathWithoutFS(path), mode);
}
bool FTPFilesystem::exists(const String & path)
{
FS * fs = getFilesystem(path);
if(fs == 0)
{
return false;
}
return fs->exists(getPathWithoutFS(path));
}
bool FTPFilesystem::remove(const String & path)
{
FS * fs = getFilesystem(path);
if(fs == 0)
{
return false;
}
return fs->remove(getPathWithoutFS(path));
}
bool FTPFilesystem::rename(const String & pathFrom, const String & pathTo)
{
FS * fsFrom = getFilesystem(pathFrom);
FS * fsTo = getFilesystem(pathTo);
if(fsFrom == 0 || fsTo == 0)
{
return false;
}
if(fsFrom != fsTo)
{
// cant move/rename from one filesystem to another one!
return false;
}
return fsFrom->rename(getPathWithoutFS(pathFrom), getPathWithoutFS(pathTo));
}
bool FTPFilesystem::mkdir(const String & path)
{
FS * fs = getFilesystem(path);
if(fs == 0)
{
return false;
}
return fs->mkdir(getPathWithoutFS(path));
}
bool FTPFilesystem::rmdir(const String & path)
{
FS * fs = getFilesystem(path);
if(fs == 0)
{
return false;
}
return fs->rmdir(getPathWithoutFS(path));
}
void FTPFilesystem::printFilesystems()
{
for (auto const & fs: _Filesystems)
{
Serial.println(fs.first);
}
}
FS * FTPFilesystem::getFilesystem(String path)
{
std::list<String> splitted = FTPPath::splitPath(path);
String name = *(splitted.begin());
std::map<String, fs::FS *>::iterator iter = _Filesystems.find(name);
if(iter == _Filesystems.end())
{
Serial.println("[ERROR] Filesystem not found!");
return 0;
}
return iter->second;
}
String FTPFilesystem::getPathWithoutFS(String path)
{
std::list<String> splitted = FTPPath::splitPath(path);
splitted.pop_front();
String path_without = FTPPath::createPath(splitted);
return path_without;
}

Wyświetl plik

@ -1,70 +0,0 @@
#ifndef FTP_FILESYSTEM_H_
#define FTP_FILESYSTEM_H_
#include <map>
#include <FS.h>
#include <FSImpl.h>
#include "FTPPath.h"
class FTPFilesystem
{
public:
FTPFilesystem();
virtual ~FTPFilesystem();
void addFilesystem(String Name, FS * const Filesystem);
void clearFilesystemList();
File open(const String & path, const char* mode = FILE_READ);
bool exists(const String & path);
bool remove(const String & path);
bool rename(const String & pathFrom, const String & pathTo);
bool mkdir(const String & path);
bool rmdir(const String & path);
void printFilesystems();
#ifndef UNIT_TEST
private:
#endif
FS * getFilesystem(String path);
static String getPathWithoutFS(String path);
std::map<String, FS *> _Filesystems;
};
class FTPFileImpl : public fs::FileImpl
{
public:
explicit FTPFileImpl(String name) : _Name(name) {}
~FTPFileImpl() {}
size_t write(const uint8_t *buf, size_t size) override { return 0; };
size_t read(uint8_t* buf, size_t size) override { return 0; };
void flush() override {};
bool seek(uint32_t pos, SeekMode mode) override { return false; };
size_t position() const override { return 0; };
size_t size() const override { return 0; };
void close() override {};
time_t getLastWrite() override { return 0; };
const char* name() const override { return _Name.c_str(); };
boolean isDirectory(void) override { return true; };
fs::FileImplPtr openNextFile(const char* mode) override
{
if(_Filesystems.empty())
{
return 0;
}
String next = _Filesystems.front();
_Filesystems.pop_front();
return fs::FileImplPtr(new FTPFileImpl(next));
}
void rewindDirectory(void) override {};
operator bool() override { return false; };
void addFilesystem(String name) { _Filesystems.push_back(name); }
private:
String _Name;
std::list<String> _Filesystems;
};
#endif

Wyświetl plik

@ -1,75 +0,0 @@
#include "FTPPath.h"
#include "common.h"
FTPPath::FTPPath()
{
}
FTPPath::FTPPath(String path)
{
changePath(path);
}
FTPPath::~FTPPath()
{
}
void FTPPath::changePath(String path)
{
std::list<String> p = splitPath(path);
std::copy(p.begin(), p.end(), std::back_inserter(_Path));
}
void FTPPath::goPathUp()
{
_Path.pop_back();
}
String FTPPath::getPath() const
{
return createPath(_Path);
}
String FTPPath::getFilePath(String filename) const
{
if(*filename.begin() == '/')
{
return filename;
}
if(_Path.size() == 0)
{
return "/" + filename;
}
return getPath() + "/" + filename;
}
std::list<String> FTPPath::splitPath(String path)
{
std::list<String> p = Split<std::list<String>>(path, '/');
p.erase(
std::remove_if(p.begin(), p.end(), [](const String & s)
{
if(s.isEmpty())
{
return true;
}
return false;
}),
p.end());
return p;
}
String FTPPath::createPath(std::list<String> path)
{
if(path.size() == 0)
{
return "/";
}
String new_path;
for(const String & p: path)
{
new_path += "/";
new_path += p;
}
return new_path;
}

Wyświetl plik

@ -1,27 +0,0 @@
#ifndef FTP_PATH_H_
#define FTP_PATH_H_
#include <Arduino.h>
#include <list>
class FTPPath
{
public:
FTPPath();
explicit FTPPath(String path);
virtual ~FTPPath();
void changePath(String path);
void goPathUp();
String getPath() const;
String getFilePath(String filename) const;
static std::list<String> splitPath(String path);
static String createPath(std::list<String> path);
private:
std::list<String> _Path;
};
#endif

Wyświetl plik

@ -1,14 +0,0 @@
#ifndef FTP_USER_H_
#define FTP_USER_H_
#include <Arduino.h>
class FTPUser
{
public:
FTPUser(const String & username, const String & password) : Username(username), Password(password) {}
const String Username;
const String Password;
};
#endif

Wyświetl plik

@ -1,22 +0,0 @@
#include "common.h"
/*
template <typename T>
T Split(String str, char parser)
{
T str_array;
int last_idx = 0;
int next_idx = str.indexOf(parser, last_idx);
do
{
str_array.push_back(str.substring(last_idx, next_idx));
last_idx = next_idx + 1;
next_idx = str.indexOf(parser, last_idx);
if(next_idx == -1 && last_idx != 0)
{
str_array.push_back(str.substring(last_idx, str.length()));
}
} while (next_idx != -1);
return str_array;
}
*/

Wyświetl plik

@ -1,27 +0,0 @@
#ifndef COMMON_H_
#define COMMON_H_
#include <Arduino.h>
#include <list>
#include <vector>
template <typename T>
T Split(String str, char parser)
{
T str_array;
int last_idx = 0;
int next_idx = str.indexOf(parser, last_idx);
do
{
str_array.push_back(str.substring(last_idx, next_idx));
last_idx = next_idx + 1;
next_idx = str.indexOf(parser, last_idx);
if(next_idx == -1 && last_idx != 0)
{
str_array.push_back(str.substring(last_idx, str.length()));
}
} while (next_idx != -1);
return str_array;
}
#endif

Wyświetl plik

@ -12,7 +12,7 @@ lib_deps =
sandeepmistry/LoRa @ 0.7.2
peterus/APRS-Decoder-Lib @ 0.0.5
peterus/APRS-IS-Lib @ 0.0.7
peterus/ESP-FTP-Server-Lib @ 0.9.2
peterus/ESP-FTP-Server-Lib @ 0.9.3
peterus/LoRa-APRS-Lib @ 0.0.5
check_tool = cppcheck
check_flags =