Skip to content

Commit f4f31a7

Browse files
authored
Merge pull request #5 from akoro/master
New FTP-commands
2 parents 51cf7fc + f5c065f commit f4f31a7

File tree

6 files changed

+137
-6
lines changed

6 files changed

+137
-6
lines changed

src/Commands/LIST.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ class LIST : public FTPCommand
1111
explicit LIST(WiFiClient * const Client, FTPFilesystem * const Filesystem, IPAddress * DataAddress, int * DataPort)
1212
: FTPCommand("LIST", 1, Client, Filesystem, DataAddress, DataPort)
1313
{}
14-
14+
1515
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
1616
{
1717
if(!ConnectDataConnection())
1818
{
1919
return;
2020
}
21-
File dir = _Filesystem->open(WorkDirectory.getPath());
21+
File dir = _Filesystem->open(WorkDirectory.getPath()); //
2222
if(!dir || !dir.isDirectory())
2323
{
2424
CloseDataConnection();
@@ -48,6 +48,7 @@ class LIST : public FTPCommand
4848
}
4949
data_println(filesize + " Jan 01 1970 " + filename);
5050
cnt++;
51+
f.close();
5152
f = dir.openNextFile();
5253
}
5354
CloseDataConnection();

src/Commands/MLSD.h

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#ifndef MSLD_H_
2+
#define MSLD_H_
3+
// Copyright (c) 2020 Arkady Korotkevich
4+
// Based on LIST.h by Peter Buchegger
5+
#include <WiFiClient.h>
6+
#include "../FTPCommand.h"
7+
#include "../common.h"
8+
#include <time.h>
9+
10+
class MLSD : public FTPCommand
11+
{
12+
public:
13+
explicit MLSD(WiFiClient * const Client, FTPFilesystem * const Filesystem, IPAddress * DataAddress, int * DataPort)
14+
: FTPCommand("MLSD", 1, Client, Filesystem, DataAddress, DataPort)
15+
{}
16+
17+
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
18+
{
19+
if(!ConnectDataConnection())
20+
{
21+
return;
22+
}
23+
24+
File root = _Filesystem->open(WorkDirectory.getPath(), "r");
25+
26+
if(!root || !root.isDirectory())
27+
{
28+
root.close();
29+
CloseDataConnection();
30+
SendResponse(550, "Can't open directory " + WorkDirectory.getPath());
31+
return;
32+
}
33+
34+
int cnt = 0;
35+
File f = root.openNextFile();
36+
while(f)
37+
{
38+
// type=
39+
data_print("type=");
40+
if(f.isDirectory())
41+
data_print("dir;");
42+
else
43+
data_print("file;");
44+
45+
// size=
46+
if(f.isDirectory())
47+
data_print("sizd=");
48+
else
49+
data_print("size=");
50+
data_print(String(f.size()));
51+
data_print(";");
52+
53+
// modify=YYYYMMDDHHMMSS; // GMT (!!!!)
54+
char buf[128];
55+
time_t ft = f.getLastWrite();
56+
struct tm *t = localtime(&ft);
57+
sprintf(buf,"modify=%4d%02d%02d%02d%02d%02d;",
58+
(t->tm_year)+1900,
59+
(t->tm_mon)+1,
60+
t->tm_mday,
61+
t->tm_hour,
62+
t->tm_min,
63+
t->tm_sec
64+
);
65+
data_print(String(buf));
66+
67+
// UNIX.mode=
68+
data_print("UNIX.mode=0700;");
69+
70+
// <filename>
71+
data_print(" ");
72+
String filename = f.name();
73+
filename.remove(0, filename.lastIndexOf('/') + 1);
74+
data_println(filename);
75+
76+
cnt++;
77+
f = root.openNextFile();
78+
}
79+
80+
root.close();
81+
CloseDataConnection();
82+
SendResponse(226, String(cnt) + " matches total");
83+
}
84+
};
85+
86+
#endif

src/ESP-FTP-Server-Lib.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
#include "ESP-FTP-Server-Lib.h"
22

3-
FTPServer::FTPServer()
4-
: _Server(FTP_CTRL_PORT, 1)
3+
FTPServer::FTPServer():
4+
#if defined(ESP32)
5+
_Server(FTP_CTRL_PORT, 1)
6+
#elif defined(ESP8266)
7+
_Server(FTP_CTRL_PORT)
8+
#endif
59
{
610
}
711

