From cb00633229f2535509777ebd404de79162b08392 Mon Sep 17 00:00:00 2001 From: Christophe Grenier Date: Wed, 26 Oct 2016 08:05:40 +0200 Subject: [PATCH] add "filecopy" parameters to copy all the files from a partition --- src/dir.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/dir.h | 1 + src/dirpart.c | 9 ++++++++ 3 files changed, 71 insertions(+) diff --git a/src/dir.c b/src/dir.c index 70dfd241..ee9c16d4 100644 --- a/src/dir.c +++ b/src/dir.c @@ -325,6 +325,67 @@ int dir_whole_partition_log(disk_t *disk, const partition_t *partition, dir_data return dir_whole_partition_log_aux(disk, partition, dir_data, inode); } +static int dir_whole_partition_copy_aux(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const unsigned long int inode, unsigned int *copy_ok, unsigned int *copy_bad) +{ + struct td_list_head *file_walker = NULL; + static unsigned int dir_nbr=0; + static unsigned long int inode_known[MAX_DIR_NBR]; + const unsigned int current_directory_namelength=strlen(dir_data->current_directory); + file_info_t dir_list; + TD_INIT_LIST_HEAD(&dir_list.list); + if(dir_nbr==MAX_DIR_NBR) + return 1; /* subdirectories depth is too high => Back */ + dir_data->get_dir(disk, partition, dir_data, inode, &dir_list); + /* Not perfect for FAT32 root cluster */ + inode_known[dir_nbr++]=inode; + td_list_for_each(file_walker, &dir_list.list) + { + const file_info_t *current_file=td_list_entry_const(file_walker, const file_info_t, list); + if(strlen(dir_data->current_directory) + 1 + strlen(current_file->name) < + sizeof(dir_data->current_directory)-1) + { + if(strcmp(dir_data->current_directory,"/")) + strcat(dir_data->current_directory,"/"); + strcat(dir_data->current_directory,current_file->name); + if(LINUX_S_ISDIR(current_file->st_mode)!=0) + { + if(is_inode_valid(current_file, dir_nbr, inode_known)>0) + { + dir_whole_partition_copy_aux(disk, partition, dir_data, current_file->st_ino, copy_ok, copy_bad); + } + } + else if(LINUX_S_ISREG(current_file->st_mode)!=0) + { + if(dir_data->copy_file(disk, partition, dir_data, current_file) == 0) + (*copy_ok)++; + else + (*copy_bad)++; + } + } + /* restore current_directory name */ + dir_data->current_directory[current_directory_namelength]='\0'; + } + delete_list_file(&dir_list); + dir_nbr--; + return 0; +} + +void dir_whole_partition_copy(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const unsigned long int inode) +{ + unsigned int copy_ok=0; + unsigned int copy_bad=0; + char *dst_directory=(char *)MALLOC(4096); + dst_directory[0]='.'; + dst_directory[1]='\0'; +#ifdef HAVE_GETCWD + if(getcwd(dst_directory, 4096)==NULL) + return ; +#endif + dir_data->local_dir=dst_directory; + dir_whole_partition_copy_aux(disk, partition, dir_data, inode, ©_ok, ©_bad); + log_info("Copy done! %u ok, %u failed", copy_ok, copy_bad); +} + int filesort(const struct td_list_head *a, const struct td_list_head *b) { const file_info_t *file_a=td_list_entry_const(a, const file_info_t, list); diff --git a/src/dir.h b/src/dir.h index 65835361..3f857198 100644 --- a/src/dir.h +++ b/src/dir.h @@ -78,6 +78,7 @@ int dir_aff_log(const dir_data_t *dir_data, const file_info_t*dir_list); int log_list_file(const disk_t *disk_car, const partition_t *partition, const dir_data_t *dir_data, const file_info_t*list); unsigned int delete_list_file(file_info_t *list); int dir_whole_partition_log(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int inode); +void dir_whole_partition_copy(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int inode); void mode_string (const unsigned int mode, char *str); int set_mode(const char *pathname, unsigned int mode); FILE *fopen_local(char **localfilename, const char *localroot, const char *filename); diff --git a/src/dirpart.c b/src/dirpart.c index 3f07ad2b..9d8a98a8 100644 --- a/src/dirpart.c +++ b/src/dirpart.c @@ -166,6 +166,7 @@ dir_partition_t dir_partition(disk_t *disk, const partition_t *partition, const case DIR_PART_OK: { int recursive=0; + int copy_files=0; if(*current_cmd!=NULL) { int do_continue; @@ -186,6 +187,12 @@ dir_partition_t dir_partition(disk_t *disk, const partition_t *partition, const dir_data.param|=FLAG_LIST_PATHNAME; do_continue=1; } + else if(strncmp(*current_cmd, "filecopy", 8)==0) + { + (*current_cmd)+=8; + copy_files=1; + do_continue=1; + } } while(do_continue==1); } if(recursive>0) @@ -204,6 +211,8 @@ dir_partition_t dir_partition(disk_t *disk, const partition_t *partition, const } #endif } + if(copy_files>0) + dir_whole_partition_copy(disk,partition,&dir_data,dir_data.current_inode); dir_data.close(&dir_data); } break;