From c32dfa4e43b312ba9089478918da3b0de6631435 Mon Sep 17 00:00:00 2001 From: Christophe Grenier Date: Mon, 22 Nov 2010 08:26:28 +0100 Subject: [PATCH] Reduce memory usage during NTFS undelete --- src/askloc.c | 20 +++++++++----------- src/dir.c | 9 +++++---- src/dir.h | 2 +- src/ntfs_udl.c | 44 +++++++++++++++++++------------------------- 4 files changed, 34 insertions(+), 41 deletions(-) diff --git a/src/askloc.c b/src/askloc.c index 42501aff..55f380fd 100644 --- a/src/askloc.c +++ b/src/askloc.c @@ -94,10 +94,8 @@ void get_dos_drive_list(struct td_list_head *list) { file_info_t *new_drive; new_drive=(file_info_t*)MALLOC(sizeof(*new_drive)); - new_drive->name[0]=i; - new_drive->name[1]=':'; - new_drive->name[2]=PATH_SEP; - new_drive->name[3]='\0'; + new_drive->name=(char*)MALLOC(4); + sprintf(new_drive->name, "%c:/", i); new_drive->stat.st_mode=LINUX_S_IFDIR|LINUX_S_IRWXUGO; td_list_add_tail(&new_drive->list, list); } @@ -161,7 +159,7 @@ char *ask_location(const char*msg, const char *src_dir, const char *dst_org) DIR* dir; static file_info_t dir_list = { .list = TD_LIST_HEAD_INIT(dir_list.list), - .name = {0} + .name = NULL }; wmove(window,5,0); wclrtoeol(window); /* before addstr for BSD compatibility */ @@ -210,7 +208,7 @@ char *ask_location(const char*msg, const char *src_dir, const char *dst_org) !dir_entrie->d_name[1]=='\0' && !(dir_entrie->d_name[1]=='.' && dir_entrie->d_name[2]=='\0')) continue; - if(strlen(dst_directory)+1+strlen(file_info->name)+1<=sizeof(current_file) + if(strlen(dst_directory) + 1 + strlen(dir_entrie->d_name) + 1 <= sizeof(current_file) #ifdef __CYGWIN__ && (memcmp(dst_directory, "/cygdrive", 9)!=0 || (dst_directory[9]!='\0' && dst_directory[10]!='\0') || @@ -249,7 +247,7 @@ char *ask_location(const char*msg, const char *src_dir, const char *dst_org) file_info->stat.st_gid=0; } #endif - strncpy(file_info->name,dir_entrie->d_name,sizeof(file_info->name)); + file_info->name=strdup(dir_entrie->d_name); td_list_add_sorted(&file_info->list, &dir_list.list, filesort); file_info=(file_info_t*)MALLOC(sizeof(*file_info)); } @@ -483,15 +481,15 @@ char *ask_location(const char*msg, const char *src_dir, const char *dst_org) (LINUX_S_ISDIR(file_info->stat.st_mode) || LINUX_S_ISLNK(file_info->stat.st_mode))) if(current_file!=&dir_list.list) { - if(strcmp(file_info->name,".")==0) + if(strcmp(file_info->name, ".")==0) { } - else if(strcmp(file_info->name,"..")==0) + else if(strcmp(file_info->name, "..")==0) { set_parent_directory(dst_directory); quit=ASK_LOCATION_NEWDIR; } - else if(strlen(dst_directory)+1+strlen(file_info->name)+1<=sizeof(dst_directory)) + else if(strlen(dst_directory) + 1 + strlen(file_info->name) + 1 <= sizeof(dst_directory)) { #if defined(DJGPP) || defined(__OS2__) if(dst_directory[0]!='\0'&&dst_directory[1]!='\0'&&dst_directory[2]!='\0'&&dst_directory[3]!='\0') @@ -499,7 +497,7 @@ char *ask_location(const char*msg, const char *src_dir, const char *dst_org) if(dst_directory[1]!='\0') #endif strcat(dst_directory,SPATH_SEP); - strcat(dst_directory,file_info->name); + strcat(dst_directory, file_info->name); quit=ASK_LOCATION_NEWDIR; } } diff --git a/src/dir.c b/src/dir.c index c17d8eb8..fc020822 100644 --- a/src/dir.c +++ b/src/dir.c @@ -269,6 +269,7 @@ void delete_list_file_info(struct td_list_head *list) { file_info_t *file_info; file_info=td_list_entry(file_walker, file_info_t, list); + free(file_info->name); td_list_del(file_walker); free(file_info); } @@ -336,13 +337,13 @@ int filesort(const struct td_list_head *a, const struct td_list_head *b) if(res) return res; /* . and .. must listed before the other directories */ - if((file_a->stat.st_mode&LINUX_S_IFDIR) && strcmp(file_a->name,".")==0) + if((file_a->stat.st_mode&LINUX_S_IFDIR) && strcmp(file_a->name, ".")==0) return -1; - if((file_a->stat.st_mode&LINUX_S_IFDIR) && strcmp(file_a->name,"..")==0 && - !strcmp(file_b->name,".")==0) + if((file_a->stat.st_mode&LINUX_S_IFDIR) && strcmp(file_a->name, "..")==0 && + !strcmp(file_b->name, ".")==0) return -1; /* Files and directories are sorted by name */ - return strcmp(file_a->name,file_b->name); + return strcmp(file_a->name, file_b->name); } /* diff --git a/src/dir.h b/src/dir.h index 0cace34f..5e599ebf 100644 --- a/src/dir.h +++ b/src/dir.h @@ -70,7 +70,7 @@ struct file_data typedef struct { struct td_list_head list; - char name[4096]; + char *name; struct stat stat; unsigned int status; } file_info_t; diff --git a/src/ntfs_udl.c b/src/ntfs_udl.c index e319b2b9..68fd070d 100644 --- a/src/ntfs_udl.c +++ b/src/ntfs_udl.c @@ -303,20 +303,23 @@ static void get_parent_name(struct filename* name, ntfs_volume* vol) { if(name->parent_name==NULL || parent_name==NULL) name->parent_name=parent_name; - else if(strcmp(parent_name,".")==0 && inode_num==5) - { - /* root directory */ - char *npn=(char *)MALLOC(strlen(name->parent_name)+2); - sprintf(npn, "/%s", name->parent_name); - free(name->parent_name); - name->parent_name=npn; - } else { - char *npn=(char *)MALLOC(strlen(parent_name)+strlen(name->parent_name)+2); - sprintf(npn, "%s/%s", parent_name, name->parent_name); + char *npn; + if(strcmp(parent_name,".")==0 && inode_num==5) + { + /* root directory */ + npn=(char *)MALLOC(strlen(name->parent_name)+2); + sprintf(npn, "/%s", name->parent_name); + } + else + { + npn=(char *)MALLOC(strlen(parent_name)+strlen(name->parent_name)+2); + sprintf(npn, "%s/%s", parent_name, name->parent_name); + } free(name->parent_name); name->parent_name=npn; + free(parent_name); } if((unsigned)inode_num!=MREF(filename_attr->parent_directory)) { @@ -1045,25 +1048,16 @@ free: static file_info_t *ufile_to_file_data(const struct ufile *file) { file_info_t *new_file; - unsigned int len; if(file->pref_name==NULL) return NULL; new_file=(file_info_t *)MALLOC(sizeof(*new_file)); - len=strlen(file->pref_name); - if(file->pref_pname!=NULL) - len+=strlen(file->pref_pname)+1; - if(lenname)) - { - if(file->pref_pname!=NULL) - sprintf((char *)&new_file->name, "%s/%s", file->pref_pname, file->pref_name); - else - memcpy(&new_file->name, file->pref_name, len); - } + if(file->pref_pname==NULL) + new_file->name=strdup(file->pref_name); else { - memcpy(new_file->name, file->pref_name, - strlen(file->pref_name)+1name)?strlen(file->pref_name)+1:sizeof(new_file->name) ); - new_file->name[sizeof(new_file->name)-1]=0; + const unsigned int len=strlen(file->pref_name) + 1 + strlen(file->pref_pname) + 1; + new_file->name=(char *)MALLOC(len); + sprintf(new_file->name, "%s/%s", file->pref_pname, file->pref_name); } new_file->stat.st_dev=0; new_file->stat.st_ino=file->inode; @@ -1553,7 +1547,7 @@ int ntfs_undelete_part(disk_t *disk_car, const partition_t *partition, const int { static file_info_t dir_list = { .list = TD_LIST_HEAD_INIT(dir_list.list), - .name = {0} + .name = NULL }; struct ntfs_dir_struct *ls=(struct ntfs_dir_struct *)dir_data.private_dir_data; scan_disk(ls->vol, &dir_list);