src/FTPConnection.cpp

+25-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "Commands/RNFR_RNTO.h"
1717
#include "Commands/STOR.h"
1818
#include "Commands/TYPE.h"
19+
#include "Commands/MLSD.h"
1920

2021
FTPConnection::FTPConnection(const WiFiClient & Client, std::list<FTPUser> & UserList, FTPFilesystem & Filesystem)
2122
: _ClientState(Idle), _Client(Client), _Filesystem(Filesystem), _UserList(UserList), _AuthUsername("")
@@ -27,6 +28,7 @@ FTPConnection::FTPConnection(const WiFiClient & Client, std::list<FTPUser> & Use
2728
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new CWD(&_Client, &_Filesystem)));
2829
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new DELE(&_Client, &_Filesystem)));
2930
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new LIST(&_Client, &_Filesystem, &_DataAddress, &_DataPort)));
31+
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new MLSD(&_Client, &_Filesystem, &_DataAddress, &_DataPort)));
3032
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new MKD(&_Client, &_Filesystem)));
3133
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new PORT(&_Client, &_DataAddress, &_DataPort)));
3234
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new PWD(&_Client)));
@@ -114,6 +116,28 @@ bool FTPConnection::handle()
114116
_Line = "";
115117
return true;
116118
}
119+
/** Additional commads begin ************************************* by Akoro */
120+
else if(command == "OPTS") // need for Win10 ftp
121+
{
122+
_Client.println("500 not implemented");
123+
_Line = "";
124+
return true;
125+
}
126+
else if(command == "NOOP")
127+
{
128+
_Client.println("200 Ok");
129+
_Line = "";
130+
return true;
131+
}
132+
else if(command == "FEAT")
133+
{
134+
_Client.println("211- Extensions suported:");
135+
_Client.println(" MLSD");
136+
_Client.println("211 End.");
137+
_Line = "";
138+
return true;
139+
}
140+
/** Additional commads end ************************************* by Akoro */
117141
else if(command == "QUIT")
118142
{
119143
_Client.println("221 Goodbye");
@@ -246,5 +270,5 @@ void FTPConnection::c_PASS()
246270
_ClientState = AuthPass;
247271
return;
248272
}
249-
_Client.println("530 passwort not correct");
273+
_Client.println("530 password not correct");
250274
}

src/FTPFilesystem.h

+15
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,20 @@ class FTPFileImpl : public fs::FileImpl
4747
void close() override {};
4848
time_t getLastWrite() override { return 0; };
4949
const char* name() const override { return _Name.c_str(); };
50+
#if defined(ESP32)
5051
boolean isDirectory(void) override { return true; };
52+
#elif defined(ESP8266)
53+
boolean isDirectory(void) const override { return true; };
54+
const char* fullName() const override {return ("/"+_Name).c_str();};
55+
bool isFile() const override { return true; };
56+
bool truncate(uint32_t size) override { return true; };
57+
#endif
58+
59+
#if defined(ESP32)
5160
fs::FileImplPtr openNextFile(const char* mode) override
61+
#elif defined(ESP8266)
62+
fs::FileImplPtr openNextFile(const char* mode)
63+
#endif
5264
{
5365
if(_Filesystems.empty())
5466
{
@@ -58,8 +70,11 @@ class FTPFileImpl : public fs::FileImpl
5870
_Filesystems.pop_front();
5971
return fs::FileImplPtr(new FTPFileImpl(next));
6072
}
73+
74+
#if defined(ESP32)
6175
void rewindDirectory(void) override {};
6276
operator bool() override { return false; };
77+
#endif
6378

6479
void addFilesystem(String name) { _Filesystems.push_back(name); }
6580
private:

src/FTPPath.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ void FTPPath::changePath(String path)
2222

2323
void FTPPath::goPathUp()
2424
{
25-
_Path.pop_back();
25+
if(_Path.size() != 0) // Added Akoro 2021-02-27
26+
_Path.pop_back();
2627
}
2728

2829
String FTPPath::getPath() const

0 commit comments

Comments
 (0)