Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
FTPClient.cpp
00001 /* FTP client library 00002 * Copyright (c) 2018 Renesas Electronics Corporation 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "mbed.h" 00018 #include "FTPClient.h" 00019 00020 #define FTP_BUF_SIZE (1460) 00021 00022 //#define ftp_debug_print printf 00023 00024 #ifndef ftp_debug_print 00025 static int ftp_debug_print(const char *format, ...) { 00026 return 0; 00027 } 00028 #endif 00029 00030 FTPClient::FTPClient(NetworkInterface *net, const char* root) { 00031 _ctr_open = false; 00032 _login = false; 00033 strcpy(_root, root); 00034 p_network = net; 00035 p_ftp_buf = new char[FTP_BUF_SIZE]; 00036 } 00037 00038 FTPClient::~FTPClient() { 00039 delete [] p_ftp_buf; 00040 } 00041 00042 bool FTPClient::open(const char* ip_addr, int port, const char* user, const char* pass) { 00043 if (_ctr_open) { 00044 FTPClientControlSock.close(); 00045 } 00046 00047 FTPClientControlSock.open(p_network); 00048 if (FTPClientControlSock.connect(ip_addr, port) < 0) { 00049 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00050 return false; 00051 } 00052 _ctr_open = true; 00053 00054 if (FTPClientControlSock.recv(p_ftp_buf, FTP_BUF_SIZE) <= 0) { 00055 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00056 return false; 00057 } 00058 if (strncmp(p_ftp_buf, "220", 3) != 0) { 00059 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00060 return false; 00061 } 00062 00063 _login = false; 00064 sprintf(p_ftp_buf, "user %s\r\n", user); 00065 FTPClientControlSock.send(p_ftp_buf, strlen(p_ftp_buf)); 00066 if (FTPClientControlSock.recv(p_ftp_buf, FTP_BUF_SIZE) <= 0) { 00067 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00068 return false; 00069 } 00070 if (strncmp(p_ftp_buf, "331", 3) != 0) { 00071 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00072 return false; 00073 } 00074 00075 sprintf(p_ftp_buf, "pass %s\r\n", pass); 00076 FTPClientControlSock.send(p_ftp_buf, strlen(p_ftp_buf)); 00077 if (FTPClientControlSock.recv(p_ftp_buf, FTP_BUF_SIZE) <= 0) { 00078 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00079 return false; 00080 } 00081 if (strncmp(p_ftp_buf, "230", 3) != 0) { 00082 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00083 return false; 00084 } 00085 00086 sprintf(p_ftp_buf, "type I\r\n"); 00087 FTPClientControlSock.send(p_ftp_buf, strlen(p_ftp_buf)); 00088 if (FTPClientControlSock.recv(p_ftp_buf, FTP_BUF_SIZE) <= 0) { 00089 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00090 return false; 00091 } 00092 00093 _login = true; 00094 return true; 00095 } 00096 00097 bool FTPClient::quit() { 00098 if (!_login) { 00099 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00100 return false; 00101 } 00102 00103 sprintf(p_ftp_buf, "quit\r\n"); 00104 FTPClientControlSock.send(p_ftp_buf, strlen(p_ftp_buf)); 00105 if (FTPClientControlSock.recv(p_ftp_buf, FTP_BUF_SIZE) <= 0) { 00106 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00107 return false; 00108 } 00109 if (strncmp(p_ftp_buf, "250", 3) != 0) { 00110 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00111 return false; 00112 } 00113 _login = false; 00114 00115 FTPClientControlSock.close(); 00116 _ctr_open = false; 00117 return true; 00118 } 00119 00120 bool FTPClient::get(const char* file_name) { 00121 FILE* fp; 00122 int size; 00123 00124 if (!_login) { 00125 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00126 return false; 00127 } 00128 00129 if (!open_data_sock()) { 00130 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00131 return false; 00132 } 00133 00134 FTPClientDataSock.set_timeout(500); 00135 sprintf(p_ftp_buf, "retr %s\r\n", file_name); 00136 FTPClientControlSock.send(p_ftp_buf, strlen(p_ftp_buf)); 00137 if (FTPClientControlSock.recv(p_ftp_buf, FTP_BUF_SIZE) <= 0) { 00138 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00139 return false; 00140 } 00141 if ((strncmp(p_ftp_buf, "150", 3) != 0) && (strncmp(p_ftp_buf, "125", 3) != 0)) { 00142 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00143 return false; 00144 } 00145 00146 sprintf(p_ftp_buf, "%s/%s", _root, file_name); 00147 fp = fopen(p_ftp_buf, "w"); 00148 while (1) { 00149 size = FTPClientDataSock.recv(p_ftp_buf, FTP_BUF_SIZE); 00150 if (size > 0) { 00151 fwrite(p_ftp_buf, size, sizeof(char), fp); 00152 } else { 00153 break; 00154 } 00155 } 00156 fclose(fp); 00157 FTPClientDataSock.close(); 00158 00159 if (FTPClientControlSock.recv(p_ftp_buf, FTP_BUF_SIZE) <= 0) { 00160 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00161 return false; 00162 } 00163 if (strncmp(p_ftp_buf, "226", 3) != 0) { 00164 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00165 return false; 00166 } 00167 return true; 00168 } 00169 00170 bool FTPClient::put(const char* file_name) { 00171 FILE* fp; 00172 int32_t remain_size; 00173 int32_t send_size; 00174 00175 if (!_login) { 00176 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00177 return false; 00178 } 00179 00180 if (!open_data_sock()) { 00181 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00182 return false; 00183 } 00184 00185 FTPClientDataSock.set_timeout(osWaitForever); 00186 sprintf(p_ftp_buf, "stor %s\r\n", file_name); 00187 FTPClientControlSock.send(p_ftp_buf, strlen(p_ftp_buf)); 00188 if (FTPClientControlSock.recv(p_ftp_buf, FTP_BUF_SIZE) <= 0) { 00189 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00190 return false; 00191 } 00192 if ((strncmp(p_ftp_buf, "150", 3) != 0) && (strncmp(p_ftp_buf, "125", 3) != 0)) { 00193 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00194 return false; 00195 } 00196 00197 sprintf(p_ftp_buf, "%s/%s", _root, file_name); 00198 fp = fopen(p_ftp_buf, "r"); 00199 fseek(fp, 0, SEEK_END); 00200 remain_size = ftell(fp); 00201 fseek(fp, 0, SEEK_SET); 00202 00203 while (remain_size > 0) { 00204 if (remain_size > FTP_BUF_SIZE) { 00205 send_size = FTP_BUF_SIZE; 00206 } else { 00207 send_size = remain_size; 00208 } 00209 fread(p_ftp_buf, 1, send_size, fp); 00210 FTPClientDataSock.send(p_ftp_buf, send_size); 00211 remain_size -= send_size; 00212 } 00213 fclose(fp); 00214 FTPClientDataSock.close(); 00215 00216 if (FTPClientControlSock.recv(p_ftp_buf, FTP_BUF_SIZE) <= 0) { 00217 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00218 return false; 00219 } 00220 if (strncmp(p_ftp_buf, "226", 3) != 0) { 00221 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00222 return false; 00223 } 00224 return true; 00225 } 00226 00227 bool FTPClient::del(const char* file_name) { 00228 if (!_login) { 00229 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00230 return false; 00231 } 00232 00233 sprintf(p_ftp_buf, "dele %s\r\n", file_name); 00234 FTPClientControlSock.send(p_ftp_buf, strlen(p_ftp_buf)); 00235 if (FTPClientControlSock.recv(p_ftp_buf, FTP_BUF_SIZE) <= 0) { 00236 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00237 return false; 00238 } 00239 if (strncmp(p_ftp_buf, "250", 3) != 0) { 00240 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00241 return false; 00242 } 00243 00244 return true; 00245 } 00246 00247 bool FTPClient::mkdir(const char* dir_name) { 00248 if (!_login) { 00249 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00250 return false; 00251 } 00252 00253 sprintf(p_ftp_buf, "xmkd %s\r\n", dir_name); 00254 FTPClientControlSock.send(p_ftp_buf, strlen(p_ftp_buf)); 00255 if (FTPClientControlSock.recv(p_ftp_buf, FTP_BUF_SIZE) <= 0) { 00256 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00257 return false; 00258 } 00259 if (strncmp(p_ftp_buf, "257", 3) != 0) { 00260 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00261 return false; 00262 } 00263 00264 return true; 00265 } 00266 00267 bool FTPClient::cd(const char* dir_name) { 00268 if (!_login) { 00269 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00270 return false; 00271 } 00272 00273 sprintf(p_ftp_buf, "cwd %s\r\n", dir_name); 00274 FTPClientControlSock.send(p_ftp_buf, strlen(p_ftp_buf)); 00275 if (FTPClientControlSock.recv(p_ftp_buf, FTP_BUF_SIZE) <= 0) { 00276 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00277 return false; 00278 } 00279 if (strncmp(p_ftp_buf, "250", 3) != 0) { 00280 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00281 return false; 00282 } 00283 00284 return true; 00285 } 00286 00287 bool FTPClient::dir(char* list_buf, int buf_size) { 00288 int size; 00289 int idx = 0; 00290 int remain_size = buf_size - 1; 00291 00292 if (list_buf == NULL) { 00293 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00294 return false; 00295 } 00296 list_buf[0] = '\0'; 00297 00298 if (!_login) { 00299 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00300 return false; 00301 } 00302 00303 if (!open_data_sock()) { 00304 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00305 return false; 00306 } 00307 00308 FTPClientDataSock.set_timeout(500); 00309 sprintf(p_ftp_buf, "list\r\n"); 00310 FTPClientControlSock.send(p_ftp_buf, strlen(p_ftp_buf)); 00311 if (FTPClientControlSock.recv(p_ftp_buf, FTP_BUF_SIZE) <= 0) { 00312 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00313 return false; 00314 } 00315 if ((strncmp(p_ftp_buf, "150", 3) != 0) && (strncmp(p_ftp_buf, "125", 3) != 0)) { 00316 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00317 return false; 00318 } 00319 00320 while (remain_size > 0) { 00321 size = FTPClientDataSock.recv(p_ftp_buf, FTP_BUF_SIZE); 00322 if (size > 0) { 00323 if (size > remain_size) { 00324 size = remain_size; 00325 } 00326 memcpy(&list_buf[idx], p_ftp_buf, size); 00327 idx += size; 00328 remain_size -= size; 00329 } else { 00330 break; 00331 } 00332 } 00333 list_buf[idx] = '\0'; 00334 FTPClientDataSock.close(); 00335 00336 if (FTPClientControlSock.recv(p_ftp_buf, FTP_BUF_SIZE) <= 0) { 00337 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00338 return false; 00339 } 00340 if (strncmp(p_ftp_buf, "226", 3) != 0) { 00341 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00342 return false; 00343 } 00344 return true; 00345 } 00346 00347 bool FTPClient::ls(char* list_buf, int buf_size) { 00348 int size; 00349 int idx = 0; 00350 int remain_size = buf_size - 1; 00351 00352 if (list_buf == NULL) { 00353 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00354 return false; 00355 } 00356 list_buf[0] = '\0'; 00357 00358 if (!_login) { 00359 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00360 return false; 00361 } 00362 00363 if (!open_data_sock()) { 00364 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00365 return false; 00366 } 00367 00368 FTPClientDataSock.set_timeout(500); 00369 sprintf(p_ftp_buf, "nlst\r\n"); 00370 FTPClientControlSock.send(p_ftp_buf, strlen(p_ftp_buf)); 00371 if (FTPClientControlSock.recv(p_ftp_buf, FTP_BUF_SIZE) <= 0) { 00372 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00373 return false; 00374 } 00375 if ((strncmp(p_ftp_buf, "150", 3) != 0) && (strncmp(p_ftp_buf, "125", 3) != 0)) { 00376 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00377 return false; 00378 } 00379 00380 while (remain_size > 0) { 00381 size = FTPClientDataSock.recv(p_ftp_buf, FTP_BUF_SIZE); 00382 if (size > 0) { 00383 if (size > remain_size) { 00384 size = remain_size; 00385 } 00386 memcpy(&list_buf[idx], p_ftp_buf, size); 00387 idx += size; 00388 remain_size -= size; 00389 } else { 00390 break; 00391 } 00392 } 00393 list_buf[idx] = '\0'; 00394 FTPClientDataSock.close(); 00395 00396 if (FTPClientControlSock.recv(p_ftp_buf, FTP_BUF_SIZE) <= 0) { 00397 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00398 return false; 00399 } 00400 if (strncmp(p_ftp_buf, "226", 3) != 0) { 00401 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00402 return false; 00403 } 00404 return true; 00405 } 00406 00407 bool FTPClient::open_data_sock() { 00408 uint8_t ip_addr[4]; 00409 int i; 00410 int remote_port = 0; 00411 char* token = NULL; 00412 char* savept = NULL; 00413 00414 sprintf(p_ftp_buf, "pasv\r\n"); 00415 FTPClientControlSock.send(p_ftp_buf, strlen(p_ftp_buf)); 00416 if (FTPClientControlSock.recv(p_ftp_buf, FTP_BUF_SIZE) <= 0) { 00417 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00418 return false; 00419 } 00420 if (strncmp(p_ftp_buf, "227", 3) != 0) { 00421 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00422 return false; 00423 } 00424 00425 token = strchr(p_ftp_buf, '(') + 1; 00426 for (i = 0; i < 4; i++) { 00427 token = strtok_r(token, ",", &savept); 00428 ip_addr[i] = (uint8_t)atoi(token); 00429 token = savept; 00430 if (token == NULL) { 00431 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00432 return false; 00433 } 00434 } 00435 00436 for (i = 0; i < 2; i++) { 00437 token = strtok_r(token, ",)", &savept); 00438 remote_port <<= 8; 00439 remote_port += atoi(token); 00440 token = savept; 00441 if (token == NULL) { 00442 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00443 return false; 00444 } 00445 } 00446 sprintf(ftp_data_ip_addr, "%d.%d.%d.%d", ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]); 00447 00448 FTPClientDataSock.open(p_network); 00449 for (i = 0; i < 20; i++) { 00450 if (FTPClientDataSock.connect(ftp_data_ip_addr, remote_port) >= 0) { 00451 return true; 00452 } 00453 wait(1); 00454 } 00455 ftp_debug_print("ERROR: %s(%d)\r\n", __FILE__, __LINE__); 00456 return false; 00457 } 00458
Generated on Thu Jul 14 2022 08:33:19 by
1.7.2