From f2b7a722ee4d8c2621fe87419adc50ac7c0b9bfb Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Mon, 17 Jan 2022 05:13:58 +0100 Subject: [PATCH] Add service commands, update CHANGELOG and About #283 --- CHANGLELOG.md | 3 + data/script.js | 2 +- data/script.js.gz | Bin 1225 -> 1266 bytes lib/SimpleFTPServer/FtpServer.cpp | 3409 +++++++++++++++-------------- lib/SimpleFTPServer/FtpServer.h | 1 + src/hasp/hasp_dispatch.cpp | 8 + src/sys/svc/hasp_ftp.cpp | 29 +- 7 files changed, 1761 insertions(+), 1691 deletions(-) diff --git a/CHANGLELOG.md b/CHANGLELOG.md index ca55f036..b7b5b06f 100644 --- a/CHANGLELOG.md +++ b/CHANGLELOG.md @@ -50,6 +50,9 @@ Update libraries to ArduinoJson 6.19.1, TFT_eSPI 2.4.25, LovyanGFX 0.4.11 and Ad ### Objects - Add `antiburn` command to prevent static parts of the screen to create a *ghosting* effect in some LCDs or conditions +## Services +- Add SimpleFTPServer to easily upload and download files to the plate *(one simultanious connection only)* + ### Devices - Add Analog touch driver for Unoshield displays (thanks @wesleygas) - Add Arduitouch MOD ESP32 with 2.4" or 2.8" diff --git a/data/script.js b/data/script.js index 9a8e4bea..0b00a6e0 100644 --- a/data/script.js +++ b/data/script.js @@ -1 +1 @@ -function aref(e){setTimeout(function(){ref("")},1e3*e)}function ref(e){var o=(new Date).getTime();return document.getElementById("bmp").src="?a="+e+"&q="+o,!1}function about(){document.getElementById("doc").innerHTML='

openHASP

Copyright© 2019-2021 Francis Van Roie
MIT License

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.


Based on the previous work of the following open source developers:

HASwitchPlate

Copyright© 2019 Allen Derusha allen @derusha.org
MIT License

LVGL

Copyright© 2021 LVGL Kft
MIT License

zi Font Engine

Copyright© 2020-2021 Francis Van Roie
MIT License

TFT_eSPI Library

