//! @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; }
//! This function creates a copy of the play list in case of a restore action //! //! @return false in case of error, see global value "fs_g_status" for more detail //! @return true otherwise //! bool pl_main_modify( void ) { _MEM_TYPE_SLOW_ uint8_t name_copyfile[]="~copy.m3u"; _MEM_TYPE_SLOW_ Fs_index index; uint8_t nav_id_save; uint16_t u16_pos; uint8_t status; bool b_copy_finish = false; if( !pl_main_isopen() ) return false; if( pl_g_list_is_modify ) return true; // If an error occurs during copy process then the play list file is set in read only mode fs_g_status = FS_ERR_PL_READ_ONLY; if( pl_g_list_is_readonly ) return false; if( !pl_g_list_undo ) { pl_g_list_is_modify = true; return true; } // Save information about current play list file nav_id_save = nav_get(); nav_select( FS_NAV_ID_PLAYLIST ); u16_pos = pl_g_u16_list_sel; // Save position in play list file_close(); // Close list pl_g_list_is_open = false; index = nav_getindex(); // Get pointer on play list // Copy play list file in a temporary file #if( (FS_ASCII == true) && (FS_UNICODE == true) ) nav_string_ascii(); // copy file name stored in ASCII #endif if( !nav_file_copy()) goto pl_main_modify_end; if( !nav_file_paste_start( name_copyfile ) ) { if( FS_ERR_FILE_EXIST != fs_g_status) goto pl_main_modify_end; // File exist then delete if( !nav_file_del(true) ) goto pl_main_modify_end; // Retry paste if( !nav_file_paste_start( name_copyfile ) ) goto pl_main_modify_end; } // Run paste do{ status = nav_file_paste_state(false); // Copy running }while( COPY_BUSY == status ); if( COPY_FINISH != status ) goto pl_main_modify_end; // Save pointer on copy file copyfile_index = nav_getindex(); b_copy_finish = true; pl_main_modify_end: // Restore the play list file #if( (FS_ASCII == true) && (FS_UNICODE == true) ) nav_string_unicode(); #endif nav_gotoindex( &index ); // Go to original play list file pl_main_open( true ); // Re open play list file pl_g_list_is_modify = b_copy_finish; nav_select( nav_id_save ); pl_nav_setpos(u16_pos); // Restore position in play list return pl_g_list_is_modify; }
//! @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; }