@@ -293,7 +293,8 @@ static int build_fullpath(const struct FtpSession* session, struct Pathname* out
293293 }
294294
295295 // return an error if the output was truncated or it failed.
296- if (rc < 0 || rc > sizeof (* out )) {
296+ if (rc < 0 || rc >= sizeof (* out )) {
297+ errno = ENAMETOOLONG ;
297298 rc = -1 ;
298299 } else {
299300 rc = 0 ;
@@ -323,7 +324,6 @@ static inline struct Pathname fix_path_for_device(const struct Pathname* path) {
323324static int ftp_build_list_entry (struct FtpSession * session , const time_t cur_time , const struct Pathname * fullpath , const char * name , const struct stat * st , int nlist ) {
324325 int rc ;
325326 struct FtpTransfer * transfer = & session -> transfer ;
326- // char buf[1024 * 4] = {0};
327327
328328 if (nlist ) {
329329 rc = snprintf (transfer -> list_buf , sizeof (transfer -> list_buf ), "%s" TELNET_EOL , name );
@@ -393,6 +393,7 @@ static int ftp_build_list_entry(struct FtpSession* session, const time_t cur_tim
393393
394394 if (rc <= 0 || rc > sizeof (transfer -> list_buf )) {
395395 // don't send anything on error or truncated
396+ errno = ENAMETOOLONG ;
396397 rc = -1 ;
397398 } else {
398399 transfer -> size = rc ;
@@ -490,6 +491,7 @@ static void ftp_dir_data_transfer_progress(struct FtpSession* session) {
490491 const time_t cur_time = time (NULL );
491492 const bool nlist = session -> transfer .mode == FTP_TRANSFER_MODE_NLST ;
492493 const bool device_list = g_ftp .cfg .devices && g_ftp .cfg .devices_count && !strcmp ("/" , session -> temp_path .s );
494+ const bool is_root = !strcmp ("/" , session -> temp_path .s );
493495 struct FtpTransfer * transfer = & session -> transfer ;
494496
495497 // send as much data as possible.
@@ -543,8 +545,14 @@ static void ftp_dir_data_transfer_progress(struct FtpSession* session) {
543545 continue ;
544546 }
545547
546- static struct Pathname filepath ;
547- int rc = snprintf (filepath .s , sizeof (filepath ), "%s/%s" , session -> temp_path .s , name );
548+ int rc ;
549+ struct Pathname filepath ;
550+ if (is_root ) {
551+ rc = snprintf (filepath .s , sizeof (filepath ), "%s%s" , session -> temp_path .s , name );
552+ } else {
553+ rc = snprintf (filepath .s , sizeof (filepath ), "%s/%s" , session -> temp_path .s , name );
554+ }
555+
548556 if (rc <= 0 || rc > sizeof (filepath )) {
549557 continue ;
550558 }
@@ -1115,7 +1123,7 @@ static void ftp_list_directory(struct FtpSession* session, const char* data, int
11151123 struct stat st = {0 };
11161124 rc = ftp_vfs_lstat (session -> temp_path .s , & st );
11171125 if (rc < 0 ) {
1118- ftp_client_msg (session , "450 Requested file action not taken. %s %s " , strerror (errno ), session -> temp_path . s );
1126+ ftp_client_msg (session , "450 Requested file action not taken. %s" , strerror (errno ));
11191127 } else {
11201128 if (S_ISDIR (st .st_mode )) {
11211129 rc = ftp_vfs_opendir (& session -> transfer .dir_vfs , session -> temp_path .s );
@@ -1124,7 +1132,7 @@ static void ftp_list_directory(struct FtpSession* session, const char* data, int
11241132 } else {
11251133 rc = ftp_data_open (session );
11261134 if (rc < 0 ) {
1127- ftp_client_msg (session , "425 Can't open data connection. %s rc: %d " , strerror (errno ), errno );
1135+ ftp_client_msg (session , "425 Can't open data connection. %s" , strerror (errno ));
11281136 } else {
11291137 session -> transfer .mode = mode ;
11301138 return ;
@@ -1180,7 +1188,7 @@ static void ftp_cmd_STAT(struct FtpSession* session, const char* data) {
11801188
11811189// HELP <CRLF> | 211, 214, 500, 501, 502, 421
11821190static void ftp_cmd_HELP (struct FtpSession * session , const char * data ) {
1183- ftp_client_msg (session , "214 ftpsrv 0.1.1 By TotalJustice." );
1191+ ftp_client_msg (session , "214 ftpsrv 0.1.2 By TotalJustice." );
11841192}
11851193
11861194// NOOP <CRLF> | 200, 500, 421
0 commit comments