Copyright© 2020 Bodmer (https://github.com/Bodmer) All rights reserved.
FreeBSD License

includes parts from the Adafruit_GFX library
Copyright© 2012 Adafruit Industries. All rights reserved
BSD License

ArduinoJson

Copyright© 2014-2021 Benoit BLANCHON
MIT License

PubSubClient

Copyright© 2008-2015 Nicholas O'Leary
MIT License

ArduinoLog

Copyright© 2017,2018 Thijs Elenbaas, MrRobot62, rahuldeo2047, NOX73, dhylands, Josha blemasle, mfalkvidd
MIT License

QR Code generator

Copyright© Project Nayuki
MIT License

AceButton

Copyright© 2018 Brian T. Park
MIT License

'} \ No newline at end of file +function aref(e){setTimeout(function(){ref("")},1e3*e)}function ref(e){var o=(new Date).getTime();return document.getElementById("bmp").src="?a="+e+"&q="+o,!1}function about(){document.getElementById("doc").innerHTML='

openHASP

Copyright© 2019-2021 Francis Van Roie
MIT License

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.


Based on the previous work of the following open source developers:

HASwitchPlate

Copyright© 2019 Allen Derusha allen @derusha.org
MIT License

LVGL

Copyright© 2021 LVGL Kft
MIT License

zi Font Engine

Copyright© 2020-2021 Francis Van Roie
MIT License

TFT_eSPI Library

Copyright© 2020 Bodmer (https://github.com/Bodmer) All rights reserved.
FreeBSD License

includes parts from the Adafruit_GFX library
Copyright© 2012 Adafruit Industries. All rights reserved
BSD License

ArduinoJson

Copyright© 2014-2021 Benoit BLANCHON
MIT License

PubSubClient

Copyright© 2008-2015 Nicholas O'Leary
MIT License

ArduinoLog

Copyright© 2017,2018 Thijs Elenbaas, MrRobot62, rahuldeo2047, NOX73, dhylands, Josha blemasle, mfalkvidd
MIT License

QR Code generator

Copyright© Project Nayuki
MIT License

SimpleFTPServer

Copyright© 2017 Renzo Mischianti www.mischianti.org All right reserved.
MIT License

AceButton

Copyright© 2018 Brian T. Park
MIT License

'} \ No newline at end of file diff --git a/data/script.js.gz b/data/script.js.gz index 35c934fdf305fa7cab702dbc9f93fbd7159ebafa..a093c05f52ff4dd95520121c40001ac5abe21497 100644 GIT binary patch literal 1266 zcmVvZ0CQtfEdYI6X6Rcm+BKoI>aBOeqr(pukI(Ey=DLlTqJ z$0yGw8OYj@jk}w2(Bpr1Hau#z^c)UkcV_O~xicB&O_gabDqs@lUF`i*s1v?K(dh2Z z*6sZ=#!jdA+j@kL?_=-xK5QFx$s~w3-3nJQW*U3_#RjI^do58nvVvS>%@QkZEKZ5$ zakzH#ZYN#VonBwb>`mt_d((M<4?1^$(66xWJi5xmQes3z4#JRuV0cxboF+5x&Arp& z@j%pAP3<^5J)*-%)N9EXg}$57(`z_6e)RI;$??e}m`GM-T)`(+K_oby9;I?Ha})4* zhLxgoJvglgA<89J%FrR_0wtzvSWv9S+=9781TlxKU~+*LXaTHRLyb~VfJimt6|WY+ zz@#^xx*!-O=6b~>l5-ABDUoqTczeBATmGDvsJgm9=)~KAPOr_8BP)SdU~D@Rthg>n zFOaCT&K&OqS zOGTF(rL4A$BM=f4mZibqsHoU${5D=%7;%WfR--oasu0U-zDDXf4G<;8HYOLKM4R(F zW}0qV_qixbu`y(67!{D>RyWLz z%IvS2q~V}6wVzW9Y9US1|7z{;NK74wgGut)jvR1f2&3SWJ9fs%0CWqAbqL z@sqym(-k@3R~TV>pU%9);Is>k1ALh4LjXTHOhl!@sTRD#TcC~)?A8Og$t3xPap=;0 zDw$m0h73cI(>{W3p>?fZ9UU!bp*3kg6U(EGsb@smEi{P=@{uPA$SUI()E` z#Flx(EAgIo<1O>>WTW#CD?#aop6!pOfqzKmuu0=49hDp_eHirk#X~}V3O>&YQ8ER= zT~-VA+CwV*0Q8QoCln8`?_LO(mPK(eAKa}+1XPo7(} zYQ8*wY(ZYEOWM`s`CgczPfJ`fRiXvUIV&$Nd7dAl^^rD`$PpG;p=4UfL+nB++J6+E zt(yye2rlN!y2MEm#-@Mrwo)O&>ZgDiS6RW$-vq2ytNwC-H1F!wOk9oWL4h+IHd^00 c4KH9Q2^^9>giK!C1afEdYI6X6Rc&+9KoI^bD<2dz(pulOq5(pQh9oAb z+E30US;*Ot!@Em6==k5=JD^%Eonat%yZh|3FL{`^O`*AHfJvNpvG-G<&iE2VtGhc} zxA)T+JDuJy=Mg@>kG)@4VcVz+CPBREHh2kRrm@#wY+$;**AjIr8z@E5F0s+Z;?-y# zhikv=cJk$_)9Wi)yy?7UZ#oa~LFevw`W4QdM}P9LoEQ<2y)a}T7~V7}r`arcbMLr% zJP<2vrfwP^AJAbWR%^)@mA+fh(`z_7eDw0+(c#e}m`K(XT)`*SKq5FEALMc{^D_u| zfsLZ`YH++7#3+|sDMN>xE0mb8VL`DPO9$o>5yTvdipd2!parmI4J(w20z|GEZ+No+ z1}44n)D^)fG1r$&A~~19loADJgm=|1X3L-R8dXx3LQ(+fu$(<-29@gYSrd7SCs=LH_&;j z=~9_X+bPGEaR5Ss!n!sX92FINjo-#g3)388upmBCEiO%Qg=k7{YErMZbIU3;`*VR%>{b98p^35OVaKq#n(fY{DnxCr2v$Oxr2p00-;tPlkVcd2vzvI}rw}L6Cx7gXq2s1>?l|z-&!*97 z2IP^rVRi=51l;fpKKS9-0q;wkcxehz0{$!xe2?z@a1@-5{qO{a6cQVYJ!G?Y~Nhpgq z^TMp}hjazrCwhi->IQ+$T7!lN2?VTO~Tq2X4vcvgP{g$>a;v8-lwo-!!8m*hPTfl&w)pRQ;PcS%hnJ_+Zx( zSC%br#Cy`lTlV3}rq4rc1f?4WZaA7o;l4JmM^YqFA}p{$$+VFB*u_%Vf0U4| n+jG9R$^wV2*0+x21q>x;4PfW#4OrT$CdI -FtpServer::FtpServer( uint16_t _cmdPort, uint16_t _pasvPort ) - : ftpServer( _cmdPort ), dataServer( _pasvPort ) +FtpServer::FtpServer(uint16_t _cmdPort, uint16_t _pasvPort) : ftpServer(_cmdPort), dataServer(_pasvPort) { - cmdPort = _cmdPort; - pasvPort = _pasvPort; + cmdPort = _cmdPort; + pasvPort = _pasvPort; - millisDelay = 0; - nbMatch = 0; - iCL = 0; + millisDelay = 0; + nbMatch = 0; + iCL = 0; - iniVariables(); + iniVariables(); } -void FtpServer::begin( const char * _user, const char * _pass, const char * _welcomeMessage ) +void FtpServer::end() { - // Tells the ftp server to begin listening for incoming connection - ftpServer.begin(); - #if defined(ESP8266) || FTP_SERVER_NETWORK_TYPE_SELECTED == NETWORK_SEEED_RTL8720DN - ftpServer.setNoDelay( true ); - #endif -// localIp = _localIP == FTP_NULLIP() || (uint32_t) _localIP == 0 ? NET_CLASS.localIP() : _localIP ; - localIp = NET_CLASS.localIP(); //_localIP == FTP_NULLIP() || (uint32_t) _localIP == 0 ? NET_CLASS.localIP() : _localIP ; -// strcpy( user, FTP_USER ); -// strcpy( pass, FTP_PASS ); - if( strlen( _user ) > 0 && strlen( _user ) < FTP_CRED_SIZE ) { - //strcpy( user, _user ); - this->user = _user; - }else{ -// strcpy( user, FTP_USER ); - this->user = FTP_USER; - } - if( strlen( _pass ) > 0 && strlen( _pass ) < FTP_CRED_SIZE ) { -// strcpy( pass, _pass ); - this->pass = _pass; - }else{ -// strcpy( pass, FTP_PASS ); - this->pass = FTP_PASS; - } + if(client.connected()) { + disconnectClient(); + } -// strcpy(_welcomeMessage, welcomeMessage); + ftpServer.end(); + dataServer.end(); + DEBUG_PRINTLN(F("Stop server!")); - this->welcomeMessage = _welcomeMessage; + cmdStage = FTP_Init; +} - dataServer.begin(); +void FtpServer::begin(const char* _user, const char* _pass, const char* _welcomeMessage) +{ + // Tells the ftp server to begin listening for incoming connection + ftpServer.begin(); #if defined(ESP8266) || FTP_SERVER_NETWORK_TYPE_SELECTED == NETWORK_SEEED_RTL8720DN - dataServer.setNoDelay( true ); + ftpServer.setNoDelay(true); +#endif + // localIp = _localIP == FTP_NULLIP() || (uint32_t) _localIP == 0 ? NET_CLASS.localIP() : _localIP ; + localIp = + NET_CLASS.localIP(); //_localIP == FTP_NULLIP() || (uint32_t) _localIP == 0 ? NET_CLASS.localIP() : _localIP ; + // strcpy( user, FTP_USER ); + // strcpy( pass, FTP_PASS ); + if(strlen(_user) > 0 && strlen(_user) < FTP_CRED_SIZE) { + // strcpy( user, _user ); + this->user = _user; + } else { + // strcpy( user, FTP_USER ); + this->user = FTP_USER; + } + if(strlen(_pass) > 0 && strlen(_pass) < FTP_CRED_SIZE) { + // strcpy( pass, _pass ); + this->pass = _pass; + } else { + // strcpy( pass, FTP_PASS ); + this->pass = FTP_PASS; + } + + // strcpy(_welcomeMessage, welcomeMessage); + + this->welcomeMessage = _welcomeMessage; + + dataServer.begin(); +#if defined(ESP8266) || FTP_SERVER_NETWORK_TYPE_SELECTED == NETWORK_SEEED_RTL8720DN + dataServer.setNoDelay(true); #endif - millisDelay = 0; - cmdStage = FTP_Stop; - iniVariables(); + millisDelay = 0; + cmdStage = FTP_Stop; + iniVariables(); } -void FtpServer::credentials( const char * _user, const char * _pass ) +void FtpServer::credentials(const char* _user, const char* _pass) { - if( strlen( _user ) > 0 && strlen( _user ) < FTP_CRED_SIZE ) -// strcpy( user, _user ); - this->user = user; - if( strlen( _pass ) > 0 && strlen( _pass ) < FTP_CRED_SIZE ) -// strcpy( pass, _pass ); - this->pass = _pass; + if(strlen(_user) > 0 && strlen(_user) < FTP_CRED_SIZE) + // strcpy( user, _user ); + this->user = user; + if(strlen(_pass) > 0 && strlen(_pass) < FTP_CRED_SIZE) + // strcpy( pass, _pass ); + this->pass = _pass; } void FtpServer::iniVariables() { - // Default for data port - dataPort = FTP_DATA_PORT_DFLT; - - // Default Data connection is Active - dataConn = FTP_NoConn; - - // Set the root directory - strcpy( cwdName, "/" ); + // Default for data port + dataPort = FTP_DATA_PORT_DFLT; - rnfrCmd = false; - transferStage = FTP_Close; + // Default Data connection is Active + dataConn = FTP_NoConn; + + // Set the root directory + strcpy(cwdName, "/"); + + rnfrCmd = false; + transferStage = FTP_Close; } -uint8_t FtpServer::handleFTP() { +uint8_t FtpServer::handleFTP() +{ #ifdef FTP_ADDITIONAL_DEBUG -// int8_t data0 = data.status(); - ftpTransfer transferStage0 = transferStage; - ftpCmd cmdStage0 = cmdStage; - ftpDataConn dataConn0 = dataConn; + // int8_t data0 = data.status(); + ftpTransfer transferStage0 = transferStage; + ftpCmd cmdStage0 = cmdStage; + ftpDataConn dataConn0 = dataConn; #endif - if ((int32_t) (millisDelay - millis()) <= 0) { - if (cmdStage == FTP_Stop) { - if (client.connected()) { - DEBUG_PRINTLN(F("Disconnect client!")); - disconnectClient(); - } - cmdStage = FTP_Init; - } else if (cmdStage == FTP_Init) { // Ftp server waiting for connection - abortTransfer(); - iniVariables(); - DEBUG_PRINT(F(" Ftp server waiting for connection on port ")); - DEBUG_PRINTLN(cmdPort); + if((int32_t)(millisDelay - millis()) <= 0) { + if(cmdStage == FTP_Stop) { + if(client.connected()) { + DEBUG_PRINTLN(F("Disconnect client!")); + disconnectClient(); + } + cmdStage = FTP_Init; + } else if(cmdStage == FTP_Init) { // Ftp server waiting for connection + abortTransfer(); + iniVariables(); + DEBUG_PRINT(F(" Ftp server waiting for connection on port ")); + DEBUG_PRINTLN(cmdPort); - cmdStage = FTP_Client; - } else if (cmdStage == FTP_Client) { // Ftp server idle + cmdStage = FTP_Client; + } else if(cmdStage == FTP_Client) { // Ftp server idle #ifdef ESP8266 - if( ftpServer.hasClient()) - { - client.stop(); - client = ftpServer.available(); - } + if(ftpServer.hasClient()) { + client.stop(); + client = ftpServer.available(); + } #else - if (client && !client.connected()) { - client.stop(); - DEBUG_PRINTLN(F("CLIENT STOP!!")); - } - client = ftpServer.accept(); + if(client && !client.connected()) { + client.stop(); + DEBUG_PRINTLN(F("CLIENT STOP!!")); + } + client = ftpServer.accept(); #endif - if (client.connected()) // A client connected - { - clientConnected(); - millisEndConnection = millis() + 1000L * FTP_AUTH_TIME_OUT; // wait client id for 10 s. - cmdStage = FTP_User; - } - } else if (readChar() > 0) // got response - { - processCommand(); - if (cmdStage == FTP_Stop) - millisEndConnection = millis() + 1000L * FTP_AUTH_TIME_OUT; // wait authentication for 10 s. - else if (cmdStage < FTP_Cmd) - millisDelay = millis() + 200; // delay of 100 ms - else - millisEndConnection = millis() + 1000L * FTP_TIME_OUT; - } else if (!client.connected()) { - cmdStage = FTP_Init; - } - if (transferStage == FTP_Retrieve) // Retrieve data - { - if (!doRetrieve()) { - transferStage = FTP_Close; - } - } else if (transferStage == FTP_Store) // Store data - { - if (!doStore()) { - if (FtpServer::_callback) { - FtpServer::_callback(FTP_FREE_SPACE_CHANGE, free(), capacity()); - } + if(client.connected()) // A client connected + { + clientConnected(); + millisEndConnection = millis() + 1000L * FTP_AUTH_TIME_OUT; // wait client id for 10 s. + cmdStage = FTP_User; + } + } else if(readChar() > 0) // got response + { + processCommand(); + if(cmdStage == FTP_Stop) + millisEndConnection = millis() + 1000L * FTP_AUTH_TIME_OUT; // wait authentication for 10 s. + else if(cmdStage < FTP_Cmd) + millisDelay = millis() + 200; // delay of 100 ms + else + millisEndConnection = millis() + 1000L * FTP_TIME_OUT; + } else if(!client.connected()) { + cmdStage = FTP_Init; + } + if(transferStage == FTP_Retrieve) // Retrieve data + { + if(!doRetrieve()) { + transferStage = FTP_Close; + } + } else if(transferStage == FTP_Store) // Store data + { + if(!doStore()) { + if(FtpServer::_callback) { + FtpServer::_callback(FTP_FREE_SPACE_CHANGE, free(), capacity()); + } - transferStage = FTP_Close; - } - } else if (transferStage == FTP_List || transferStage == FTP_Nlst) // LIST or NLST - { - if (!doList()) { - transferStage = FTP_Close; - } - } else if (transferStage == FTP_Mlsd) // MLSD listing - { - if (!doMlsd()) { + transferStage = FTP_Close; + } + } else if(transferStage == FTP_List || transferStage == FTP_Nlst) // LIST or NLST + { + if(!doList()) { + transferStage = FTP_Close; + } + } else if(transferStage == FTP_Mlsd) // MLSD listing + { + if(!doMlsd()) { - transferStage = FTP_Close; - } - } else if (cmdStage > FTP_Client - && !((int32_t) (millisEndConnection - millis()) > 0)) { - client.println(F("530 Timeout")); - millisDelay = millis() + 200; // delay of 200 ms - cmdStage = FTP_Stop; - } + transferStage = FTP_Close; + } + } else if(cmdStage > FTP_Client && !((int32_t)(millisEndConnection - millis()) > 0)) { + client.println(F("530 Timeout")); + millisDelay = millis() + 200; // delay of 200 ms + cmdStage = FTP_Stop; + } #ifdef FTP_ADDITIONAL_DEBUG - if (cmdStage != cmdStage0 || transferStage != transferStage0 - || dataConn != dataConn0) { - DEBUG_PRINT(F(" Command Old: ")); - DEBUG_PRINT(cmdStage0); - DEBUG_PRINT(F(" Transfer Old: ")); - DEBUG_PRINT(transferStage0); - DEBUG_PRINT(F(" Data Old: ")); - DEBUG_PRINTLN(dataConn0); + if(cmdStage != cmdStage0 || transferStage != transferStage0 || dataConn != dataConn0) { + DEBUG_PRINT(F(" Command Old: ")); + DEBUG_PRINT(cmdStage0); + DEBUG_PRINT(F(" Transfer Old: ")); + DEBUG_PRINT(transferStage0); + DEBUG_PRINT(F(" Data Old: ")); + DEBUG_PRINTLN(dataConn0); - DEBUG_PRINT(F(" Command : ")); - DEBUG_PRINT(cmdStage); - DEBUG_PRINT(F(" Transfer : ")); - DEBUG_PRINT(transferStage); - DEBUG_PRINT(F(" Data : ")); - DEBUG_PRINTLN(dataConn); - } + DEBUG_PRINT(F(" Command : ")); + DEBUG_PRINT(cmdStage); + DEBUG_PRINT(F(" Transfer : ")); + DEBUG_PRINT(transferStage); + DEBUG_PRINT(F(" Data : ")); + DEBUG_PRINTLN(dataConn); + } #endif - } - return cmdStage | (transferStage << 3) | (dataConn << 6); + } + return cmdStage | (transferStage << 3) | (dataConn << 6); } void FtpServer::clientConnected() { - DEBUG_PRINTLN( F(" Client connected!") ); - client.print(F("220---")); client.print(welcomeMessage); client.println(F(" ---")); - client.println(F("220--- By Renzo Mischianti ---")); - client.print(F("220 -- Version ")); client.print(FTP_SERVER_VERSION); client.println(F(" --")); - iCL = 0; - if (FtpServer::_callback) { - FtpServer::_callback(FTP_CONNECT, free(), capacity()); - } - + DEBUG_PRINTLN(F(" Client connected!")); + client.print(F("220---")); + client.print(welcomeMessage); + client.println(F(" ---")); + client.println(F("220--- By Renzo Mischianti ---")); + client.print(F("220 -- Version ")); + client.print(FTP_SERVER_VERSION); + client.println(F(" --")); + iCL = 0; + if(FtpServer::_callback) { + FtpServer::_callback(FTP_CONNECT, free(), capacity()); + } } void FtpServer::disconnectClient() { - DEBUG_PRINTLN( F(" Disconnecting client") ); + DEBUG_PRINTLN(F(" Disconnecting client")); - abortTransfer(); - client.println(F("221 Goodbye") ); + abortTransfer(); + client.println(F("221 Goodbye")); - if (FtpServer::_callback) { - FtpServer::_callback(FTP_DISCONNECT, free(), capacity()); - } + if(FtpServer::_callback) { + FtpServer::_callback(FTP_DISCONNECT, free(), capacity()); + } - if( client ) { - } - if( data ) { - data.stop(); - } + if(client) { + } + if(data) { + data.stop(); + } } bool FtpServer::processCommand() { - /////////////////////////////////////// - // // - // AUTHENTICATION COMMANDS // - // // - /////////////////////////////////////// + /////////////////////////////////////// + // // + // AUTHENTICATION COMMANDS // + // // + /////////////////////////////////////// - // RoSchmi added the next two lines - DEBUG_PRINT("Command is: "); - DEBUG_PRINTLN(command); + // RoSchmi added the next two lines + DEBUG_PRINT("Command is: "); + DEBUG_PRINTLN(command); - // - // USER - User Identity - // - if( CommandIs( "USER" )) - { - if( ! strcmp( parameter, user )) - { - client.println(F("331 Ok. Password required") ); - strcpy( cwdName, "/" ); - cmdStage = FTP_Pass; - } - else - { - client.println(F("530 ") ); - cmdStage = FTP_Stop; - } - } - // - // PASS - Password - // - else if( CommandIs( "PASS" )) - { - if( cmdStage != FTP_Pass ) - { - client.println(F("503 ") ); - cmdStage = FTP_Stop; - } - if( ! strcmp( parameter, pass )) - { - DEBUG_PRINTLN( F(" Authentication Ok. Waiting for commands.") ); - - client.println(F("230 Ok") ); - cmdStage = FTP_Cmd; - } - else - { - client.println( F("530 ") ); - cmdStage = FTP_Stop; - } - } - // - // FEAT - New Features - // - else if( CommandIs( "FEAT" )) - { - client.println(F("211-Extensions suported:")); - client.println(F(" MLST type*;modify*;size*;") ); - client.println(F(" MLSD") ); - client.println(F(" MDTM") ); - client.println(F(" MFMT") ); - client.println(F(" SIZE") ); - client.println(F(" SITE FREE") ); - client.println(F("211 End.") ); - } - // - // AUTH - Not implemented - // - else if( CommandIs( "AUTH" )) - client.println(F("502 ") ); - // - // Unrecognized commands at stage of authentication - // - else if( cmdStage < FTP_Cmd ) - { - client.println(F("530 ") ); - cmdStage = FTP_Stop; - } - - /////////////////////////////////////// - // // - // ACCESS CONTROL COMMANDS // - // // - /////////////////////////////////////// - - // - // PWD - Print Directory - // - else if( CommandIs( "PWD" ) || - ( CommandIs( "CWD" ) && ParameterIs( "." ))) { - client.print( F("257 \"")); client.print( cwdName ); client.print( F("\"") ); client.println( F(" is your current directory") ); - // - // CDUP - Change to Parent Directory - // - } else if( CommandIs( "CDUP" ) || - ( CommandIs( "CWD" ) && ParameterIs( ".." ))) - { - bool ok = false; - - if( strlen( cwdName ) > 1 ) // do nothing if cwdName is root - { - // if cwdName ends with '/', remove it (must not append) - if( cwdName[ strlen( cwdName ) - 1 ] == '/' ) { - cwdName[ strlen( cwdName ) - 1 ] = 0; - } - // search last '/' - char * pSep = strrchr( cwdName, '/' ); - ok = pSep > cwdName; - // if found, ends the string on its position - if( ok ) - { - * pSep = 0; - ok = exists( cwdName ); - } - } - // if an error appends, move to root - if( ! ok ) { - strcpy( cwdName, "/" ); - } - client.print( F("250 Ok. Current directory is ") ); client.println( cwdName ); - } - // - // CWD - Change Working Directory - // - else if( CommandIs( "CWD" )) - { - char path[ FTP_CWD_SIZE ]; - if( haveParameter() && makeExistsPath( path )) - { - strcpy( cwdName, path ); - client.print( F("250 Directory changed to ") ); client.print(cwdName); client.println(); - } - } - // - // QUIT - // - else if( CommandIs( "QUIT" )) - { - client.println(F("221 Goodbye") ); - disconnectClient(); - cmdStage = FTP_Stop; - } - - /////////////////////////////////////// - // // - // TRANSFER PARAMETER COMMANDS // - // // - /////////////////////////////////////// - - // - // MODE - Transfer Mode - // - else if( CommandIs( "MODE" )) - { - if( ParameterIs( "S" )) { - client.println(F("200 S Ok") ); - } else { - client.println(F("504 Only S(tream) is suported") ); - } - } - // - // PASV - Passive Connection management - // - else if( CommandIs( "PASV" )) - { - data.stop(); - dataServer.begin(); - if((((uint32_t) NET_CLASS.localIP()) & ((uint32_t) NET_CLASS.subnetMask())) == - (((uint32_t) client.remoteIP()) & ((uint32_t) NET_CLASS.subnetMask()))) { - dataIp = NET_CLASS.localIP(); - } else { - dataIp = localIp; - } - dataPort = pasvPort; - DEBUG_PRINTLN( F(" Connection management set to passive") ); - DEBUG_PRINT( F(" Listening at ") ); - DEBUG_PRINT( int( dataIp[0]) ); DEBUG_PRINT( F(".") ); DEBUG_PRINT( int( dataIp[1]) ); DEBUG_PRINT( F(".") ); - DEBUG_PRINT( int( dataIp[2]) ); DEBUG_PRINT( F(".") ); DEBUG_PRINT( int( dataIp[3]) ); - DEBUG_PRINT( F(":") ); DEBUG_PRINTLN( dataPort ); - - client.print( F("227 Entering Passive Mode") ); client.print( F(" (") ); - client.print( int( dataIp[0]) ); client.print( F(",") ); client.print( int( dataIp[1]) ); client.print( F(",") ); - client.print( int( dataIp[2]) ); client.print( F(",") ); client.print( int( dataIp[3]) ); client.print( F(",") ); - client.print( ( dataPort >> 8 ) ); client.print( F(",") ); client.print( ( dataPort & 255 ) ); client.println( F(")") ); - dataConn = FTP_Pasive; - } - // - // PORT - Data Port - // - else if( CommandIs( "PORT" )) - { - data.stop(); - // get IP of data client - dataIp[ 0 ] = atoi( parameter ); - char * p = strchr( parameter, ',' ); - for( uint8_t i = 1; i < 4; i ++ ) - { - dataIp[ i ] = atoi( ++ p ); - p = strchr( p, ',' ); - } - // get port of data client - dataPort = 256 * atoi( ++ p ); - p = strchr( p, ',' ); - dataPort += atoi( ++ p ); - if( p == NULL ) { - client.println(F("501 Can't interpret parameters") ); - } else - { - DEBUG_PRINT( F(" Data IP set to ") ); DEBUG_PRINT( int( dataIp[0]) ); DEBUG_PRINT( F(".") ); DEBUG_PRINT( int( dataIp[1]) ); - DEBUG_PRINT( F(".") ); DEBUG_PRINT( int( dataIp[2]) ); DEBUG_PRINT( F(".") ); DEBUG_PRINTLN( int( dataIp[3]) ); - DEBUG_PRINT( F(" Data port set to ") ); DEBUG_PRINTLN( dataPort ); - - client.println(F("200 PORT command successful") ); - dataConn = FTP_Active; - } - } - // - // STRU - File Structure - // - else if( CommandIs( "STRU" )) - { - if( ParameterIs( "F" )) { - client.println(F("200 F Ok") ); - // else if( ParameterIs( "R" )) - // client.println(F("200 B Ok") ); - }else{ - client.println(F("504 Only F(ile) is suported") ); - } - } - // - // TYPE - Data Type - // - else if( CommandIs( "TYPE" )) - { - if( ParameterIs( "A" )) { - client.println(F("200 TYPE is now ASCII")); - } else if( ParameterIs( "I" )) { - client.println(F("200 TYPE is now 8-bit binary") ); - } else { - client.println(F("504 Unknow TYPE") ); - } - } - - /////////////////////////////////////// - // // - // FTP SERVICE COMMANDS // - // // - /////////////////////////////////////// - - // - // ABOR - Abort - // - else if( CommandIs( "ABOR" )) - { - abortTransfer(); - client.println(F("226 Data connection closed")); - } - // - // DELE - Delete a File - // - else if( CommandIs( "DELE" )) - { - char path[ FTP_CWD_SIZE ]; - if( haveParameter() && makeExistsPath( path )) { - if( remove( path )) { - if (FtpServer::_callback) { - FtpServer::_callback(FTP_FREE_SPACE_CHANGE, free(), capacity()); - } - - client.print( F("250 Deleted ") ); client.println( parameter ); - } else { - client.print( F("450 Can't delete ") ); client.println( parameter ); - } - } - } - // - // LIST - List - // NLST - Name List - // MLSD - Listing for Machine Processing (see RFC 3659) - // - else if( CommandIs( "LIST" ) || CommandIs( "NLST" ) || CommandIs( "MLSD" )) - { - DEBUG_PRINT("List of file!!"); - - if( dataConnect()){ - if( openDir( & dir )) - { - DEBUG_PRINT("Dir opened!!"); - - nbMatch = 0; - if( CommandIs( "LIST" )) - transferStage = FTP_List; - else if( CommandIs( "NLST" )) - transferStage = FTP_Nlst; - else - transferStage = FTP_Mlsd; - } - else { - DEBUG_PRINT("List Data stop!!"); - data.stop(); - } - } - } - // - // MLST - Listing for Machine Processing (see RFC 3659) - // - else if( CommandIs( "MLST" )) - { - char path[ FTP_CWD_SIZE ]; - uint16_t dat, tim; - char dtStr[ 15 ]; - bool isdir; - if( haveParameter() && makeExistsPath( path )){ - if( ! getFileModTime( path, & dat, & tim )) { - client.print( F("550 Unable to retrieve time for ") ); client.println( parameter ); - } else - { - isdir = isDir( path ); - client.println( F("250-Begin") ); - client.print( F(" Type=") ); client.print( ( isdir ? F("dir") : F("file")) ); - client.print( F(";Modify=") ); client.print( makeDateTimeStr( dtStr, dat, tim ) ); - if( ! isdir ) - { - if( openFile( path, FTP_FILE_READ )) - { - client.print( F(";Size=") ); client.print( long( fileSize( file )) ); - file.close(); - } - } - client.print( F("; ") ); client.println( path ); - client.println( F("250 End.") ); - } - } - } - // - // NOOP - // - else if( CommandIs( "NOOP" )) { - client.println(F("200 Zzz...") ); - } - // - // RETR - Retrieve - // - else if( CommandIs( "RETR" )) - { - char path[ FTP_CWD_SIZE ]; - if( haveParameter() && makeExistsPath( path )) { - if( ! openFile( path, FTP_FILE_READ )) { - client.print( F("450 Can't open ") ); client.print( parameter ); - } else if( dataConnect( false )) - { - DEBUG_PRINT( F(" Sending ") ); DEBUG_PRINT( parameter ); DEBUG_PRINT( F(" size ") ); DEBUG_PRINTLN( long( fileSize( file )) ); - - if (FtpServer::_transferCallback) { - FtpServer::_transferCallback(FTP_DOWNLOAD_START, path, long( fileSize( file ))); - } - - - client.print( F("150-Connected to port ") ); client.println( dataPort ); - client.print( F("150 ") ); client.print( long( fileSize( file )) ); client.println( F(" bytes to download") ); - millisBeginTrans = millis(); - bytesTransfered = 0; - transferStage = FTP_Retrieve; - } - } - } - // - // STOR - Store - // APPE - Append - // - else if( CommandIs( "STOR" ) || CommandIs( "APPE" )) - { - char path[ FTP_CWD_SIZE ]; - if( haveParameter() && makePath( path )) - { - bool open; - if( exists( path )) { - DEBUG_PRINTLN(F("APPEND FILE!!")); - open = openFile( path, ( CommandIs( "APPE" ) ? FTP_FILE_WRITE_APPEND : FTP_FILE_WRITE_CREATE )); - } else { - DEBUG_PRINTLN(F("CREATE FILE!!")); - open = openFile( path, FTP_FILE_WRITE_CREATE ); - } - - data.stop(); - data.flush(); - - DEBUG_PRINT(F("open/create ")); - DEBUG_PRINTLN(open); - if( ! open ){ - client.print( F("451 Can't open/create ") ); client.println( parameter ); - }else if( ! dataConnect()) // && !data.available()) - file.close(); - else - { - DEBUG_PRINT( F(" Receiving ") ); DEBUG_PRINTLN( parameter ); - - millisBeginTrans = millis(); - bytesTransfered = 0; - transferStage = FTP_Store; - - if (FtpServer::_transferCallback) { - -// FtpServer::_transferCallback(FTP_UPLOAD_START, parameter, bytesTransfered); - FtpServer::_transferCallback(FTP_UPLOAD_START, path, bytesTransfered); - } - - } - } - } - // - // MKD - Make Directory - // - else if( CommandIs( "MKD" )) - { - char path[ FTP_CWD_SIZE ]; - if( haveParameter() && makePath( path )) - { - if( exists( path )) { - client.print( F("521 \"") ); client.print( parameter ); client.println( F("\" directory already exists") ); - } else - { - DEBUG_PRINT( F(" Creating directory ")); DEBUG_PRINTLN( parameter ); - -#if STORAGE_TYPE != STORAGE_SPIFFS - if( makeDir( path )) { - client.print( F("257 \"") ); client.print( parameter ); client.print( F("\"") ); client.println( F(" created") ); + // + // USER - User Identity + // + if(CommandIs("USER")) { + if(!strcmp(parameter, user)) { + client.println(F("331 Ok. Password required")); + strcpy(cwdName, "/"); + cmdStage = FTP_Pass; } else { -#endif - client.print( F("550 Can't create \"") ); client.print( parameter ); client.println( F("\"") ); + client.println(F("530 ")); + cmdStage = FTP_Stop; + } + } + // + // PASS - Password + // + else if(CommandIs("PASS")) { + if(cmdStage != FTP_Pass) { + client.println(F("503 ")); + cmdStage = FTP_Stop; + } + if(!strcmp(parameter, pass)) { + DEBUG_PRINTLN(F(" Authentication Ok. Waiting for commands.")); + + client.println(F("230 Ok")); + cmdStage = FTP_Cmd; + } else { + client.println(F("530 ")); + cmdStage = FTP_Stop; + } + } + // + // FEAT - New Features + // + else if(CommandIs("FEAT")) { + client.println(F("211-Extensions suported:")); + client.println(F(" MLST type*;modify*;size*;")); + client.println(F(" MLSD")); + client.println(F(" MDTM")); + client.println(F(" MFMT")); + client.println(F(" SIZE")); + client.println(F(" SITE FREE")); + client.println(F("211 End.")); + } + // + // AUTH - Not implemented + // + else if(CommandIs("AUTH")) + client.println(F("502 ")); + // + // Unrecognized commands at stage of authentication + // + else if(cmdStage < FTP_Cmd) { + client.println(F("530 ")); + cmdStage = FTP_Stop; + } + + /////////////////////////////////////// + // // + // ACCESS CONTROL COMMANDS // + // // + /////////////////////////////////////// + + // + // PWD - Print Directory + // + else if(CommandIs("PWD") || (CommandIs("CWD") && ParameterIs("."))) { + client.print(F("257 \"")); + client.print(cwdName); + client.print(F("\"")); + client.println(F(" is your current directory")); + // + // CDUP - Change to Parent Directory + // + } else if(CommandIs("CDUP") || (CommandIs("CWD") && ParameterIs(".."))) { + bool ok = false; + + if(strlen(cwdName) > 1) // do nothing if cwdName is root + { + // if cwdName ends with '/', remove it (must not append) + if(cwdName[strlen(cwdName) - 1] == '/') { + cwdName[strlen(cwdName) - 1] = 0; + } + // search last '/' + char* pSep = strrchr(cwdName, '/'); + ok = pSep > cwdName; + // if found, ends the string on its position + if(ok) { + *pSep = 0; + ok = exists(cwdName); + } + } + // if an error appends, move to root + if(!ok) { + strcpy(cwdName, "/"); + } + client.print(F("250 Ok. Current directory is ")); + client.println(cwdName); + } + // + // CWD - Change Working Directory + // + else if(CommandIs("CWD")) { + char path[FTP_CWD_SIZE]; + if(haveParameter() && makeExistsPath(path)) { + strcpy(cwdName, path); + client.print(F("250 Directory changed to ")); + client.print(cwdName); + client.println(); + } + } + // + // QUIT + // + else if(CommandIs("QUIT")) { + client.println(F("221 Goodbye")); + disconnectClient(); + cmdStage = FTP_Stop; + } + + /////////////////////////////////////// + // // + // TRANSFER PARAMETER COMMANDS // + // // + /////////////////////////////////////// + + // + // MODE - Transfer Mode + // + else if(CommandIs("MODE")) { + if(ParameterIs("S")) { + client.println(F("200 S Ok")); + } else { + client.println(F("504 Only S(tream) is suported")); + } + } + // + // PASV - Passive Connection management + // + else if(CommandIs("PASV")) { + data.stop(); + dataServer.begin(); + if((((uint32_t)NET_CLASS.localIP()) & ((uint32_t)NET_CLASS.subnetMask())) == + (((uint32_t)client.remoteIP()) & ((uint32_t)NET_CLASS.subnetMask()))) { + dataIp = NET_CLASS.localIP(); + } else { + dataIp = localIp; + } + dataPort = pasvPort; + DEBUG_PRINTLN(F(" Connection management set to passive")); + DEBUG_PRINT(F(" Listening at ")); + DEBUG_PRINT(int(dataIp[0])); + DEBUG_PRINT(F(".")); + DEBUG_PRINT(int(dataIp[1])); + DEBUG_PRINT(F(".")); + DEBUG_PRINT(int(dataIp[2])); + DEBUG_PRINT(F(".")); + DEBUG_PRINT(int(dataIp[3])); + DEBUG_PRINT(F(":")); + DEBUG_PRINTLN(dataPort); + + client.print(F("227 Entering Passive Mode")); + client.print(F(" (")); + client.print(int(dataIp[0])); + client.print(F(",")); + client.print(int(dataIp[1])); + client.print(F(",")); + client.print(int(dataIp[2])); + client.print(F(",")); + client.print(int(dataIp[3])); + client.print(F(",")); + client.print((dataPort >> 8)); + client.print(F(",")); + client.print((dataPort & 255)); + client.println(F(")")); + dataConn = FTP_Pasive; + } + // + // PORT - Data Port + // + else if(CommandIs("PORT")) { + data.stop(); + // get IP of data client + dataIp[0] = atoi(parameter); + char* p = strchr(parameter, ','); + for(uint8_t i = 1; i < 4; i++) { + dataIp[i] = atoi(++p); + p = strchr(p, ','); + } + // get port of data client + dataPort = 256 * atoi(++p); + p = strchr(p, ','); + dataPort += atoi(++p); + if(p == NULL) { + client.println(F("501 Can't interpret parameters")); + } else { + DEBUG_PRINT(F(" Data IP set to ")); + DEBUG_PRINT(int(dataIp[0])); + DEBUG_PRINT(F(".")); + DEBUG_PRINT(int(dataIp[1])); + DEBUG_PRINT(F(".")); + DEBUG_PRINT(int(dataIp[2])); + DEBUG_PRINT(F(".")); + DEBUG_PRINTLN(int(dataIp[3])); + DEBUG_PRINT(F(" Data port set to ")); + DEBUG_PRINTLN(dataPort); + + client.println(F("200 PORT command successful")); + dataConn = FTP_Active; + } + } + // + // STRU - File Structure + // + else if(CommandIs("STRU")) { + if(ParameterIs("F")) { + client.println(F("200 F Ok")); + // else if( ParameterIs( "R" )) + // client.println(F("200 B Ok") ); + } else { + client.println(F("504 Only F(ile) is suported")); + } + } + // + // TYPE - Data Type + // + else if(CommandIs("TYPE")) { + if(ParameterIs("A")) { + client.println(F("200 TYPE is now ASCII")); + } else if(ParameterIs("I")) { + client.println(F("200 TYPE is now 8-bit binary")); + } else { + client.println(F("504 Unknow TYPE")); + } + } + + /////////////////////////////////////// + // // + // FTP SERVICE COMMANDS // + // // + /////////////////////////////////////// + + // + // ABOR - Abort + // + else if(CommandIs("ABOR")) { + abortTransfer(); + client.println(F("226 Data connection closed")); + } + // + // DELE - Delete a File + // + else if(CommandIs("DELE")) { + char path[FTP_CWD_SIZE]; + if(haveParameter() && makeExistsPath(path)) { + if(remove(path)) { + if(FtpServer::_callback) { + FtpServer::_callback(FTP_FREE_SPACE_CHANGE, free(), capacity()); + } + + client.print(F("250 Deleted ")); + client.println(parameter); + } else { + client.print(F("450 Can't delete ")); + client.println(parameter); + } + } + } + // + // LIST - List + // NLST - Name List + // MLSD - Listing for Machine Processing (see RFC 3659) + // + else if(CommandIs("LIST") || CommandIs("NLST") || CommandIs("MLSD")) { + DEBUG_PRINT("List of file!!"); + + if(dataConnect()) { + if(openDir(&dir)) { + DEBUG_PRINT("Dir opened!!"); + + nbMatch = 0; + if(CommandIs("LIST")) + transferStage = FTP_List; + else if(CommandIs("NLST")) + transferStage = FTP_Nlst; + else + transferStage = FTP_Mlsd; + } else { + DEBUG_PRINT("List Data stop!!"); + data.stop(); + } + } + } + // + // MLST - Listing for Machine Processing (see RFC 3659) + // + else if(CommandIs("MLST")) { + char path[FTP_CWD_SIZE]; + uint16_t dat, tim; + char dtStr[15]; + bool isdir; + if(haveParameter() && makeExistsPath(path)) { + if(!getFileModTime(path, &dat, &tim)) { + client.print(F("550 Unable to retrieve time for ")); + client.println(parameter); + } else { + isdir = isDir(path); + client.println(F("250-Begin")); + client.print(F(" Type=")); + client.print((isdir ? F("dir") : F("file"))); + client.print(F(";Modify=")); + client.print(makeDateTimeStr(dtStr, dat, tim)); + if(!isdir) { + if(openFile(path, FTP_FILE_READ)) { + client.print(F(";Size=")); + client.print(long(fileSize(file))); + file.close(); + } + } + client.print(F("; ")); + client.println(path); + client.println(F("250 End.")); + } + } + } + // + // NOOP + // + else if(CommandIs("NOOP")) { + client.println(F("200 Zzz...")); + } + // + // RETR - Retrieve + // + else if(CommandIs("RETR")) { + char path[FTP_CWD_SIZE]; + if(haveParameter() && makeExistsPath(path)) { + if(!openFile(path, FTP_FILE_READ)) { + client.print(F("450 Can't open ")); + client.print(parameter); + } else if(dataConnect(false)) { + DEBUG_PRINT(F(" Sending ")); + DEBUG_PRINT(parameter); + DEBUG_PRINT(F(" size ")); + DEBUG_PRINTLN(long(fileSize(file))); + + if(FtpServer::_transferCallback) { + FtpServer::_transferCallback(FTP_DOWNLOAD_START, path, long(fileSize(file))); + } + + client.print(F("150-Connected to port ")); + client.println(dataPort); + client.print(F("150 ")); + client.print(long(fileSize(file))); + client.println(F(" bytes to download")); + millisBeginTrans = millis(); + bytesTransfered = 0; + transferStage = FTP_Retrieve; + } + } + } + // + // STOR - Store + // APPE - Append + // + else if(CommandIs("STOR") || CommandIs("APPE")) { + char path[FTP_CWD_SIZE]; + if(haveParameter() && makePath(path)) { + bool open; + if(exists(path)) { + DEBUG_PRINTLN(F("APPEND FILE!!")); + open = openFile(path, (CommandIs("APPE") ? FTP_FILE_WRITE_APPEND : FTP_FILE_WRITE_CREATE)); + } else { + DEBUG_PRINTLN(F("CREATE FILE!!")); + open = openFile(path, FTP_FILE_WRITE_CREATE); + } + + data.stop(); + data.flush(); + + DEBUG_PRINT(F("open/create ")); + DEBUG_PRINTLN(open); + if(!open) { + client.print(F("451 Can't open/create ")); + client.println(parameter); + } else if(!dataConnect()) // && !data.available()) + file.close(); + else { + DEBUG_PRINT(F(" Receiving ")); + DEBUG_PRINTLN(parameter); + + millisBeginTrans = millis(); + bytesTransfered = 0; + transferStage = FTP_Store; + + if(FtpServer::_transferCallback) { + + // FtpServer::_transferCallback(FTP_UPLOAD_START, parameter, bytesTransfered); + FtpServer::_transferCallback(FTP_UPLOAD_START, path, bytesTransfered); + } + } + } + } + // + // MKD - Make Directory + // + else if(CommandIs("MKD")) { + char path[FTP_CWD_SIZE]; + if(haveParameter() && makePath(path)) { + if(exists(path)) { + client.print(F("521 \"")); + client.print(parameter); + client.println(F("\" directory already exists")); + } else { + DEBUG_PRINT(F(" Creating directory ")); + DEBUG_PRINTLN(parameter); + #if STORAGE_TYPE != STORAGE_SPIFFS - } + if(makeDir(path)) { + client.print(F("257 \"")); + client.print(parameter); + client.print(F("\"")); + client.println(F(" created")); + } else { #endif - } - } - } - // - // RMD - Remove a Directory - // - else if( CommandIs( "RMD" )) - { - char path[ FTP_CWD_SIZE ]; - if( haveParameter() && makeExistsPath( path )) { - if( removeDir( path )) - { - DEBUG_PRINT( F(" Deleting ") ); DEBUG_PRINTLN( path ); - - client.print( F("250 \"") ); client.print( parameter ); client.println( F("\" deleted") ); - } - else { - client.print( F("550 Can't remove \"") ); client.print( parameter ); client.println( F("\". Directory not empty?") ); - } - } - } - // - // RNFR - Rename From - // - else if( CommandIs( "RNFR" )) - { - rnfrName[ 0 ] = 0; - if( haveParameter() && makeExistsPath( rnfrName )) - { - DEBUG_PRINT( F(" Ready for renaming ") ); DEBUG_PRINTLN( rnfrName ); - - client.println(F("350 RNFR accepted - file exists, ready for destination") ); - rnfrCmd = true; - } - } - // - // RNTO - Rename To - // - else if( CommandIs( "RNTO" )) - { - char path[ FTP_CWD_SIZE ]; - char dirp[ FTP_FIL_SIZE ]; - if( strlen( rnfrName ) == 0 || ! rnfrCmd ) { - client.println(F("503 Need RNFR before RNTO") ); - } else if( haveParameter() && makePath( path )) - { - if( exists( path )) { - client.print( F("553 ") ); client.print( parameter ); client.println( F(" already exists") ); - } else - { - strcpy( dirp, path ); - char * psep = strrchr( dirp, '/' ); - bool fail = psep == NULL; - if( ! fail ) - { - if( psep == dirp ) - psep ++; - * psep = 0; -// fail = ! isDir( dirp ); -// if( fail ) { -// client.print( F("550 \"") ); client.print( dirp ); client.println( F("\" is not directory") ); -// } else -// { - DEBUG_PRINT( F(" Renaming ") ); DEBUG_PRINT( rnfrName ); DEBUG_PRINT( F(" to ") ); DEBUG_PRINTLN( path ); - - if( rename( rnfrName, path )) - client.println(F("250 File successfully renamed or moved") ); - else - fail = true; -// } + client.print(F("550 Can't create \"")); + client.print(parameter); + client.println(F("\"")); +#if STORAGE_TYPE != STORAGE_SPIFFS + } +#endif + } } - if( fail ) - client.println(F("451 Rename/move failure") ); - } } - rnfrCmd = false; - } - /* - // - // SYST - System - // - else if( CommandIs( "SYST" )) - FtpOutCli << F("215 MSDOS") << endl; - */ - - /////////////////////////////////////// - // // - // EXTENSIONS COMMANDS (RFC 3659) // - // // - /////////////////////////////////////// + // + // RMD - Remove a Directory + // + else if(CommandIs("RMD")) { + char path[FTP_CWD_SIZE]; + if(haveParameter() && makeExistsPath(path)) { + if(removeDir(path)) { + DEBUG_PRINT(F(" Deleting ")); + DEBUG_PRINTLN(path); - // - // MDTM && MFMT - File Modification Time (see RFC 3659) - // - else if( CommandIs( "MDTM" ) || CommandIs( "MFMT" )) - { - if( haveParameter()) - { - char path[ FTP_CWD_SIZE ]; - char * fname = parameter; - uint16_t year; - uint8_t month, day, hour, minute, second, setTime; - char dt[ 15 ]; - bool mdtm = CommandIs( "MDTM" ); + client.print(F("250 \"")); + client.print(parameter); + client.println(F("\" deleted")); + } else { + client.print(F("550 Can't remove \"")); + client.print(parameter); + client.println(F("\". Directory not empty?")); + } + } + } + // + // RNFR - Rename From + // + else if(CommandIs("RNFR")) { + rnfrName[0] = 0; + if(haveParameter() && makeExistsPath(rnfrName)) { + DEBUG_PRINT(F(" Ready for renaming ")); + DEBUG_PRINTLN(rnfrName); - setTime = getDateTime( dt, & year, & month, & day, & hour, & minute, & second ); - // fname point to file name - fname += setTime; - if( strlen( fname ) <= 0 ) { - client.println(F("501 No file name") ); - } else if( makeExistsPath( path, fname )) { - if( setTime ) // set file modification time - { - if( timeStamp( path, year, month, day, hour, minute, second )) { - client.print( F("213 ") ); client.println( dt ); - } else { - client.println(F("550 Unable to modify time" )); - } + client.println(F("350 RNFR accepted - file exists, ready for destination")); + rnfrCmd = true; } - else if( mdtm ) // get file modification time - { - uint16_t dat, tim; - char dtStr[ 15 ]; - if( getFileModTime( path, & dat, & tim )) { - client.print( F("213 ") ); client.println( makeDateTimeStr( dtStr, dat, tim ) ); - } else { - client.println("550 Unable to retrieve time" ); - } + } + // + // RNTO - Rename To + // + else if(CommandIs("RNTO")) { + char path[FTP_CWD_SIZE]; + char dirp[FTP_FIL_SIZE]; + if(strlen(rnfrName) == 0 || !rnfrCmd) { + client.println(F("503 Need RNFR before RNTO")); + } else if(haveParameter() && makePath(path)) { + if(exists(path)) { + client.print(F("553 ")); + client.print(parameter); + client.println(F(" already exists")); + } else { + strcpy(dirp, path); + char* psep = strrchr(dirp, '/'); + bool fail = psep == NULL; + if(!fail) { + if(psep == dirp) psep++; + *psep = 0; + // fail = ! isDir( dirp ); + // if( fail ) { + // client.print( F("550 \"") ); client.print( dirp ); client.println( F("\" is not + // directory") ); + // } else + // { + DEBUG_PRINT(F(" Renaming ")); + DEBUG_PRINT(rnfrName); + DEBUG_PRINT(F(" to ")); + DEBUG_PRINTLN(path); + + if(rename(rnfrName, path)) + client.println(F("250 File successfully renamed or moved")); + else + fail = true; + // } + } + if(fail) client.println(F("451 Rename/move failure")); + } } - } + rnfrCmd = false; } - } - // - // SIZE - Size of the file - // - else if( CommandIs( "SIZE" )) - { - char path[ FTP_CWD_SIZE ]; - if( haveParameter() && makeExistsPath( path )) { - if( ! openFile( path, FTP_FILE_READ )) { - client.print( F("450 Can't open ") ); client.println( parameter ); - } else - { - client.print( F("213 ") ); client.println( long( fileSize( file )) ); - file.close(); - } + /* + // + // SYST - System + // + else if( CommandIs( "SYST" )) + FtpOutCli << F("215 MSDOS") << endl; + */ + + /////////////////////////////////////// + // // + // EXTENSIONS COMMANDS (RFC 3659) // + // // + /////////////////////////////////////// + + // + // MDTM && MFMT - File Modification Time (see RFC 3659) + // + else if(CommandIs("MDTM") || CommandIs("MFMT")) { + if(haveParameter()) { + char path[FTP_CWD_SIZE]; + char* fname = parameter; + uint16_t year; + uint8_t month, day, hour, minute, second, setTime; + char dt[15]; + bool mdtm = CommandIs("MDTM"); + + setTime = getDateTime(dt, &year, &month, &day, &hour, &minute, &second); + // fname point to file name + fname += setTime; + if(strlen(fname) <= 0) { + client.println(F("501 No file name")); + } else if(makeExistsPath(path, fname)) { + if(setTime) // set file modification time + { + if(timeStamp(path, year, month, day, hour, minute, second)) { + client.print(F("213 ")); + client.println(dt); + } else { + client.println(F("550 Unable to modify time")); + } + } else if(mdtm) // get file modification time + { + uint16_t dat, tim; + char dtStr[15]; + if(getFileModTime(path, &dat, &tim)) { + client.print(F("213 ")); + client.println(makeDateTimeStr(dtStr, dat, tim)); + } else { + client.println("550 Unable to retrieve time"); + } + } + } + } } - } - // - // SITE - System command - // - else if( CommandIs( "SITE" )) - { - if( ParameterIs( "FREE" )) - { - uint32_t capa = capacity(); - if(( capa >> 10 ) < 1000 ) { // less than 1 Giga - client.print( F("200 ") ); client.print( free() ); client.print( F(" kB free of ") ); - client.print( capa ); client.println( F(" kB capacity") ); - }else { - client.print( F("200 ") ); client.print( ( free() >> 10 ) ); client.print( F(" MB free of ") ); - client.print( ( capa >> 10 ) ); client.println( F(" MB capacity") ); - } + // + // SIZE - Size of the file + // + else if(CommandIs("SIZE")) { + char path[FTP_CWD_SIZE]; + if(haveParameter() && makeExistsPath(path)) { + if(!openFile(path, FTP_FILE_READ)) { + client.print(F("450 Can't open ")); + client.println(parameter); + } else { + client.print(F("213 ")); + client.println(long(fileSize(file))); + file.close(); + } + } } - else { - client.print( F("500 Unknow SITE command ") ); client.println( parameter ); + // + // SITE - System command + // + else if(CommandIs("SITE")) { + if(ParameterIs("FREE")) { + uint32_t capa = capacity(); + if((capa >> 10) < 1000) { // less than 1 Giga + client.print(F("200 ")); + client.print(free()); + client.print(F(" kB free of ")); + client.print(capa); + client.println(F(" kB capacity")); + } else { + client.print(F("200 ")); + client.print((free() >> 10)); + client.print(F(" MB free of ")); + client.print((capa >> 10)); + client.println(F(" MB capacity")); + } + } else { + client.print(F("500 Unknow SITE command ")); + client.println(parameter); + } } - } - // - // Unrecognized commands ... - // - else - client.println(F("500 Unknow command") ); - return true; + // + // Unrecognized commands ... + // + else + client.println(F("500 Unknow command")); + return true; } -int FtpServer::dataConnect( bool out150 ) +int FtpServer::dataConnect(bool out150) { - if( ! data.connected()) { - if( dataConn == FTP_Pasive ) - { - uint16_t count = 1000; // wait up to a second - while( ! data.connected() && count -- > 0 ) - { - #ifdef ESP8266 - if( dataServer.hasClient()) - { - data.stop(); - data = dataServer.available(); - } - #else - data = dataServer.accept(); - #endif - delay( 1 ); - } + if(!data.connected()) { + if(dataConn == FTP_Pasive) { + uint16_t count = 1000; // wait up to a second + while(!data.connected() && count-- > 0) { +#ifdef ESP8266 + if(dataServer.hasClient()) { + data.stop(); + data = dataServer.available(); + } +#else + data = dataServer.accept(); +#endif + delay(1); + } + } else if(dataConn == FTP_Active) + data.connect(dataIp, dataPort); } - else if( dataConn == FTP_Active ) - data.connect( dataIp, dataPort ); - } - -//#ifdef ESP8266 - if( ! ( data.connected() || data.available())) { -//#else -// if( ! ( data.connected() )) { -//#endif - client.println(F("425 No data connection")); - } else if( out150 ) { - client.print( F("150 Accepted data connection to port ") ); client.println( dataPort ); - } -//#ifdef ESP8266 - return data.connected() || data.available(); -//#else -// return data.connected(); -//#endif + //#ifdef ESP8266 + if(!(data.connected() || data.available())) { + //#else + // if( ! ( data.connected() )) { + //#endif + client.println(F("425 No data connection")); + } else if(out150) { + client.print(F("150 Accepted data connection to port ")); + client.println(dataPort); + } + //#ifdef ESP8266 + return data.connected() || data.available(); + //#else + // return data.connected(); + //#endif } bool FtpServer::dataConnected() { - if( data.connected()) - return true; - data.stop(); - client.println(F("426 Data connection closed. Transfer aborted") ); - transferStage = FTP_Close; - return false; + if(data.connected()) return true; + data.stop(); + client.println(F("426 Data connection closed. Transfer aborted")); + transferStage = FTP_Close; + return false; } - -bool FtpServer::openDir( FTP_DIR * pdir ) + +bool FtpServer::openDir(FTP_DIR* pdir) { - bool openD; -#if (STORAGE_TYPE == STORAGE_LITTLEFS && defined(ESP8266)) - if( cwdName == 0 ) { - dir = STORAGE_MANAGER.openDir( "/" ); - } else { - dir = STORAGE_MANAGER.openDir( cwdName ); - } - openD = dir.rewind(); + bool openD; +#if(STORAGE_TYPE == STORAGE_LITTLEFS && defined(ESP8266)) + if(cwdName == 0) { + dir = STORAGE_MANAGER.openDir("/"); + } else { + dir = STORAGE_MANAGER.openDir(cwdName); + } + openD = dir.rewind(); - if( ! openD ) { - client.print( F("550 Can't open directory ") ); client.println( cwdName ); - } + if(!openD) { + client.print(F("550 Can't open directory ")); + client.println(cwdName); + } #elif STORAGE_TYPE == STORAGE_SD - if( cwdName == 0 ) { - dir = STORAGE_MANAGER.open( "/" ); - } else { - dir = STORAGE_MANAGER.open( cwdName ); - } - openD = true; - if( ! openD ) { - client.print( F("550 Can't open directory ") ); client.println( cwdName ); - } + if(cwdName == 0) { + dir = STORAGE_MANAGER.open("/"); + } else { + dir = STORAGE_MANAGER.open(cwdName); + } + openD = true; + if(!openD) { + client.print(F("550 Can't open directory ")); + client.println(cwdName); + } #elif STORAGE_TYPE == STORAGE_FFAT || (STORAGE_TYPE == STORAGE_LITTLEFS && defined(ESP32)) - if( cwdName == 0 ) { - dir = STORAGE_MANAGER.open( "/" ); - } else { - dir = STORAGE_MANAGER.open( cwdName ); - } - openD = true; - if( ! openD ) { - client.print( F("550 Can't open directory ") ); client.println( cwdName ); - } + if(cwdName == 0) { + dir = STORAGE_MANAGER.open("/"); + } else { + dir = STORAGE_MANAGER.open(cwdName); + } + openD = true; + if(!openD) { + client.print(F("550 Can't open directory ")); + client.println(cwdName); + } #elif STORAGE_TYPE == STORAGE_SEEED_SD - if( cwdName == 0 ) { - DEBUG_PRINT("cwdName forced -> "); - DEBUG_PRINTLN(cwdName ); + if(cwdName == 0) { + DEBUG_PRINT("cwdName forced -> "); + DEBUG_PRINTLN(cwdName); - FTP_DIR d = STORAGE_MANAGER.open( "/" ); - dir=d; - } else { - DEBUG_PRINT("cwdName -> "); - DEBUG_PRINTLN(cwdName ); + FTP_DIR d = STORAGE_MANAGER.open("/"); + dir = d; + } else { + DEBUG_PRINT("cwdName -> "); + DEBUG_PRINTLN(cwdName); - FTP_DIR d = STORAGE_MANAGER.open( cwdName ); - dir=d; - } + FTP_DIR d = STORAGE_MANAGER.open(cwdName); + dir = d; + } - openD = dir.isDirectory(); + openD = dir.isDirectory(); -//#ifdef FTP_ADDITIONAL_DEBUG -// DEBUG_PRINT("Listing directory: "); -// DEBUG_PRINTLN(cwdName); -// -// if (!dir) { -// DEBUG_PRINTLN("Failed to open directory"); -// } -// if (!dir.isDirectory()) { -// DEBUG_PRINTLN("Not a directory"); -// } -// -// File file = dir.openNextFile(); -// while (file) { -// if (file.isDirectory()) { -// DEBUG_PRINT(" DIR : "); -// DEBUG_PRINTLN(file.name()); -// } else { -// DEBUG_PRINT(" FILE: "); -// DEBUG_PRINT(file.name()); -// DEBUG_PRINT(" SIZE: "); -// DEBUG_PRINTLN(file.size()); -// } -// file = dir.openNextFile(); -// } -// -// dir.rewindDirectory(); -// -//#endif + //#ifdef FTP_ADDITIONAL_DEBUG + // DEBUG_PRINT("Listing directory: "); + // DEBUG_PRINTLN(cwdName); + // + // if (!dir) { + // DEBUG_PRINTLN("Failed to open directory"); + // } + // if (!dir.isDirectory()) { + // DEBUG_PRINTLN("Not a directory"); + // } + // + // File file = dir.openNextFile(); + // while (file) { + // if (file.isDirectory()) { + // DEBUG_PRINT(" DIR : "); + // DEBUG_PRINTLN(file.name()); + // } else { + // DEBUG_PRINT(" FILE: "); + // DEBUG_PRINT(file.name()); + // DEBUG_PRINT(" SIZE: "); + // DEBUG_PRINTLN(file.size()); + // } + // file = dir.openNextFile(); + // } + // + // dir.rewindDirectory(); + // + //#endif - if( ! openD ) { - client.print( F("550 Can't open directory ") ); client.println( cwdName ); - } + if(!openD) { + client.print(F("550 Can't open directory ")); + client.println(cwdName); + } #elif STORAGE_TYPE == STORAGE_SPIFFS - if( cwdName == 0 || strcmp(cwdName, "/") == 0 ) { - DEBUG_PRINT("DIRECTORY / EXIST "); + if(cwdName == 0 || strcmp(cwdName, "/") == 0) { + DEBUG_PRINT("DIRECTORY / EXIST "); #if ESP8266 - dir = STORAGE_MANAGER.openDir( "/" ); + dir = STORAGE_MANAGER.openDir("/"); #else - dir = STORAGE_MANAGER.open( "/" ); + dir = STORAGE_MANAGER.open("/"); #endif - openD = true; + openD = true; } else { - openD = false; + openD = false; } - if( ! openD ) { - client.print( F("550 Can't open directory ") ); client.println( cwdName ); + if(!openD) { + client.print(F("550 Can't open directory ")); + client.println(cwdName); } #else - if( cwdName == 0 ) { - openD = pdir->open( "/" ); - } else { - openD = pdir->open( cwdName ); - } - if( ! openD ) { - client.print( F("550 Can't open directory ") ); client.println( cwdName ); - } + if(cwdName == 0) { + openD = pdir->open("/"); + } else { + openD = pdir->open(cwdName); + } + if(!openD) { + client.print(F("550 Can't open directory ")); + client.println(cwdName); + } #endif - return openD; + return openD; } bool FtpServer::doRetrieve() { - if( ! dataConnected()) - { - file.close(); - return false; - } - int16_t nb = file.read( buf, FTP_BUF_SIZE ); - if( nb > 0 ) - { - data.write( buf, nb ); - DEBUG_PRINT(F("NB --> ")); - DEBUG_PRINTLN(nb); - bytesTransfered += nb; + if(!dataConnected()) { + file.close(); + return false; + } + int16_t nb = file.read(buf, FTP_BUF_SIZE); + if(nb > 0) { + data.write(buf, nb); + DEBUG_PRINT(F("NB --> ")); + DEBUG_PRINTLN(nb); + bytesTransfered += nb; - if (FtpServer::_transferCallback) { - FtpServer::_transferCallback(FTP_DOWNLOAD, getFileName(&file), bytesTransfered); - } + if(FtpServer::_transferCallback) { + FtpServer::_transferCallback(FTP_DOWNLOAD, getFileName(&file), bytesTransfered); + } // RoSchmi #if STORAGE_TYPE != STORAGE_SEEED_SD - return true; + return true; #endif - } - closeTransfer(); - return false; + } + closeTransfer(); + return false; } bool FtpServer::doStore() { - int16_t na = data.available(); - if( na == 0 ) { - DEBUG_PRINTLN("NO DATA AVAILABLE!"); + int16_t na = data.available(); + if(na == 0) { + DEBUG_PRINTLN("NO DATA AVAILABLE!"); #if FTP_SERVER_NETWORK_TYPE_SELECTED == NETWORK_SEEED_RTL8720DN - data.stop(); + data.stop(); #endif - if( data.connected()) { - return true; - } else - { - closeTransfer(); - return false; + if(data.connected()) { + return true; + } else { + closeTransfer(); + return false; + } } - } - if( na > FTP_BUF_SIZE ) { - na = FTP_BUF_SIZE; - } - int16_t nb = data.read((uint8_t *) buf, na ); - int16_t rc = 0; - if( nb > 0 ) - { - DEBUG_PRINT("NB -> "); - DEBUG_PRINTLN(nb); + if(na > FTP_BUF_SIZE) { + na = FTP_BUF_SIZE; + } + int16_t nb = data.read((uint8_t*)buf, na); + int16_t rc = 0; + if(nb > 0) { + DEBUG_PRINT("NB -> "); + DEBUG_PRINTLN(nb); - rc = file.write( buf, nb ); - DEBUG_PRINT("RC -> "); - DEBUG_PRINTLN(rc); - bytesTransfered += nb; + rc = file.write(buf, nb); + DEBUG_PRINT("RC -> "); + DEBUG_PRINTLN(rc); + bytesTransfered += nb; - if (FtpServer::_transferCallback) { + if(FtpServer::_transferCallback) { - FtpServer::_transferCallback(FTP_UPLOAD, getFileName(&file), bytesTransfered); - } - } - if( nb < 0 || rc == nb ) { - return true; - } - client.println(F("552 Probably insufficient storage space") ); - file.close(); - data.stop(); - return false; + FtpServer::_transferCallback(FTP_UPLOAD, getFileName(&file), bytesTransfered); + } + } + if(nb < 0 || rc == nb) { + return true; + } + client.println(F("552 Probably insufficient storage space")); + file.close(); + data.stop(); + return false; } bool FtpServer::doList() { - if( ! dataConnected()) - { + if(!dataConnected()) { +#if STORAGE_TYPE != STORAGE_SPIFFS && STORAGE_TYPE != STORAGE_LITTLEFS && STORAGE_TYPE != STORAGE_SEEED_SD + dir.close(); +#endif + return false; + } +#if STORAGE_TYPE == STORAGE_SPIFFS +#if ESP8266 + if(dir.next()) +#else + FTP_FILE fileDir = dir.openNextFile(); + if(fileDir) +#endif + { + + data.print(F("+r,s")); +#if ESP8266 + data.print(long(dir.fileSize())); + data.print(F(",\t")); + data.println(dir.fileName()); +#else + data.print(long(fileDir.size())); + data.print(F(",\t")); + data.println(fileDir.name()); +#endif + nbMatch++; + return true; + } +#elif STORAGE_TYPE == STORAGE_LITTLEFS || STORAGE_TYPE == STORAGE_SEEED_SD || STORAGE_TYPE == STORAGE_FFAT +#if ESP8266 + if(dir.next()) +#else +#if STORAGE_TYPE == STORAGE_SEEED_SD + FTP_FILE fileDir = STORAGE_MANAGER.open(dir.name()); + fileDir = dir.openNextFile(); +#else + FTP_FILE fileDir = dir.openNextFile(); +#endif + if(fileDir) +#endif + { + + if(dir.isDirectory()) { + data.print(F("+/,\t")); + DEBUG_PRINT(F("+/,\t")); + } else { + data.print(F("+r,s")); + DEBUG_PRINT(F("+r,s")); + } +#if ESP8266 + data.print(long(dir.fileSize())); + data.print(F(",\t")); + data.println(dir.fileName()); +#elif STORAGE_TYPE == STORAGE_SEEED_SD + String fn = fileDir.name(); + fn.remove(0, strlen(dir.name())); + if(fn[0] == '/') { + fn.remove(0, fn.lastIndexOf("/") + 1); + } + long fz = fileDir.size(); +#else + data.print(long(fileDir.size())); + data.print(F(",\t")); + data.println(fileDir.name()); + + DEBUG_PRINT(long(fileDir.size())); + DEBUG_PRINT(F(",\t")); + DEBUG_PRINTLN(fileDir.name()); + +#endif + + nbMatch++; + return true; + } +#elif STORAGE_TYPE == STORAGE_SD + FTP_FILE fileDir = dir.openNextFile(); + if(fileDir) { + + data.print(F("+r,s")); + data.print(long(fileDir.size())); + data.print(F(",\t")); + data.println(fileDir.name()); + + nbMatch++; + return true; + } + // + //#elif STORAGE_TYPE == STORAGE_SPIFFS || STORAGE_TYPE == STORAGE_LITTLEFS || STORAGE_TYPE == STORAGE_SD + // #if ESP8266 && STORAGE_TYPE != STORAGE_SD + // if( dir.next()) + // #else + // File fileDir = dir.openNextFile(); + // if( fileDir ) + // #endif + // { + // + // #if (STORAGE_TYPE == STORAGE_LITTLEFS) + // if( dir.isDirectory()) { + // data.print( F("+/,\t") ); + // } else { + // #endif + // data.print( F("+r,s") ); + // #if ESP8266 && STORAGE_TYPE != STORAGE_SD + // data.print( long( dir.fileSize()) ); + // data.print( F(",\t") ); + // data.println( dir.fileName() ); + // #else + // data.print( long( fileDir.size()) ); + // data.print( F(",\t") ); + // data.println( fileDir.name() ); + // #endif + // #if (STORAGE_TYPE == STORAGE_LITTLEFS) + // } + // #endif + // + // nbMatch ++; + // return true; + // } + // + +#elif STORAGE_TYPE == STORAGE_FATFS + if(dir.nextFile()) { + if(dir.isDir()) { + data.print(F("+/,\t")); + } else { + data.print(F("+r,s")); + data.print(long(dir.fileSize())); + data.print(F(",\t")); + } + data.println(dir.fileName()); + nbMatch++; + return true; + } +#else + if(file.openNext(&dir, FTP_FILE_READ_ONLY)) { + if(file.isDir()) { + data.print(F("+/,\t")); + } else { + data.print(F("+r,s")); + data.print(long(fileSize(file))); + data.print(F(",\t")); + } + file.printName(&data); + data.println(); + file.close(); + nbMatch++; + return true; + } +#endif + client.print(F("226 ")); + client.print(nbMatch); + client.println(F(" matches total")); #if STORAGE_TYPE != STORAGE_SPIFFS && STORAGE_TYPE != STORAGE_LITTLEFS && STORAGE_TYPE != STORAGE_SEEED_SD dir.close(); #endif + data.stop(); return false; - } -#if STORAGE_TYPE == STORAGE_SPIFFS - #if ESP8266 - if( dir.next()) - #else - FTP_FILE fileDir = dir.openNextFile(); - if( fileDir ) - #endif - { - - data.print( F("+r,s") ); - #if ESP8266 - data.print( long( dir.fileSize()) ); - data.print( F(",\t") ); - data.println( dir.fileName() ); - #else - data.print( long( fileDir.size()) ); - data.print( F(",\t") ); - data.println( fileDir.name() ); - #endif - nbMatch ++; - return true; - } -#elif STORAGE_TYPE == STORAGE_LITTLEFS || STORAGE_TYPE == STORAGE_SEEED_SD || STORAGE_TYPE == STORAGE_FFAT - #if ESP8266 - if( dir.next()) - #else -#if STORAGE_TYPE == STORAGE_SEEED_SD - FTP_FILE fileDir = STORAGE_MANAGER.open(dir.name()); - fileDir = dir.openNextFile(); -#else - FTP_FILE fileDir = dir.openNextFile(); -#endif - if( fileDir ) - #endif - { - - if( dir.isDirectory()) { - data.print( F("+/,\t") ); - DEBUG_PRINT(F("+/,\t")); - } else { - data.print( F("+r,s") ); - DEBUG_PRINT(F("+r,s")); - } - #if ESP8266 - data.print( long( dir.fileSize()) ); - data.print( F(",\t") ); - data.println( dir.fileName() ); - #elif STORAGE_TYPE == STORAGE_SEEED_SD - String fn = fileDir.name(); - fn.remove(0, strlen(dir.name())); - if (fn[0]=='/') { fn.remove(0, fn.lastIndexOf("/")+1); } - long fz = fileDir.size(); - #else - data.print( long( fileDir.size()) ); - data.print( F(",\t") ); - data.println( fileDir.name() ); - - DEBUG_PRINT( long( fileDir.size())); - DEBUG_PRINT( F(",\t") ); - DEBUG_PRINTLN( fileDir.name() ); - - #endif - - - nbMatch ++; - return true; - } -#elif STORAGE_TYPE == STORAGE_SD - FTP_FILE fileDir = dir.openNextFile(); - if( fileDir ) - { - - data.print( F("+r,s") ); - data.print( long( fileDir.size()) ); - data.print( F(",\t") ); - data.println( fileDir.name() ); - - nbMatch ++; - return true; - } -// -//#elif STORAGE_TYPE == STORAGE_SPIFFS || STORAGE_TYPE == STORAGE_LITTLEFS || STORAGE_TYPE == STORAGE_SD -// #if ESP8266 && STORAGE_TYPE != STORAGE_SD -// if( dir.next()) -// #else -// File fileDir = dir.openNextFile(); -// if( fileDir ) -// #endif -// { -// -// #if (STORAGE_TYPE == STORAGE_LITTLEFS) -// if( dir.isDirectory()) { -// data.print( F("+/,\t") ); -// } else { -// #endif -// data.print( F("+r,s") ); -// #if ESP8266 && STORAGE_TYPE != STORAGE_SD -// data.print( long( dir.fileSize()) ); -// data.print( F(",\t") ); -// data.println( dir.fileName() ); -// #else -// data.print( long( fileDir.size()) ); -// data.print( F(",\t") ); -// data.println( fileDir.name() ); -// #endif -// #if (STORAGE_TYPE == STORAGE_LITTLEFS) -// } -// #endif -// -// nbMatch ++; -// return true; -// } -// - -#elif STORAGE_TYPE == STORAGE_FATFS - if( dir.nextFile()) - { - if( dir.isDir()) { - data.print( F("+/,\t") ); - } else { - data.print( F("+r,s") ); data.print( long( dir.fileSize()) ); data.print( F(",\t") ); - } - data.println( dir.fileName() ); - nbMatch ++; - return true; - } -#else - if( file.openNext( &dir, FTP_FILE_READ_ONLY )) - { - if( file.isDir()) { - data.print( F("+/,\t") ); - } else { - data.print( F("+r,s") ); data.print( long( fileSize( file )) ); data.print( F(",\t") ); - } - file.printName( & data ); - data.println(); - file.close(); - nbMatch ++; - return true; - } -#endif - client.print( F("226 ") ); client.print( nbMatch ); client.println( F(" matches total") ); -#if STORAGE_TYPE != STORAGE_SPIFFS && STORAGE_TYPE != STORAGE_LITTLEFS && STORAGE_TYPE != STORAGE_SEEED_SD - dir.close(); -#endif - data.stop(); - return false; } bool FtpServer::doMlsd() { - if( ! dataConnected()) - { + if(!dataConnected()) { #if STORAGE_TYPE != STORAGE_SPIFFS && STORAGE_TYPE != STORAGE_LITTLEFS && STORAGE_TYPE != STORAGE_SEEED_SD - dir.close(); + dir.close(); #endif - DEBUG_PRINTLN(F("Not connected!!")); - return false; - } - DEBUG_PRINTLN(F("Connected!!")); + DEBUG_PRINTLN(F("Not connected!!")); + return false; + } + DEBUG_PRINTLN(F("Connected!!")); #if STORAGE_TYPE == STORAGE_SPIFFS - DEBUG_PRINTLN("DIR MLSD "); - #if ESP8266 - if( dir.next()) - #else - File fileDir = dir.openNextFile(); - if( fileDir ) - #endif - { - DEBUG_PRINTLN("DIR NEXT "); - char dtStr[ 15 ]; - - struct tm * timeinfo; - - #if ESP8266 - time_t time = dir.fileTime(); - #else - time_t time = fileDir.getLastWrite(); - #endif - - timeinfo = localtime ( &time ); - - // 2000 01 01 16 06 56 - - strftime (dtStr,15,"%Y%m%d%H%M%S",timeinfo); - - - #if ESP8266 - String fn = dir.fileName(); - fn.remove(0, fn.lastIndexOf("/")+1); - long fz = dir.fileSize(); - #else - String fn = fileDir.name(); - fn.remove(0, fn.lastIndexOf("/")+1); - long fz = fileDir.size(); - #endif - - data.print( F("Type=") ); - - data.print( F("file") ); - data.print( F(";Modify=") ); data.print(dtStr);// data.print( makeDateTimeStr( dtStr, time, time) ); - data.print( F(";Size=") ); data.print( fz ); - data.print( F("; ") ); data.println( fn ); - - DEBUG_PRINT( F("Type=") ); - DEBUG_PRINT( F("file") ); - - DEBUG_PRINT( F(";Modify=") ); DEBUG_PRINT(dtStr); //DEBUG_PRINT( makeDateTimeStr( dtStr, time, time) ); - DEBUG_PRINT( F(";Size=") ); DEBUG_PRINT( fz ); - DEBUG_PRINT( F("; ") ); DEBUG_PRINTLN( fn ); - - nbMatch ++; - return true; - } -#elif STORAGE_TYPE == STORAGE_LITTLEFS || STORAGE_TYPE == STORAGE_SEEED_SD || STORAGE_TYPE == STORAGE_FFAT - DEBUG_PRINTLN("DIR MLSD "); - #if ESP8266 - if( dir.next()) - #else -#if STORAGE_TYPE == STORAGE_SEEED_SD - File fileDir = STORAGE_MANAGER.open(dir.name()); - fileDir = dir.openNextFile(); + DEBUG_PRINTLN("DIR MLSD "); +#if ESP8266 + if(dir.next()) #else - File fileDir = dir.openNextFile(); + File fileDir = dir.openNextFile(); + if(fileDir) #endif - DEBUG_PRINTLN(dir); - DEBUG_PRINTLN(fileDir); - if( fileDir ) - #endif - { - DEBUG_PRINTLN("DIR NEXT "); - char dtStr[ 15 ]; + { + DEBUG_PRINTLN("DIR NEXT "); + char dtStr[15]; + struct tm* timeinfo; - #if STORAGE_TYPE == STORAGE_SEEED_SD - struct tm * timeinfo; +#if ESP8266 + time_t time = dir.fileTime(); +#else + time_t time = fileDir.getLastWrite(); +#endif - strcpy(dtStr, "19700101000000"); - #else - struct tm * timeinfo; + timeinfo = localtime(&time); - #if ESP8266 - time_t time = dir.fileTime(); - #else - time_t time = fileDir.getLastWrite(); - #endif + // 2000 01 01 16 06 56 - timeinfo = localtime ( &time ); + strftime(dtStr, 15, "%Y%m%d%H%M%S", timeinfo); - // 2000 01 01 16 06 56 +#if ESP8266 + String fn = dir.fileName(); + fn.remove(0, fn.lastIndexOf("/") + 1); + long fz = dir.fileSize(); +#else + String fn = fileDir.name(); + fn.remove(0, fn.lastIndexOf("/") + 1); + long fz = fileDir.size(); +#endif - strftime (dtStr,15,"%Y%m%d%H%M%S",timeinfo); - #endif + data.print(F("Type=")); - #if ESP8266 - String fn = dir.fileName(); - long fz = dir.fileSize(); - FTP_DIR fileDir = dir; - #elif STORAGE_TYPE == STORAGE_SEEED_SD - String fn = fileDir.name(); - fn.remove(0, strlen(dir.name())); - if (fn[0]=='/') { fn.remove(0, fn.lastIndexOf("/")+1); } - long fz = fileDir.size(); - #else - String fn = fileDir.name(); - fn.remove(0, fn.lastIndexOf("/")+1); - long fz = fileDir.size(); - #endif + data.print(F("file")); + data.print(F(";Modify=")); + data.print(dtStr); // data.print( makeDateTimeStr( dtStr, time, time) ); + data.print(F(";Size=")); + data.print(fz); + data.print(F("; ")); + data.println(fn); - data.print( F("Type=") ); + DEBUG_PRINT(F("Type=")); + DEBUG_PRINT(F("file")); - data.print( ( fileDir.isDirectory() ? F("dir") : F("file")) ); - data.print( F(";Modify=") ); data.print(dtStr);// data.print( makeDateTimeStr( dtStr, time, time) ); - data.print( F(";Size=") ); data.print( fz ); - data.print( F("; ") ); data.println( fn ); + DEBUG_PRINT(F(";Modify=")); + DEBUG_PRINT(dtStr); // DEBUG_PRINT( makeDateTimeStr( dtStr, time, time) ); + DEBUG_PRINT(F(";Size=")); + DEBUG_PRINT(fz); + DEBUG_PRINT(F("; ")); + DEBUG_PRINTLN(fn); - DEBUG_PRINT( F("Type=") ); - DEBUG_PRINT( ( fileDir.isDirectory() ? F("dir") : F("file")) ); + nbMatch++; + return true; + } +#elif STORAGE_TYPE == STORAGE_LITTLEFS || STORAGE_TYPE == STORAGE_SEEED_SD || STORAGE_TYPE == STORAGE_FFAT + DEBUG_PRINTLN("DIR MLSD "); +#if ESP8266 + if(dir.next()) +#else +#if STORAGE_TYPE == STORAGE_SEEED_SD + File fileDir = STORAGE_MANAGER.open(dir.name()); + fileDir = dir.openNextFile(); +#else + File fileDir = dir.openNextFile(); +#endif + DEBUG_PRINTLN(dir); + DEBUG_PRINTLN(fileDir); + if(fileDir) +#endif + { + DEBUG_PRINTLN("DIR NEXT "); + char dtStr[15]; - DEBUG_PRINT( F(";Modify=") ); DEBUG_PRINT(dtStr); //DEBUG_PRINT( makeDateTimeStr( dtStr, time, time) ); - DEBUG_PRINT( F(";Size=") ); DEBUG_PRINT( fz ); - DEBUG_PRINT( F("; ") ); DEBUG_PRINTLN( fn ); +#if STORAGE_TYPE == STORAGE_SEEED_SD + struct tm* timeinfo; - nbMatch ++; + strcpy(dtStr, "19700101000000"); +#else + struct tm* timeinfo; + +#if ESP8266 + time_t time = dir.fileTime(); +#else + time_t time = fileDir.getLastWrite(); +#endif + + timeinfo = localtime(&time); + + // 2000 01 01 16 06 56 + + strftime(dtStr, 15, "%Y%m%d%H%M%S", timeinfo); +#endif + +#if ESP8266 + String fn = dir.fileName(); + long fz = dir.fileSize(); + FTP_DIR fileDir = dir; +#elif STORAGE_TYPE == STORAGE_SEEED_SD + String fn = fileDir.name(); + fn.remove(0, strlen(dir.name())); + if(fn[0] == '/') { + fn.remove(0, fn.lastIndexOf("/") + 1); + } + long fz = fileDir.size(); +#else + String fn = fileDir.name(); + fn.remove(0, fn.lastIndexOf("/") + 1); + long fz = fileDir.size(); +#endif + + data.print(F("Type=")); + + data.print((fileDir.isDirectory() ? F("dir") : F("file"))); + data.print(F(";Modify=")); + data.print(dtStr); // data.print( makeDateTimeStr( dtStr, time, time) ); + data.print(F(";Size=")); + data.print(fz); + data.print(F("; ")); + data.println(fn); + + DEBUG_PRINT(F("Type=")); + DEBUG_PRINT((fileDir.isDirectory() ? F("dir") : F("file"))); + + DEBUG_PRINT(F(";Modify=")); + DEBUG_PRINT(dtStr); // DEBUG_PRINT( makeDateTimeStr( dtStr, time, time) ); + DEBUG_PRINT(F(";Size=")); + DEBUG_PRINT(fz); + DEBUG_PRINT(F("; ")); + DEBUG_PRINTLN(fn); + + nbMatch++; // RoSchmi: next line was commented #if STORAGE_TYPE == STORAGE_SEEED_SD - fileDir.close(); + fileDir.close(); #endif - return true; - } + return true; + } #elif STORAGE_TYPE == STORAGE_SD - DEBUG_PRINTLN("DIR MLSD "); - File fileDir = dir.openNextFile(); - if( fileDir ) - { - DEBUG_PRINTLN("DIR NEXT "); - char dtStr[ 15 ]; + DEBUG_PRINTLN("DIR MLSD "); + File fileDir = dir.openNextFile(); + if(fileDir) { + DEBUG_PRINTLN("DIR NEXT "); + char dtStr[15]; - struct tm * timeinfo; + struct tm* timeinfo; - strcpy(dtStr, "19700101000000"); + strcpy(dtStr, "19700101000000"); + // long fz = dir.fileSize(); + String fn = fileDir.name(); -// long fz = dir.fileSize(); - String fn = fileDir.name(); + //#ifdef ESP32 + fn.remove(0, fn.lastIndexOf("/") + 1); + //#else if !defined(ESP8266) + // fn.remove(0, 1); + //#endif -//#ifdef ESP32 - fn.remove(0, fn.lastIndexOf("/")+1); -//#else if !defined(ESP8266) -// fn.remove(0, 1); -//#endif + long fz = fileDir.size(); + data.print(F("Type=")); - long fz = fileDir.size(); + data.print((fileDir.isDirectory() ? F("dir") : F("file"))); + data.print(F(";Modify=")); + data.print(dtStr); // data.print( makeDateTimeStr( dtStr, time, time) ); + data.print(F(";Size=")); + data.print(fz); + data.print(F("; ")); + data.println(fn); - data.print( F("Type=") ); + DEBUG_PRINT(F("Type=")); + DEBUG_PRINT((fileDir.isDirectory() ? F("dir") : F("file"))); - data.print( ( fileDir.isDirectory() ? F("dir") : F("file")) ); - data.print( F(";Modify=") ); data.print(dtStr);// data.print( makeDateTimeStr( dtStr, time, time) ); - data.print( F(";Size=") ); data.print( fz ); - data.print( F("; ") ); data.println( fn ); + DEBUG_PRINT(F(";Modify=")); + DEBUG_PRINT(dtStr); // DEBUG_PRINT( makeDateTimeStr( dtStr, time, time) ); + DEBUG_PRINT(F(";Size=")); + DEBUG_PRINT(fz); + DEBUG_PRINT(F("; ")); + DEBUG_PRINTLN(fn); - DEBUG_PRINT( F("Type=") ); - DEBUG_PRINT( ( fileDir.isDirectory() ? F("dir") : F("file")) ); - - DEBUG_PRINT( F(";Modify=") ); DEBUG_PRINT(dtStr); //DEBUG_PRINT( makeDateTimeStr( dtStr, time, time) ); - DEBUG_PRINT( F(";Size=") ); DEBUG_PRINT( fz ); - DEBUG_PRINT( F("; ") ); DEBUG_PRINTLN( fn ); - - nbMatch ++; - return true; - } + nbMatch++; + return true; + } #elif STORAGE_TYPE == STORAGE_FATFS - if( dir.nextFile()) - { - char dtStr[ 15 ]; - data.print( F("Type=") ); data.print( ( dir.isDir() ? F("dir") : F("file")) ); - data.print( F(";Modify=") ); data.print( makeDateTimeStr( dtStr, dir.fileModDate(), dir.fileModTime()) ); - data.print( F(";Size=") ); data.print( long( dir.fileSize()) ); - data.print( F("; ") ); data.println( dir.fileName() ); - nbMatch ++; - return true; - } -#else - if( file.openNext( &dir, FTP_FILE_READ_ONLY )) - { - char dtStr[ 15 ]; - uint16_t filelwd, filelwt; - bool gfmt = getFileModTime( & filelwd, & filelwt ); - DEBUG_PRINT("gfmt --> "); - DEBUG_PRINTLN(gfmt); - if( gfmt ) - { - data.print( F("Type=") ); data.print( ( file.isDir() ? F("dir") : F("file")) ); - data.print( F(";Modify=") ); data.print( makeDateTimeStr( dtStr, filelwd, filelwt ) ); - data.print( F(";Size=") ); data.print( long( fileSize( file )) ); data.print( F("; ") ); - file.printName( & data ); - data.println(); - - DEBUG_PRINT( F("Type=") ); DEBUG_PRINT( ( file.isDir() ? F("dir") : F("file")) ); - DEBUG_PRINT( F(";Modify=") ); DEBUG_PRINT( makeDateTimeStr( dtStr, filelwd, filelwt ) ); - DEBUG_PRINT( F(";Size=") ); DEBUG_PRINT( long( fileSize( file )) ); DEBUG_PRINT( F("; ") ); -// DEBUG_PRINT(file.name()); - DEBUG_PRINTLN(); - nbMatch ++; + if(dir.nextFile()) { + char dtStr[15]; + data.print(F("Type=")); + data.print((dir.isDir() ? F("dir") : F("file"))); + data.print(F(";Modify=")); + data.print(makeDateTimeStr(dtStr, dir.fileModDate(), dir.fileModTime())); + data.print(F(";Size=")); + data.print(long(dir.fileSize())); + data.print(F("; ")); + data.println(dir.fileName()); + nbMatch++; + return true; + } +#else + if(file.openNext(&dir, FTP_FILE_READ_ONLY)) { + char dtStr[15]; + uint16_t filelwd, filelwt; + bool gfmt = getFileModTime(&filelwd, &filelwt); + DEBUG_PRINT("gfmt --> "); + DEBUG_PRINTLN(gfmt); + if(gfmt) { + data.print(F("Type=")); + data.print((file.isDir() ? F("dir") : F("file"))); + data.print(F(";Modify=")); + data.print(makeDateTimeStr(dtStr, filelwd, filelwt)); + data.print(F(";Size=")); + data.print(long(fileSize(file))); + data.print(F("; ")); + file.printName(&data); + data.println(); + + DEBUG_PRINT(F("Type=")); + DEBUG_PRINT((file.isDir() ? F("dir") : F("file"))); + DEBUG_PRINT(F(";Modify=")); + DEBUG_PRINT(makeDateTimeStr(dtStr, filelwd, filelwt)); + DEBUG_PRINT(F(";Size=")); + DEBUG_PRINT(long(fileSize(file))); + DEBUG_PRINT(F("; ")); + // DEBUG_PRINT(file.name()); + DEBUG_PRINTLN(); + nbMatch++; + } + file.close(); + return gfmt; } - file.close(); - return gfmt; - } #endif - client.println(F("226-options: -a -l") ); - client.print( F("226 ") ); client.print( nbMatch ); client.println( F(" matches total") ); -#if STORAGE_TYPE != STORAGE_SPIFFS && STORAGE_TYPE != STORAGE_LITTLEFS && STORAGE_TYPE != STORAGE_SEEED_SD && STORAGE_TYPE != STORAGE_SEEED_SD + client.println(F("226-options: -a -l")); + client.print(F("226 ")); + client.print(nbMatch); + client.println(F(" matches total")); +#if STORAGE_TYPE != STORAGE_SPIFFS && STORAGE_TYPE != STORAGE_LITTLEFS && STORAGE_TYPE != STORAGE_SEEED_SD && \ + STORAGE_TYPE != STORAGE_SEEED_SD dir.close(); #endif - data.stop(); - DEBUG_PRINTLN(F("All file readed!!")); - return false; + data.stop(); + DEBUG_PRINTLN(F("All file readed!!")); + return false; } void FtpServer::closeTransfer() { - uint32_t deltaT = (int32_t) ( millis() - millisBeginTrans ); - if( deltaT > 0 && bytesTransfered > 0 ) - { - DEBUG_PRINT( F(" Transfer completed in ") ); DEBUG_PRINT( deltaT ); DEBUG_PRINTLN( F(" ms, ") ); - DEBUG_PRINT( bytesTransfered / deltaT ); DEBUG_PRINTLN( F(" kbytes/s") ); + uint32_t deltaT = (int32_t)(millis() - millisBeginTrans); + if(deltaT > 0 && bytesTransfered > 0) { + DEBUG_PRINT(F(" Transfer completed in ")); + DEBUG_PRINT(deltaT); + DEBUG_PRINTLN(F(" ms, ")); + DEBUG_PRINT(bytesTransfered / deltaT); + DEBUG_PRINTLN(F(" kbytes/s")); - if (FtpServer::_transferCallback) { - FtpServer::_transferCallback(FTP_TRANSFER_STOP, getFileName(&file), bytesTransfered); - } + if(FtpServer::_transferCallback) { + FtpServer::_transferCallback(FTP_TRANSFER_STOP, getFileName(&file), bytesTransfered); + } + client.println(F("226-File successfully transferred")); + client.print(F("226 ")); + client.print(deltaT); + client.print(F(" ms, ")); + client.print(bytesTransfered / deltaT); + client.println(F(" kbytes/s")); + } else + client.println(F("226 File successfully transferred")); - client.println(F("226-File successfully transferred") ); - client.print( F("226 ") ); client.print( deltaT ); client.print( F(" ms, ") ); - client.print( bytesTransfered / deltaT ); client.println( F(" kbytes/s") ); - } - else - client.println(F("226 File successfully transferred") ); - - file.close(); - data.stop(); + file.close(); + data.stop(); } void FtpServer::abortTransfer() { - if( transferStage != FTP_Close ) - { - if (FtpServer::_transferCallback) { - FtpServer::_transferCallback(FTP_TRANSFER_ERROR, getFileName(&file), bytesTransfered); - } + if(transferStage != FTP_Close) { + if(FtpServer::_transferCallback) { + FtpServer::_transferCallback(FTP_TRANSFER_ERROR, getFileName(&file), bytesTransfered); + } - file.close(); + file.close(); #if STORAGE_TYPE != STORAGE_SPIFFS && STORAGE_TYPE != STORAGE_LITTLEFS && STORAGE_TYPE != STORAGE_SEEED_SD - dir.close(); + dir.close(); #endif - client.println(F("426 Transfer aborted") ); - DEBUG_PRINTLN( F(" Transfer aborted!") ); + client.println(F("426 Transfer aborted")); + DEBUG_PRINTLN(F(" Transfer aborted!")); - transferStage = FTP_Close; - } -// if( data.connected()) - data.stop(); + transferStage = FTP_Close; + } + // if( data.connected()) + data.stop(); } // Read a char from client connected to ftp server @@ -1556,79 +1611,67 @@ void FtpServer::abortTransfer() // -2 if buffer cmdLine is full // -1 if line not completed // 0 if empty line received -// length of cmdLine (positive) if no empty line received +// length of cmdLine (positive) if no empty line received int8_t FtpServer::readChar() { - int8_t rc = -1; + int8_t rc = -1; - if( client.available()) - { - char c = client.read(); - DEBUG_PRINT("-"); - DEBUG_PRINT( c ); + if(client.available()) { + char c = client.read(); + DEBUG_PRINT("-"); + DEBUG_PRINT(c); - if( c == '\\' ) - c = '/'; - if( c != '\r' ){ - if( c != '\n' ) - { - if( iCL < FTP_CMD_SIZE ) - cmdLine[ iCL ++ ] = c; - else - rc = -2; // Line too long - } - else - { - cmdLine[ iCL ] = 0; - command[ 0 ] = 0; - parameter = NULL; - // empty line? - if( iCL == 0 ) - rc = 0; - else - { - rc = iCL; - // search for space between command and parameter - parameter = strchr( cmdLine, ' ' ); - if( parameter != NULL ) - { - if( parameter - cmdLine > 4 ) - rc = -2; // Syntax error - else - { - strncpy( command, cmdLine, parameter - cmdLine ); - command[ parameter - cmdLine ] = 0; - while( * ( ++ parameter ) == ' ' ) - ; + if(c == '\\') c = '/'; + if(c != '\r') { + if(c != '\n') { + if(iCL < FTP_CMD_SIZE) + cmdLine[iCL++] = c; + else + rc = -2; // Line too long + } else { + cmdLine[iCL] = 0; + command[0] = 0; + parameter = NULL; + // empty line? + if(iCL == 0) + rc = 0; + else { + rc = iCL; + // search for space between command and parameter + parameter = strchr(cmdLine, ' '); + if(parameter != NULL) { + if(parameter - cmdLine > 4) + rc = -2; // Syntax error + else { + strncpy(command, cmdLine, parameter - cmdLine); + command[parameter - cmdLine] = 0; + while(*(++parameter) == ' ') + ; + } + } else if(strlen(cmdLine) > 4) + rc = -2; // Syntax error. + else + strcpy(command, cmdLine); + iCL = 0; + } } - } - else if( strlen( cmdLine ) > 4 ) - rc = -2; // Syntax error. - else - strcpy( command, cmdLine ); - iCL = 0; } - } + if(rc > 0) + for(uint8_t i = 0; i < strlen(command); i++) command[i] = toupper(command[i]); + if(rc == -2) { + iCL = 0; + client.println(F("500 Syntax error")); + } } - if( rc > 0 ) - for( uint8_t i = 0 ; i < strlen( command ); i ++ ) - command[ i ] = toupper( command[ i ] ); - if( rc == -2 ) - { - iCL = 0; - client.println(F("500 Syntax error")); - } - } - return rc; + return rc; } bool FtpServer::haveParameter() { - if( parameter != NULL && strlen( parameter ) > 0 ) - return true; - client.println("501 No file name" ); - return false; + if(parameter != NULL && strlen(parameter) > 0) return true; + client.println("501 No file name"); + return false; } // Make complete path/name from cwdName and param @@ -1641,63 +1684,56 @@ bool FtpServer::haveParameter() // return: // true, if done -bool FtpServer::makePath( char * fullName, char * param ) +bool FtpServer::makePath(char* fullName, char* param) { - if( param == NULL ) - param = parameter; - - // Root or empty? - if( strcmp( param, "/" ) == 0 || strlen( param ) == 0 ) - { - strcpy( fullName, "/" ); - return true; - } - // If relative path, concatenate with current dir - if( param[0] != '/' ) - { - strcpy( fullName, cwdName ); - if( fullName[ strlen( fullName ) - 1 ] != '/' ) - strncat( fullName, "/", FTP_CWD_SIZE ); - strncat( fullName, param, FTP_CWD_SIZE ); - } - else - strcpy( fullName, param ); - // If ends with '/', remove it - uint16_t strl = strlen( fullName ) - 1; - if( fullName[ strl ] == '/' && strl > 1 ) - fullName[ strl ] = 0; - if( strlen( fullName ) >= FTP_CWD_SIZE ) - { - client.println(F("500 Command line too long")); - return false; - } - for( uint8_t i = 0; i < strlen( fullName ); i ++ ) - if( ! legalChar( fullName[i])) - { - client.println(F("553 File name not allowed") ); - return false; + if(param == NULL) param = parameter; + + // Root or empty? + if(strcmp(param, "/") == 0 || strlen(param) == 0) { + strcpy(fullName, "/"); + return true; } - return true; + // If relative path, concatenate with current dir + if(param[0] != '/') { + strcpy(fullName, cwdName); + if(fullName[strlen(fullName) - 1] != '/') strncat(fullName, "/", FTP_CWD_SIZE); + strncat(fullName, param, FTP_CWD_SIZE); + } else + strcpy(fullName, param); + // If ends with '/', remove it + uint16_t strl = strlen(fullName) - 1; + if(fullName[strl] == '/' && strl > 1) fullName[strl] = 0; + if(strlen(fullName) >= FTP_CWD_SIZE) { + client.println(F("500 Command line too long")); + return false; + } + for(uint8_t i = 0; i < strlen(fullName); i++) + if(!legalChar(fullName[i])) { + client.println(F("553 File name not allowed")); + return false; + } + return true; } -bool FtpServer::makeExistsPath( char * path, char * param ) +bool FtpServer::makeExistsPath(char* path, char* param) { - if( ! makePath( path, param )) - return false; - // RoSchmi - //#if STORAGE_TYPE == STORAGE_SPIFFS || STORAGE_TYPE == STORAGE_SD -#if (STORAGE_TYPE == STORAGE_SPIFFS || STORAGE_TYPE == STORAGE_SD || STORAGE_TYPE == STORAGE_SEEED_SD) - if (strcmp(path, "/") == 0) return true; + if(!makePath(path, param)) return false; + // RoSchmi + //#if STORAGE_TYPE == STORAGE_SPIFFS || STORAGE_TYPE == STORAGE_SD +#if(STORAGE_TYPE == STORAGE_SPIFFS || STORAGE_TYPE == STORAGE_SD || STORAGE_TYPE == STORAGE_SEEED_SD) + if(strcmp(path, "/") == 0) return true; #endif - DEBUG_PRINT("PATH --> ") - DEBUG_PRINT(path) - if( exists( path )) { - DEBUG_PRINTLN(" ...EXIST!") - return true; - } - DEBUG_PRINTLN(" ...NOT EXIST!") - client.print(F("550 ")); client.print( path ); client.println( F(" not found.") ); - return false; + DEBUG_PRINT("PATH --> ") + DEBUG_PRINT(path) + if(exists(path)) { + DEBUG_PRINTLN(" ...EXIST!") + return true; + } + DEBUG_PRINTLN(" ...NOT EXIST!") + client.print(F("550 ")); + client.print(path); + client.println(F(" not found.")); + return false; } // Calculate year, month, day, hour, minute and second @@ -1717,335 +1753,352 @@ bool FtpServer::makeExistsPath( char * path, char * param ) // Date/time are expressed as a 14 digits long string // terminated by a space and followed by name of file -uint8_t FtpServer::getDateTime( char * dt, uint16_t * pyear, uint8_t * pmonth, uint8_t * pday, - uint8_t * phour, uint8_t * pminute, uint8_t * psecond ) +uint8_t FtpServer::getDateTime(char* dt, uint16_t* pyear, uint8_t* pmonth, uint8_t* pday, uint8_t* phour, + uint8_t* pminute, uint8_t* psecond) { - uint8_t i; - dt[ 0 ] = 0; - if( strlen( parameter ) < 15 ) //|| parameter[ 14 ] != ' ' ) - return 0; - for( i = 0; i < 14; i ++ ) - if( ! isdigit( parameter[ i ])) - return 0; - for( i = 14; i < 18; i ++ ) - if( parameter[ i ] == ' ' ) - break; - else if( ! isdigit( parameter[ i ])) - return 0; - if( i == 18 ) - return 0; - i ++ ; - - strncpy( dt, parameter, 14 ); - dt[ 14 ] = 0; - * psecond = atoi( dt + 12 ); - dt[ 12 ] = 0; - * pminute = atoi( dt + 10 ); - dt[ 10 ] = 0; - * phour = atoi( dt + 8 ); - dt[ 8 ] = 0; - * pday = atoi( dt + 6 ); - dt[ 6 ] = 0 ; - * pmonth = atoi( dt + 4 ); - dt[ 4 ] = 0 ; - * pyear = atoi( dt ); - strncpy( dt, parameter, 14 ); - DEBUG_PRINT( F(" Modification time: ") ); DEBUG_PRINT( * pyear ); DEBUG_PRINT( F("/") ); DEBUG_PRINT( int(* pmonth) ); DEBUG_PRINT( F("/") ); DEBUG_PRINT( int(* pday) ); - DEBUG_PRINT( F(" ") ); DEBUG_PRINT( int(* phour) ); DEBUG_PRINT( F(":") ); DEBUG_PRINT( int(* pminute) ); DEBUG_PRINT( F(":") ); DEBUG_PRINT( int(* psecond) ); - DEBUG_PRINT( F(" of file: ") ); DEBUG_PRINTLN( (char *) ( parameter + i ) ); + uint8_t i; + dt[0] = 0; + if(strlen(parameter) < 15) //|| parameter[ 14 ] != ' ' ) + return 0; + for(i = 0; i < 14; i++) + if(!isdigit(parameter[i])) return 0; + for(i = 14; i < 18; i++) + if(parameter[i] == ' ') + break; + else if(!isdigit(parameter[i])) + return 0; + if(i == 18) return 0; + i++; - return i; + strncpy(dt, parameter, 14); + dt[14] = 0; + *psecond = atoi(dt + 12); + dt[12] = 0; + *pminute = atoi(dt + 10); + dt[10] = 0; + *phour = atoi(dt + 8); + dt[8] = 0; + *pday = atoi(dt + 6); + dt[6] = 0; + *pmonth = atoi(dt + 4); + dt[4] = 0; + *pyear = atoi(dt); + strncpy(dt, parameter, 14); + DEBUG_PRINT(F(" Modification time: ")); + DEBUG_PRINT(*pyear); + DEBUG_PRINT(F("/")); + DEBUG_PRINT(int(*pmonth)); + DEBUG_PRINT(F("/")); + DEBUG_PRINT(int(*pday)); + DEBUG_PRINT(F(" ")); + DEBUG_PRINT(int(*phour)); + DEBUG_PRINT(F(":")); + DEBUG_PRINT(int(*pminute)); + DEBUG_PRINT(F(":")); + DEBUG_PRINT(int(*psecond)); + DEBUG_PRINT(F(" of file: ")); + DEBUG_PRINTLN((char*)(parameter + i)); + + return i; } // Create string YYYYMMDDHHMMSS from date and time // // parameters: -// date, time +// date, time // tstr: where to store the string. Must be at least 15 characters long // // return: // pointer to tstr -char * FtpServer::makeDateTimeStr( char * tstr, uint16_t date, uint16_t time ) +char* FtpServer::makeDateTimeStr(char* tstr, uint16_t date, uint16_t time) { - sprintf( tstr, "%04u%02u%02u%02u%02u%02u", - (( date & 0xFE00 ) >> 9 ) + 1980, ( date & 0x01E0 ) >> 5, date & 0x001F, - ( time & 0xF800 ) >> 11, ( time & 0x07E0 ) >> 5, ( time & 0x001F ) << 1 ); - return tstr; + sprintf(tstr, "%04u%02u%02u%02u%02u%02u", ((date & 0xFE00) >> 9) + 1980, (date & 0x01E0) >> 5, date & 0x001F, + (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) << 1); + return tstr; } - -uint16_t FtpServer::fileSize( FTP_FILE file ) { -#if (STORAGE_TYPE == STORAGE_SPIFFS || STORAGE_TYPE == STORAGE_LITTLEFS || STORAGE_TYPE == STORAGE_FFAT || STORAGE_TYPE == STORAGE_SD || STORAGE_TYPE == STORAGE_SEEED_SD) - return file.size(); +uint16_t FtpServer::fileSize(FTP_FILE file) +{ +#if(STORAGE_TYPE == STORAGE_SPIFFS || STORAGE_TYPE == STORAGE_LITTLEFS || STORAGE_TYPE == STORAGE_FFAT || \ + STORAGE_TYPE == STORAGE_SD || STORAGE_TYPE == STORAGE_SEEED_SD) + return file.size(); #else - return file.fileSize(); + return file.fileSize(); #endif } -#if (STORAGE_TYPE == STORAGE_SEEED_SD) - bool FtpServer::openFile( char path[ FTP_CWD_SIZE ], int readTypeInt ){ - DEBUG_PRINT(F("File to open ") ); - DEBUG_PRINT( path ); - DEBUG_PRINT(F(" readType ") ); - DEBUG_PRINTLN(readTypeInt); +#if(STORAGE_TYPE == STORAGE_SEEED_SD) +bool FtpServer::openFile(char path[FTP_CWD_SIZE], int readTypeInt) +{ + DEBUG_PRINT(F("File to open ")); + DEBUG_PRINT(path); + DEBUG_PRINT(F(" readType ")); + DEBUG_PRINTLN(readTypeInt); - if (readTypeInt == 0X01) { - readTypeInt = FILE_READ; - }else { - readTypeInt = FILE_WRITE; - } + if(readTypeInt == 0X01) { + readTypeInt = FILE_READ; + } else { + readTypeInt = FILE_WRITE; + } - file = STORAGE_MANAGER.open( path, readTypeInt ); - if (!file) { // && readTypeInt[0]==FILE_READ) { - return false; - }else{ - DEBUG_PRINTLN("TRUE"); + file = STORAGE_MANAGER.open(path, readTypeInt); + if(!file) { // && readTypeInt[0]==FILE_READ) { + return false; + } else { + DEBUG_PRINTLN("TRUE"); - return true; - } + return true; + } } -#elif (STORAGE_TYPE == STORAGE_SD && defined(ESP8266))// FTP_SERVER_NETWORK_TYPE_SELECTED == NETWORK_ESP8266_242) - bool FtpServer::openFile( char path[ FTP_CWD_SIZE ], int readTypeInt ){ - DEBUG_PRINT(F("File to open ") ); - DEBUG_PRINT( path ); - DEBUG_PRINT(F(" readType ") ); - DEBUG_PRINTLN(readTypeInt); +#elif(STORAGE_TYPE == STORAGE_SD && defined(ESP8266)) // FTP_SERVER_NETWORK_TYPE_SELECTED == NETWORK_ESP8266_242) +bool FtpServer::openFile(char path[FTP_CWD_SIZE], int readTypeInt) +{ + DEBUG_PRINT(F("File to open ")); + DEBUG_PRINT(path); + DEBUG_PRINT(F(" readType ")); + DEBUG_PRINTLN(readTypeInt); - if (readTypeInt == 0X01) { - readTypeInt = FILE_READ; - }else { - readTypeInt = FILE_WRITE; - } + if(readTypeInt == 0X01) { + readTypeInt = FILE_READ; + } else { + readTypeInt = FILE_WRITE; + } - file = STORAGE_MANAGER.open( path, readTypeInt ); - if (!file) { // && readTypeInt[0]==FILE_READ) { - return false; - }else{ - DEBUG_PRINTLN("TRUE"); + file = STORAGE_MANAGER.open(path, readTypeInt); + if(!file) { // && readTypeInt[0]==FILE_READ) { + return false; + } else { + DEBUG_PRINTLN("TRUE"); - return true; - } + return true; + } } -#elif (STORAGE_TYPE == STORAGE_SPIFFS || STORAGE_TYPE == STORAGE_LITTLEFS || STORAGE_TYPE == STORAGE_FFAT ) - bool FtpServer::openFile( const char * path, const char * readType ) { - DEBUG_PRINT(F("File to open ") ); - DEBUG_PRINT( path ); - DEBUG_PRINT(F(" readType ") ); - DEBUG_PRINTLN(readType); - file = STORAGE_MANAGER.open( path, readType ); - if (!file && readType[0]=='r') { - return false; - }else{ - DEBUG_PRINTLN("TRUE"); +#elif(STORAGE_TYPE == STORAGE_SPIFFS || STORAGE_TYPE == STORAGE_LITTLEFS || STORAGE_TYPE == STORAGE_FFAT) +bool FtpServer::openFile(const char* path, const char* readType) +{ + DEBUG_PRINT(F("File to open ")); + DEBUG_PRINT(path); + DEBUG_PRINT(F(" readType ")); + DEBUG_PRINTLN(readType); + file = STORAGE_MANAGER.open(path, readType); + if(!file && readType[0] == 'r') { + return false; + } else { + DEBUG_PRINTLN("TRUE"); - return true; - } - } + return true; + } +} #elif STORAGE_TYPE <= STORAGE_SDFAT2 - bool FtpServer::openFile( char path[ FTP_CWD_SIZE ], int readTypeInt ){ - DEBUG_PRINT(F("File to open ") ); - DEBUG_PRINT( path ); - DEBUG_PRINT(F(" readType ") ); - DEBUG_PRINTLN(readTypeInt); +bool FtpServer::openFile(char path[FTP_CWD_SIZE], int readTypeInt) +{ + DEBUG_PRINT(F("File to open ")); + DEBUG_PRINT(path); + DEBUG_PRINT(F(" readType ")); + DEBUG_PRINTLN(readTypeInt); - file = STORAGE_MANAGER.open( path, readTypeInt ); - if (!file) { - return false; - }else{ - DEBUG_PRINTLN("TRUE"); + file = STORAGE_MANAGER.open(path, readTypeInt); + if(!file) { + return false; + } else { + DEBUG_PRINTLN("TRUE"); - return true; - } + return true; + } } #else - bool FtpServer::openFile( char path[ FTP_CWD_SIZE ], const char * readType ) { - return openFile( (const char*) path, readType ); - } - bool FtpServer::openFile( const char * path, const char * readType ) { - DEBUG_PRINT(F("File to open ") ); - DEBUG_PRINT( path ); - DEBUG_PRINT(F(" readType ") ); - DEBUG_PRINTLN(readType); - #if (STORAGE_TYPE == STORAGE_SD && !defined(ESP32)) - if (readType == 0X01) { - readType = FILE_READ; - }else { - readType = FILE_WRITE; - } - #endif - file = STORAGE_MANAGER.open( path, readType ); - if (!file && readType[0]=='r') { - return false; - }else{ - DEBUG_PRINTLN("TRUE"); +bool FtpServer::openFile(char path[FTP_CWD_SIZE], const char* readType) +{ + return openFile((const char*)path, readType); +} +bool FtpServer::openFile(const char* path, const char* readType) +{ + DEBUG_PRINT(F("File to open ")); + DEBUG_PRINT(path); + DEBUG_PRINT(F(" readType ")); + DEBUG_PRINTLN(readType); +#if(STORAGE_TYPE == STORAGE_SD && !defined(ESP32)) + if(readType == 0X01) { + readType = FILE_READ; + } else { + readType = FILE_WRITE; + } +#endif + file = STORAGE_MANAGER.open(path, readType); + if(!file && readType[0] == 'r') { + return false; + } else { + DEBUG_PRINTLN("TRUE"); - return true; - } - } + return true; + } +} #endif // Return true if path points to a directory -bool FtpServer::isDir( char * path ) +bool FtpServer::isDir(char* path) { -#if (STORAGE_TYPE == STORAGE_LITTLEFS && defined(ESP8266)) - FTP_DIR dir; - bool res; - dir = STORAGE_MANAGER.openDir( path ); +#if(STORAGE_TYPE == STORAGE_LITTLEFS && defined(ESP8266)) + FTP_DIR dir; + bool res; + dir = STORAGE_MANAGER.openDir(path); - return true; -// res = dir.isDirectory(); -// return res; + return true; + // res = dir.isDirectory(); + // return res; #elif STORAGE_TYPE == STORAGE_SPIFFS - if (strcmp(path, "/") == 0) { return true; } - return false; // no directory support -#elif STORAGE_TYPE == STORAGE_SEEED_SD || STORAGE_TYPE == STORAGE_FFAT || (STORAGE_TYPE == STORAGE_LITTLEFS && defined(ESP32)) - FTP_DIR dir; - bool res; - dir = STORAGE_MANAGER.open( path ); - -// return true; - res = dir.isDirectory(); - return res; -#elif STORAGE_TYPE == STORAGE_FATFS - return STORAGE_MANAGER.isDir( path ); -#elif STORAGE_TYPE == STORAGE_SDFAT1 || STORAGE_TYPE == STORAGE_SDFAT2 -// bool res = (!dir.open(path, FTP_FILE_READ) || !dir.isDir()); -// dir.close(); -// return res; - if (strcmp(path, "/") == 0) { return true; } - if( ! openFile( path, FTP_FILE_READ )) { - return false; + if(strcmp(path, "/") == 0) { + return true; } - return true; + return false; // no directory support +#elif STORAGE_TYPE == STORAGE_SEEED_SD || STORAGE_TYPE == STORAGE_FFAT || \ + (STORAGE_TYPE == STORAGE_LITTLEFS && defined(ESP32)) + FTP_DIR dir; + bool res; + dir = STORAGE_MANAGER.open(path); + + // return true; + res = dir.isDirectory(); + return res; +#elif STORAGE_TYPE == STORAGE_FATFS + return STORAGE_MANAGER.isDir(path); +#elif STORAGE_TYPE == STORAGE_SDFAT1 || STORAGE_TYPE == STORAGE_SDFAT2 + // bool res = (!dir.open(path, FTP_FILE_READ) || !dir.isDir()); + // dir.close(); + // return res; + if(strcmp(path, "/") == 0) { + return true; + } + if(!openFile(path, FTP_FILE_READ)) { + return false; + } + return true; #else - FTP_FILE file; - bool res; - - if( ! openFile( path, FTP_FILE_READ )) { - return false; - } + FTP_FILE file; + bool res; + + if(!openFile(path, FTP_FILE_READ)) { + return false; + } #if STORAGE_TYPE == STORAGE_SD -// if (strcmp(path, "/") == 0) return true; -// res = file.isDirectory(); -// DEBUG_PRINT(path); -// DEBUG_PRINT(" IS DIRECOTORY --> "); -// DEBUG_PRINTLN(res); - return true; + // if (strcmp(path, "/") == 0) return true; + // res = file.isDirectory(); + // DEBUG_PRINT(path); + // DEBUG_PRINT(" IS DIRECOTORY --> "); + // DEBUG_PRINTLN(res); + return true; #else // res = file.isDir(); // DEBUG_PRINT("IS DIRECTORY --> " ); // DEBUG_PRINTLN(res); #endif - file.close(); - return res; + file.close(); + return res; #endif } -bool FtpServer::timeStamp( char * path, uint16_t year, uint8_t month, uint8_t day, - uint8_t hour, uint8_t minute, uint8_t second ) +bool FtpServer::timeStamp(char* path, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, + uint8_t second) { -#if STORAGE_TYPE == STORAGE_SPIFFS || STORAGE_TYPE == STORAGE_LITTLEFS || STORAGE_TYPE == STORAGE_FFAT || STORAGE_TYPE == STORAGE_SD || STORAGE_TYPE == STORAGE_SEEED_SD -// struct tm tmDate = { second, minute, hour, day, month, year }; -// time_t rawtime = mktime(&tmDate); +#if STORAGE_TYPE == STORAGE_SPIFFS || STORAGE_TYPE == STORAGE_LITTLEFS || STORAGE_TYPE == STORAGE_FFAT || \ + STORAGE_TYPE == STORAGE_SD || STORAGE_TYPE == STORAGE_SEEED_SD + // struct tm tmDate = { second, minute, hour, day, month, year }; + // time_t rawtime = mktime(&tmDate); return true; - // setTime(rawtime); - // SPIFFS USE time() call + // setTime(rawtime); + // SPIFFS USE time() call // return STORAGE_MANAGER.timeStamp( path, year, month, day, hour, minute, second ); #elif STORAGE_TYPE == STORAGE_FATFS - return STORAGE_MANAGER.timeStamp( path, year, month, day, hour, minute, second ); + return STORAGE_MANAGER.timeStamp(path, year, month, day, hour, minute, second); #else - FTP_FILE file; - bool res; + FTP_FILE file; + bool res; - if( ! openFile( path, FTP_FILE_READ_WRITE )) - return false; - res = file.timestamp( T_WRITE, year, month, day, hour, minute, second ); - file.close(); - return res; + if(!openFile(path, FTP_FILE_READ_WRITE)) return false; + res = file.timestamp(T_WRITE, year, month, day, hour, minute, second); + file.close(); + return res; #endif } - -bool FtpServer::getFileModTime( char * path, uint16_t * pdate, uint16_t * ptime ) + +bool FtpServer::getFileModTime(char* path, uint16_t* pdate, uint16_t* ptime) { #if STORAGE_TYPE == STORAGE_FATFS - return STORAGE_MANAGER.getFileModTime( path, pdate, ptime ); + return STORAGE_MANAGER.getFileModTime(path, pdate, ptime); #else -// FTP_FILE file; - bool res; + // FTP_FILE file; + bool res; - if( ! openFile( path, FTP_FILE_READ )) { - return false; - } - res = getFileModTime( pdate, ptime ); - file.close(); - return res; + if(!openFile(path, FTP_FILE_READ)) { + return false; + } + res = getFileModTime(pdate, ptime); + file.close(); + return res; #endif } // Assume SD library is SdFat (or family) and file is open - + #if STORAGE_TYPE != STORAGE_FATFS -bool FtpServer::getFileModTime( uint16_t * pdate, uint16_t * ptime ) +bool FtpServer::getFileModTime(uint16_t* pdate, uint16_t* ptime) { #if STORAGE_TYPE == STORAGE_SPIFFS || STORAGE_TYPE == STORAGE_LITTLEFS || STORAGE_TYPE == STORAGE_FFAT - #if ESP8266 - return dir.fileTime(); - #else - return dir.getLastWrite(); - #endif -#elif STORAGE_TYPE == STORAGE_SDFAT1 || STORAGE_TYPE == STORAGE_SPIFM - dir_t d; - - if( ! file.dirEntry( & d )) - return false; - * pdate = d.lastWriteDate; - * ptime = d.lastWriteTime; - return true; -#elif STORAGE_TYPE == STORAGE_SDFAT2 - return file.getModifyDateTime( pdate, ptime ); +#if ESP8266 + return dir.fileTime(); +#else + return dir.getLastWrite(); #endif - return false; +#elif STORAGE_TYPE == STORAGE_SDFAT1 || STORAGE_TYPE == STORAGE_SPIFM + dir_t d; + + if(!file.dirEntry(&d)) return false; + *pdate = d.lastWriteDate; + *ptime = d.lastWriteTime; + return true; +#elif STORAGE_TYPE == STORAGE_SDFAT2 + return file.getModifyDateTime(pdate, ptime); +#endif + return false; } #endif #if STORAGE_TYPE == STORAGE_SD - bool FtpServer::rename( const char * path, const char * newpath ){ +bool FtpServer::rename(const char* path, const char* newpath) +{ - FTP_FILE myFileIn = STORAGE_MANAGER.open(path, FILE_READ); - FTP_FILE myFileOut = STORAGE_MANAGER.open(newpath, FILE_WRITE); + FTP_FILE myFileIn = STORAGE_MANAGER.open(path, FILE_READ); + FTP_FILE myFileOut = STORAGE_MANAGER.open(newpath, FILE_WRITE); - if(myFileOut) { - while (myFileIn.available() > 0) - { - int i = myFileIn.readBytes((char*)buf, FTP_BUF_SIZE); - myFileOut.write(buf, i); - } - // done, close the destination file - myFileOut.close(); - myFileOut = STORAGE_MANAGER.open(newpath, FILE_READ); + if(myFileOut) { + while(myFileIn.available() > 0) { + int i = myFileIn.readBytes((char*)buf, FTP_BUF_SIZE); + myFileOut.write(buf, i); + } + // done, close the destination file + myFileOut.close(); + myFileOut = STORAGE_MANAGER.open(newpath, FILE_READ); + } + bool operation = false; - } - bool operation = false; + DEBUG_PRINT(F("RENAME --> ")); + DEBUG_PRINT(myFileIn.size()); + DEBUG_PRINT(" size "); + DEBUG_PRINTLN(myFileOut.size()); - DEBUG_PRINT(F("RENAME --> ")); - DEBUG_PRINT(myFileIn.size()); - DEBUG_PRINT(" size "); - DEBUG_PRINTLN(myFileOut.size()); + if(myFileIn.size() == myFileOut.size()) { + operation = true; + } - if (myFileIn.size() == myFileOut.size()) { - operation = true; - } + if(!operation) return operation; + myFileIn.close(); + myFileOut.close(); - if (!operation) return operation; - - myFileIn.close(); - myFileOut.close(); - - return remove( path ); - }; + return remove(path); +}; #endif diff --git a/lib/SimpleFTPServer/FtpServer.h b/lib/SimpleFTPServer/FtpServer.h index 931d2d78..dfff905d 100644 --- a/lib/SimpleFTPServer/FtpServer.h +++ b/lib/SimpleFTPServer/FtpServer.h @@ -453,6 +453,7 @@ public: FtpServer( uint16_t _cmdPort = FTP_CMD_PORT, uint16_t _pasvPort = FTP_DATA_PORT_PASV ); void begin( const char * _user = FTP_USER, const char * _pass = FTP_PASS, const char * welcomeMessage = "Welcome to Simply FTP server" ); + void end(); void credentials( const char * _user, const char * _pass ); uint8_t handleFTP(); diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp index 2fbbef2d..0eb6bf8a 100644 --- a/src/hasp/hasp_dispatch.cpp +++ b/src/hasp/hasp_dispatch.cpp @@ -1279,6 +1279,14 @@ void dispatch_service(const char*, const char* payload, uint8_t source) } #endif +#if HASP_USE_FTP > 0 + if(!strcmp_P(payload, "start ftp")) { + ftpStart(); + } else if(!strcmp_P(payload, "stop ftp")) { + ftpStop(); + } +#endif + #if HASP_USE_HTTP > 0 || HASP_USE_HTTP_ASYNC > 0 if(!strcmp_P(payload, "start http")) { httpStart(); diff --git a/src/sys/svc/hasp_ftp.cpp b/src/sys/svc/hasp_ftp.cpp index 88c17dba..ebaf4851 100644 --- a/src/sys/svc/hasp_ftp.cpp +++ b/src/sys/svc/hasp_ftp.cpp @@ -16,19 +16,15 @@ #include "FtpServerKey.h" #include "SimpleFTPServer.h" +#if HASP_USE_HTTP > 0 || HASP_USE_HTTP_ASYNC > 0 +extern hasp_http_config_t http_config; +#endif + FtpServer ftpSrv; // set #define FTP_DEBUG in ESP8266FtpServer.h to see ftp verbose on serial uint16_t ftpPort = 23; uint8_t ftpEnabled = true; // Enable telnet debug output -#if HASP_USE_HTTP > 0 || HASP_USE_HTTP_ASYNC > 0 -extern hasp_http_config_t http_config; -static inline bool telnet_has_password() -{ - return (strlen(http_config.username) != 0) || (strlen(http_config.password) != 0); -} -#endif - void _callback(FtpOperation ftpOperation, unsigned int freeSpace, unsigned int totalSpace) { switch(ftpOperation) { @@ -81,16 +77,25 @@ void _transferCallback(FtpTransferOperation ftpOperation, const char* name, unsi }; void ftpStop(void) -{} +{ + // LOG_WARNING(TAG_FTP, F("Service cannot be stopped")); + ftpSrv.end(); + LOG_INFO(TAG_FTP, F(D_SERVICE_STOPPED)); +} void ftpStart() { - LOG_TRACE(TAG_TFT, F(D_SERVICE_STARTING)); + LOG_TRACE(TAG_FTP, F(D_SERVICE_STARTING)); ftpSrv.setCallback(_callback); ftpSrv.setTransferCallback(_transferCallback); - ftpSrv.begin("esp8266", "esp8266"); // username, password for ftp. (default 21, 50009 for PASV) - LOG_INFO(TAG_TFT, F(D_SERVICE_STARTED)); +#if HASP_USE_HTTP > 0 || HASP_USE_HTTP_ASYNC > 0 + ftpSrv.begin(http_config.username, http_config.password); // Password must be non-empty +#else + ftpSrv.begin("ftpuser", "haspadmin"); // username, password for ftp. (default 21, 50009 for PASV) +#endif + + LOG_INFO(TAG_FTP, F(D_SERVICE_STARTED)); } void ftpSetup()