Reduce memory usage during NTFS undelete

This commit is contained in:
Christophe Grenier 2010-11-22 08:26:28 +01:00
parent 3072cedc43
commit c32dfa4e43
4 changed files with 34 additions and 41 deletions

View file

@ -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;
}
}

View file

@ -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);
}
/*

View file

@ -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;

View file

@ -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(len<sizeof(new_file->name))
{
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)+1<sizeof(new_file->name)?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);