ftp server: longfilename in subdirectory

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

ftp server: longfilename in subdirectory

426 Views
emanueletrapani
Contributor III

hi, i'm working on a frdmk64f, with CW10.6 and MQX4.1.

i start the ftp server but i cannot see the longfilename of the files inside the subdirectory i have on my sdcard.

in my app i initialize the sd card, the ethernet device and the ftp server. everything works fine. on my pc i start filezilla ftp client. filezilla can read every file and every directory present in my sd card. it read the longfilename of the files in the root directory correctly. but if i want the longfilename of the file in a subdirectory i cannot. in debug mode i see that the IO_IOCTL_GET_LFN inside io_mfs_dir_read give the error FILE_NOT_FOUND.

i try to use in the main of my app this IO_IOCTL_GET_LFN function and it works fine on my root directory. if i try to use it with the full pathname of the file in the subdirectory. it give me always the error FILE_NOT_FOUND.

the code of ftp server initialization

FTPSRV_PARAM_STRUCT  params = {0};

  uint32_t             ftpsrv_handle;

  #if RTCSCFG_ENABLE_IP4

  params.af |= AF_INET;

  #endif

  #if RTCSCFG_ENABLE_IP6

  params.af |= AF_INET6;

  #endif

  params.auth_table = (FTPSRV_AUTH_STRUCT*) ftpsrv_users;

  params.root_dir = "a:";

  ftpsrv_handle = FTPSRV_init(&params);

  if (ftpsrv_handle != 0)

  {

  printf("FTP Server Started. Root directory is set to \"%s\", login: \"%s\", password: \"%s\".\n",

  params.root_dir,

  ftpsrv_users[0].uid,

  ftpsrv_users[0].pass);

  }

  else

  {

  printf("Failed to start FTP server.\n");

  }

the code of IO_IOCTL_GET_LFN function

uint32_t err_code;

  MFS_GET_LFN_STRUCT test_struct;

  char nome_file_long[32 + 1];

  char percorso1[] = "\\abcdef~1.txt";

  printf("\n\rpercorso1: %s\n", percorso1);

   

  test_struct.PATHNAME = percorso1;

  test_struct.LONG_FILENAME = nome_file_long;

  err_code = ioctl(filesystem_handle, IO_IOCTL_GET_LFN, (uint32_t *) &test_struct);

  if (!err_code) {

  printf("\n\rnome file long1: %s", nome_file_long);

  } else {

  printf("\n\rerrore1: %x\n", err_code);

  }

char percorso8[] = "\\CONFIG";

  err_code = ioctl(filesystem_handle, IO_IOCTL_CHANGE_CURRENT_DIR, (uint32_t *) percorso8);

  printf("\n\rerrore3: %x\n", err_code);

char percorso2[] = "\\CONFIG\abcdef~2.txt";

  test_struct.PATHNAME = percorso2;

  //test_struct.LONG_FILENAME = nome_file_long;

  err_code = ioctl(filesystem_handle, IO_IOCTL_GET_LFN, (uint32_t *) &test_struct);

  if (!err_code) {

  printf("\n\rnome file long11: %s", nome_file_long);

  } else {

  printf("\n\rerrore11: %x\n", err_code);

  }

i use this function in the root directory and in the subdir CONFIG and it works fine. it give me the list of all the file in the directory

MFS_SEARCH_DATA cerca_data;

  MFS_SEARCH_PARAM cerca;

  DIR_STRUCT_ dir_prova;

  char percorso0[] = "*.*";

cerca.ATTRIBUTE = MFS_SEARCH_ANY;

  cerca.WILDCARD = percorso0;

  cerca.SEARCH_DATA_PTR = &cerca_data;

  err_code = ioctl(filesystem_handle, IO_IOCTL_FIND_FIRST_FILE, (uint32_t *) &cerca);

  while (err_code == MFS_NO_ERROR) {

  printf ("\n\r%-12.12s %6lu %02lu-%02lu-%04lu %02lu:%02lu:%02lu", cerca_data.NAME, cerca_data.FILE_SIZE,

  (uint32_t)(cerca_data.DATE & MFS_MASK_MONTH) >>

  MFS_SHIFT_MONTH,

  (uint32_t)(cerca_data.DATE & MFS_MASK_DAY) >>

  MFS_SHIFT_DAY,

  (uint32_t)((cerca_data.DATE & MFS_MASK_YEAR) >>

  MFS_SHIFT_YEAR) + 1980,

  (uint32_t)(cerca_data.TIME & MFS_MASK_HOURS) >>

  MFS_SHIFT_HOURS,

  (uint32_t)(cerca_data.TIME & MFS_MASK_MINUTES) >>

  MFS_SHIFT_MINUTES,

  (uint32_t)(cerca_data.TIME & MFS_MASK_SECONDS) << 1);

  err_code = ioctl(filesystem_handle, IO_IOCTL_FIND_NEXT_FILE, (uint32_t *) &cerca_data);

  }

how can i get the longfilename of the file in my subdurectories?

thank you

PS: i found that i can have the long_filename in filezilla if i change the current dir before to start the infinite loop

char percorso8[] = "\\CONFIG";

  err_code = ioctl(filesystem_handle, IO_IOCTL_CHANGE_CURRENT_DIR, (uint32_t *) percorso8);

  printf("\n\rerrore3: %x\n", err_code);

while (1) {

     _time_delay(500);

}

now i can see, in filezilla, only the long_filename of the file present in CONFIG folder, and now i cannot se the long_filename of the file in root folder.

but how can i get the long_filename of all the file in all the subdirectory i have?

maybe changing the current dir every times i call a io_mfs_dir_read, but ho can i pass the full path in this function?

0 Kudos
1 Reply

225 Views
RadekS
NXP Employee
NXP Employee

Hi Emanuele,

In MQX 4.1 IO_IOCTL_FIND_FIRST_FILE/ IO_IOCTL_FIND_NEXT_FILE searches in one directory.

If you want search in several directories, you have to run this loop so many times as you have (sub)directories. MFS_SEARCH_PARAM cannot be changed during searching loop.

For IO_IOCTL_GET_LFN you can use also relative path (without slash at begin of path), however unfortunately MQX 4.1 contains bug and it is possible that you will get wrong results (if you have more than one different long name for the same short name). So, I would like to recommend use full absolute path for IO_IOCTL_GET_LFN ioctl command in MQX 4.1.

From my point of view, best solution will be (partial) upgrade to MQX 4.2. This version of MQX contains reworked MFS which solves several MFS bugs and it improves speed of searching files. Additionally ioctl commands IO_IOCTL_FIND_FIRST_FILE/ IO_IOCTL_FIND_NEXT_FILE in this version of MFS returns directly long names of searched files.

I hope it helps you.

Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------