//! This function closes the play list and selects this one in current navigator //! //! @return false in case of error, see global value "fs_g_status" for more detail //! @return true otherwise //! bool pl_main_close( void ) { _MEM_TYPE_SLOW_ Fs_index index; uint8_t nav_id_save; if( !pl_main_isopen() ) return false; // Close play list nav_id_save = nav_get(); nav_select( FS_NAV_ID_PLAYLIST ); file_close(); #if( PL_READONLY == false ) if( pl_g_list_is_modify ) { if( pl_g_list_undo ) { uint16_t size_name; FS_STRING sz_name; //** Play list modified but not saved, then restore previous list // Get name of play list nav_string_length_enable(); nav_file_name( (FS_STRING)&size_name, 1, FS_NAME_GET, false ); nav_string_length_disable(); sz_name = PLAYLIST_BUF_ALLOC( size_name* (Is_unicode? 2 : 1 ) ); if( NULL != sz_name ) { if( nav_file_name( sz_name, size_name, FS_NAME_GET, false ) ) { // Delete current play list if( nav_file_del( true ) ) // Remove copy file { nav_gotoindex( ©file_index ); // Select copy play list nav_file_rename( sz_name ); // rename copy play list } } PLAYLIST_BUF_FREE( sz_name ); } } } #endif // Select the play list file in current navigator index = nav_getindex(); // Save a pointer on play list file nav_select( nav_id_save ); nav_gotoindex( &index ); pl_g_list_is_open = false; return true; }
//! This function searches a file name in file list FLAT //! //! @param sz_name name to search (UNICODE or ASCII) <br> //! It must be terminated by NULL or '*' value //! @param b_match_case false to ignore the case //! //! @return false in case of error, see global value "fs_g_status" for more detail //! @return true otherwise //! //! @verbatim //! This function starts a search at the next position of the current in file list //! @endverbatim //! bool nav_flat_findname( const FS_STRING sz_name , bool b_match_case ) { while( 1 ) { if ( !nav_flat_next() ) return false; if ( nav_file_name( sz_name , 0 , FS_NAME_CHECK , b_match_case )) return true; } }
//! This function searchs a file name in file list FLAT //! //! @param sz_name name to search (UNICODE or ASCII) <br> //! It must be terminated by NULL or '*' value //! @param b_match_case FALSE to ignore the case //! //! @return FALSE in case of error, see global value "fs_g_status" for more detail //! @return TRUE otherwise //! //! @verbatim //! This function starts a search at the next position of the current in file list //! @endverbatim //! Bool nav_flat_findname( const FS_STRING sz_name , Bool b_match_case ) { while( 1 ) { if ( !nav_flat_next() ) return FALSE; if ( nav_file_name( sz_name , 0 , FS_NAME_CHECK , b_match_case )) return TRUE; } }
//! @brief This function manages the ls command //! //! @param b_more enable the '|more' management when true otherwise no '|more' management //! void ushell_cmd_ls( bool b_more ) { uint8_t str_char[MAX_FILE_PATH_LENGTH]; uint16_t u16_i,u16_nb_file,u16_nb_dir,last_i; uint8_t ext_filter=false; //** Print drive name printf("%c: volume is %s\r\n", 'a'+nav_drive_get(), mem_name(nav_drive_get()) ); printf("Drive uses "); switch (nav_partition_type()) { case FS_TYPE_FAT_12: printf("FAT12\n\r"); break; case FS_TYPE_FAT_16: printf("FAT16\n\r"); break; case FS_TYPE_FAT_32: printf("FAT32\n\r"); break; default: printf("an unknown partition type\r\n"); return; } //** Print directory name if( !nav_dir_name( (FS_STRING)str_char, MAX_FILE_PATH_LENGTH ) ) return; printf("Dir name is %s\n\r",str_char); //** Check extension filter in extra parameters if(g_s_arg[0][0]!=0) { if(g_s_arg[0][0] == '*' && g_s_arg[0][1]=='.') { ext_filter=true; for(u16_i=2; u16_i<USHELL_SIZE_CMD_LINE; u16_i++) { g_s_arg[0][u16_i-2]=g_s_arg[0][u16_i]; } } } //** Print files list printf(" Size Name\n\r"); // Init loop at the beginning of directory nav_filelist_reset(); u16_nb_file=0; u16_nb_dir=0; last_i=0; // For each file in list while( nav_filelist_set(0,FS_FIND_NEXT) ) { if(!ext_filter) { // No extension filter if( nav_file_isdir() ) { printf("Dir "); u16_nb_dir++; // count the number of directory }else{ printf(" "); } } else { // If extension filter then ignore directories if(nav_file_isdir()) continue; // Check extension if(!nav_file_checkext((FS_STRING)g_s_arg[0])) continue; } u16_nb_file++; // count the total of files (directories and files) // Check 'more' step if( b_more && ((u16_nb_file%USHELL_NB_LINE)==0) && (u16_nb_file!=0) && (last_i != u16_nb_file) ) { last_i=u16_nb_file; if( !ushell_more_wait() ) return; // Exit LS command } // Display file nav_file_name((FS_STRING)str_char, MAX_FILE_PATH_LENGTH, FS_NAME_GET, true); printf("%10lu %s\n\r", nav_file_lgt(), str_char); } // Display total number printf(" %4i Files\r\n", u16_nb_file-u16_nb_dir ); printf(" %4i Dir\r\n", u16_nb_dir ); }
//! @brief Synchronize a path with an other path //! //! @return true if success //! bool ushell_cmd_sync( void ) { Fs_index sav_index; uint8_t u8_folder_level = 0; if( g_s_arg[0][0] == 0 ) return false; if( g_s_arg[1][0] == 0 ) return false; // Add '\' at the end of path, else the nav_setcwd select the directory but don't enter into. ushell_path_valid_syntac( g_s_arg[0] ); ushell_path_valid_syntac( g_s_arg[1] ); printf("Synchronize folders:\n\r"); sav_index = nav_getindex(); // Save the position // Select source directory in COPYFILE navigator handle nav_select( FS_NAV_ID_COPYFILE ); printf("Select source directory\n\r"); if( !nav_setcwd( (FS_STRING)g_s_arg[0], true, false ) ) goto ushell_cmd_sync_error; nav_filelist_reset(); // Select destination directory in USHELL navigator handle nav_select( FS_NAV_ID_USHELL_CMD ); printf("Select destination directory\n\r"); if( !nav_setcwd( (FS_STRING)g_s_arg[1], true, true ) ) goto ushell_cmd_sync_error; nav_filelist_reset(); // loop to scan and create ALL folders and files while(1) { while(1) { // Loop to Search files or directories // Reselect Source nav_select( FS_NAV_ID_COPYFILE ); if( nav_filelist_set( 0 , FS_FIND_NEXT ) ) break; // a next file and directory is found // No other dir or file in current dir then go to parent dir on Source and Destination disk if( 0 == u8_folder_level ) { // end of update folder //********* END OF COPY ************** goto ushell_cmd_sync_finish; } printf("Go to parent\n\r"); // Remark, nav_dir_gotoparent() routine go to in parent dir and select the children dir in list u8_folder_level--; if( !nav_dir_gotoparent() ) goto ushell_cmd_sync_error; // Select Destination navigator and go to the same dir of Source nav_select( FS_NAV_ID_USHELL_CMD ); if( !nav_dir_gotoparent() ) goto ushell_cmd_sync_error; } // end of while (1) if( nav_file_isdir()) { printf("Dir found - create dir: "); //** here, a new directory is found and is selected // Get name of current selection (= dir name on Source) if( !nav_file_name( (FS_STRING)g_s_arg[0], USHELL_SIZE_CMD_LINE, FS_NAME_GET, false )) goto ushell_cmd_sync_error; // Enter in dir (on Source) if( !nav_dir_cd()) goto ushell_cmd_sync_error; u8_folder_level++; // Select Destination disk nav_select( FS_NAV_ID_USHELL_CMD ); // Create folder in Destination disk printf((char*)g_s_arg[0]); printf("\n\r"); if( !nav_dir_make( (FS_STRING )g_s_arg[0] )) { if( FS_ERR_FILE_EXIST != fs_g_status ) goto ushell_cmd_sync_error; // here, error the name exist } // Here the navigator have selected the folder on Destination if( !nav_dir_cd()) { if( FS_ERR_NO_DIR == fs_g_status ) { // FYC -> Copy impossible, because a file have the same name of folder } goto ushell_cmd_sync_error; } // here, the folder is created and the navigator is entered in this dir } else { printf("File found - copy file: "); //** here, a new file is found and is selected // Get name of current selection (= file name on Source) if( !nav_file_name( (FS_STRING)g_s_arg[0], USHELL_SIZE_CMD_LINE, FS_NAME_GET, false )) goto ushell_cmd_sync_error; printf((char*)g_s_arg[0]); printf("\n\r"); if( !nav_file_copy()) goto ushell_cmd_sync_error; // Paste file in current dir of Destination disk nav_select( FS_NAV_ID_USHELL_CMD ); while( !nav_file_paste_start( (FS_STRING)g_s_arg[0] ) ) { // Error if( fs_g_status != FS_ERR_FILE_EXIST ) goto ushell_cmd_sync_error; // File exists then deletes this one printf("File exists then deletes this one.\n\r"); if( !nav_file_del( true ) ) goto ushell_cmd_sync_error; // here, retry PASTE } // Copy running { uint8_t status; do{ status = nav_file_paste_state(false); }while( COPY_BUSY == status ); if( COPY_FINISH != status ) goto ushell_cmd_sync_error; } } // if dir OR file } // end of first while(1) ushell_cmd_sync_error: // Restore the position nav_select( FS_NAV_ID_USHELL_CMD ); nav_gotoindex(&sav_index); printf("!!!Copy fail\n\r"); return false; ushell_cmd_sync_finish: // Restore the position nav_select( FS_NAV_ID_USHELL_CMD ); nav_gotoindex(&sav_index); printf("End of copy\n\r"); return true; }
//! @brief This function copies a file to other location //! void ushell_cmd_copy( void ) { Fs_index sav_index; uint8_t u8_status_copy; if( g_s_arg[0][0] == 0 ) return; // Save the position sav_index = nav_getindex(); // Select source file if( !nav_setcwd( (FS_STRING)g_s_arg[0], true, false ) ) { fputs(MSG_ER_UNKNOWN_FILE, stdout); return; } // Get name of source to be used as same destination name nav_file_name( (FS_STRING)g_s_arg[0], MAX_FILE_PATH_LENGTH, FS_NAME_GET, true ); // Mark this selected file like source file if( !nav_file_copy()) { fputs(MSG_KO, stdout); goto cp_end; } // Select destination if( g_s_arg[1][0]==0 ) { // g_s_arg[1] is NULL, using mark if( !nav_gotoindex(&g_mark_index) ) goto cp_end; } else { // g_s_arg[1] exists, then go to this destination if( !nav_setcwd( (FS_STRING)g_s_arg[1], true, false ) ) { fputs(MSG_ER_UNKNOWN_FILE, stdout); goto cp_end; } } // Set the name destination and start paste if( !nav_file_paste_start((FS_STRING)g_s_arg[0]) ) { fputs(MSG_ER_PASTE, stdout); goto cp_end; } // Performs copy do { u8_status_copy = nav_file_paste_state( false ); }while( u8_status_copy == COPY_BUSY ); // Check status of copy action if( u8_status_copy == COPY_FAIL ) { fputs(MSG_ER_PASTE, stdout); goto cp_end; } cp_end: // Restore the position nav_gotoindex(&sav_index); }
//! //! @brief Synchronize the contents of two directories (limited to files). //! //! @param dst_fs_idx Fs_index *: File system index for destination navigation path //! @param dst_dir const char *: Pointer to destination directory name //! @param src_fs_idx Fs_index *: File system index for source navigation path //! @param src_dir const char *: Pointer to source directory name //! //! @return bool: true on success //! //! @todo Do recursive directory copy... //! bool host_mass_storage_task_sync_dir(Fs_index *dst_fs_idx, const char *dst_dir, Fs_index *src_fs_idx, const char *src_dir) { uint8_t nb_file; uint8_t i; uint32_t free_space; uint16_t file_size; // First, check the host controller is in full operating mode with the // B-device attached and enumerated if (!Is_host_ready()) return false; // Go to source navigation nav_gotoindex(src_fs_idx); if (!goto_code_name(src_dir)) return false; // Check that source directory exists nav_dir_cd(); // Source directory exists, so go to it *src_fs_idx = nav_getindex(); // Save navigation position nav_filelist_first(FS_FILE); // Go to first file nb_file = nav_filelist_nb(FS_FILE); // Get the number of files in this directory // Go to destination navigation nav_gotoindex(dst_fs_idx); if (!goto_code_name(dst_dir)) // Destination directory does not exist, so create it { str_code_to_unicode_ram(dst_dir, ms_str_unicode); nav_dir_make(ms_str_unicode); if (!goto_code_name(dst_dir)) return false; // Check that destination directory has been created } nav_dir_cd(); *dst_fs_idx = nav_getindex(); // Get available free space free_space = nav_partition_space(); nav_gotoindex(src_fs_idx); nav_filelist_first(FS_FILE); // For all files in directory for (i = 0; i < nb_file; i++) { // Get source name to be used as destination name nav_file_name(ms_str_unicode, MAX_FILE_PATH_LENGTH, FS_NAME_GET); file_size = nav_file_lgtsector(); // Get file size if (file_size > free_space) return false; // Check that there is enough free space left // Update free space (to save time, do no call nav_partition_space() again) free_space -= file_size; // Mark source nav_file_copy(); // Save current source position *src_fs_idx = nav_getindex(); // Go to destination navigation nav_gotoindex(dst_fs_idx); if (goto_unicode_name(ms_str_unicode)) // If file already exists { nav_file_del(); // Delete it } // Paste nav_file_paste_start(ms_str_unicode); // Restore previous navigation position nav_gotoindex(src_fs_idx); // Copy while (nav_file_paste_state(false) == COPY_BUSY); // Restore previous navigation position nav_gotoindex(src_fs_idx); nav_filelist_set(0, FS_FIND_NEXT); } return true; }