mirror of
https://github.com/lora-aprs/LoRa_APRS_iGate.git
synced 2025-12-06 07:42:00 +01:00
FTP lib got added again in correct version
This commit is contained in:
parent
b658ed2ed6
commit
75024a2617
5
lib/ESP-FTP-Server-Lib/.gitignore
vendored
5
lib/ESP-FTP-Server-Lib/.gitignore
vendored
|
|
@ -1,5 +0,0 @@
|
||||||
.pio
|
|
||||||
.vscode/.browse.c_cpp.db*
|
|
||||||
.vscode/c_cpp_properties.json
|
|
||||||
.vscode/launch.json
|
|
||||||
.vscode/ipch
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
@ -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=
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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");
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -12,7 +12,7 @@ lib_deps =
|
||||||
sandeepmistry/LoRa @ 0.7.2
|
sandeepmistry/LoRa @ 0.7.2
|
||||||
peterus/APRS-Decoder-Lib @ 0.0.5
|
peterus/APRS-Decoder-Lib @ 0.0.5
|
||||||
peterus/APRS-IS-Lib @ 0.0.7
|
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
|
peterus/LoRa-APRS-Lib @ 0.0.5
|
||||||
check_tool = cppcheck
|
check_tool = cppcheck
|
||||||
check_flags =
|
check_flags =
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue