summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2013-05-05 21:52:54 +0200
committerChristophe Grenier <grenier@cgsecurity.org>2013-05-05 21:52:54 +0200
commit3f03c0e6aafef241a795e62f2edb159b1de4b038 (patch)
treec04b806dd3d93d89dc2dfbeea1e2cd070252253b /src
parentb9458447e8cbce92cbb8bb082ae447cc5a9d9341 (diff)
Migrate from file_data to file_info structure
Diffstat (limited to 'src')
-rw-r--r--src/askloc.c2
-rw-r--r--src/dir.c52
-rw-r--r--src/dir.h56
-rw-r--r--src/dirn.c147
-rw-r--r--src/exfat_dir.c31
-rw-r--r--src/ext2_dir.c30
-rw-r--r--src/ext2_inc.h3
-rw-r--r--src/fat_adv.c200
-rw-r--r--src/fat_dir.c61
-rw-r--r--src/fat_dir.h2
-rw-r--r--src/fat_unformat.c41
-rw-r--r--src/filegen.h2
-rw-r--r--src/ntfs_dir.c54
-rw-r--r--src/ntfs_fix.c26
-rw-r--r--src/ntfs_inc.h3
-rw-r--r--src/ntfs_udl.c2
-rw-r--r--src/phrecn.c13
-rw-r--r--src/rfs_dir.c27
18 files changed, 368 insertions, 384 deletions
diff --git a/src/askloc.c b/src/askloc.c
index 23f18c7..8ca2b19 100644
--- a/src/askloc.c
+++ b/src/askloc.c
@@ -542,7 +542,7 @@ char *ask_location(const char*msg, const char *src_dir, const char *dst_org)
offset=pos_num-INTER_DIR+1;
} while(quit==ASK_LOCATION_WAITKEY && old_LINES==LINES);
} while(quit==ASK_LOCATION_UPDATE || old_LINES!=LINES);
- delete_list_file_info(&dir_list.list);
+ delete_list_file(&dir_list);
}
else
{
diff --git a/src/dir.c b/src/dir.c
index a4b9630..aa0c78b 100644
--- a/src/dir.c
+++ b/src/dir.c
@@ -149,16 +149,17 @@ void mode_string (const unsigned int mode, char *str)
#endif
}
-int dir_aff_log(const dir_data_t *dir_data, const file_data_t*dir_list)
+int dir_aff_log(const dir_data_t *dir_data, const file_info_t *dir_list)
{
int test_date=0;
- const file_data_t *current_file;
+ struct td_list_head *file_walker = NULL;
if(dir_data!=NULL)
{
log_info("Directory %s\n",dir_data->current_directory);
}
- for(current_file=dir_list;current_file!=NULL;current_file=current_file->next)
+ td_list_for_each(file_walker, &dir_list->list)
{
+ const file_info_t *current_file=td_list_entry(file_walker, file_info_t, list);
char datestr[80];
char str[11];
if(current_file->td_mtime)
@@ -247,52 +248,45 @@ int log_list_file(const disk_t *disk, const partition_t *partition, const dir_da
return test_date;
}
-unsigned int delete_list_file(file_data_t *file_list)
-{
- int nbr=0;
- file_data_t *current_file=file_list;
- while(current_file!=NULL)
- {
- file_data_t *next=current_file->next;
- free(current_file);
- current_file=next;
- nbr++;
- }
- return nbr;
-}
-
-void delete_list_file_info(struct td_list_head *list)
+unsigned int delete_list_file(file_info_t *file_info)
{
+ unsigned int nbr=0;
struct td_list_head *file_walker = NULL;
struct td_list_head *file_walker_next = NULL;
- td_list_for_each_safe(file_walker,file_walker_next, list)
+ td_list_for_each_safe(file_walker,file_walker_next, &file_info->list)
{
- file_info_t *file_info;
- file_info=td_list_entry(file_walker, file_info_t, list);
- free(file_info->name);
+ file_info_t *tmp;
+ tmp=td_list_entry(file_walker, file_info_t, list);
+ free(tmp->name);
td_list_del(file_walker);
- free(file_info);
+ free(tmp);
+ nbr++;
}
+ return nbr;
}
static int dir_whole_partition_log_aux(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const unsigned long int inode)
{
- file_data_t *dir_list;
- file_data_t *current_file;
+ struct td_list_head *file_walker = NULL;
#define MAX_DIR_NBR 256
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);
+ static file_info_t dir_list = {
+ .list = TD_LIST_HEAD_INIT(dir_list.list),
+ .name = NULL
+ };
if(dir_nbr==MAX_DIR_NBR)
return 1; /* subdirectories depth is too high => Back */
if(dir_data->verbose>0)
log_info("\ndir_partition inode=%lu\n",inode);
- dir_list=dir_data->get_dir(disk, partition, dir_data, inode);
- dir_aff_log(dir_data, dir_list);
+ dir_data->get_dir(disk, partition, dir_data, inode, &dir_list);
+ dir_aff_log(dir_data, &dir_list);
/* Not perfect for FAT32 root cluster */
inode_known[dir_nbr++]=inode;
- for(current_file=dir_list;current_file!=NULL;current_file=current_file->next)
+ td_list_for_each(file_walker, &dir_list.list)
{
+ const file_info_t *current_file=td_list_entry(file_walker, file_info_t, list);
if(LINUX_S_ISDIR(current_file->st_mode)!=0)
{
const unsigned long int new_inode=current_file->st_ino;
@@ -319,7 +313,7 @@ static int dir_whole_partition_log_aux(disk_t *disk, const partition_t *partitio
}
}
}
- delete_list_file(dir_list);
+ delete_list_file(&dir_list);
dir_nbr--;
return 0;
}
diff --git a/src/dir.h b/src/dir.h
index ba8a0f9..a21ae1e 100644
--- a/src/dir.h
+++ b/src/dir.h
@@ -39,7 +39,20 @@ extern "C" {
#define CAPA_LIST_ADS 2
typedef struct dir_data dir_data_t;
-typedef struct file_data file_data_t;
+typedef struct
+{
+ struct td_list_head list;
+ char *name;
+ uint32_t st_ino;
+ uint32_t st_mode;
+ uint32_t st_uid;
+ uint32_t st_gid;
+ uint64_t st_size;
+ time_t td_atime; /* time of last access */
+ time_t td_mtime; /* time of last modification */
+ time_t td_ctime; /* time of last status change */
+ unsigned int status;
+} file_info_t;
struct dir_data
{
@@ -49,8 +62,8 @@ struct dir_data
int verbose;
unsigned int param;
unsigned int capabilities;
- file_data_t *(*get_dir)(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int first_inode);
- int (*copy_file)(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const file_data_t *file);
+ int(*get_dir)(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int first_inode, file_info_t*list);
+ int (*copy_file)(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const file_info_t *file);
void (*close)(dir_data_t *dir_data);
char *local_dir;
void *private_dir_data;
@@ -60,42 +73,9 @@ struct dir_data
#define FILE_STATUS_MARKED 2
#define FILE_STATUS_ADS 4
-/* TODO: migrate file_data to file_info */
-struct file_data
-{
- file_data_t *prev;
- file_data_t *next;
- char name[DIR_NAME_LEN];
- uint32_t st_ino;
- uint32_t st_mode;
- uint32_t st_uid;
- uint32_t st_gid;
- uint64_t st_size;
- time_t td_atime; /* time of last access */
- time_t td_mtime; /* time of last modification */
- time_t td_ctime; /* time of last status change */
- unsigned int status;
-};
-
-typedef struct
-{
- struct td_list_head list;
- char *name;
- uint32_t st_ino;
- uint32_t st_mode;
- uint32_t st_uid;
- uint32_t st_gid;
- uint64_t st_size;
- time_t td_atime; /* time of last access */
- time_t td_mtime; /* time of last modification */
- time_t td_ctime; /* time of last status change */
- unsigned int status;
-} file_info_t;
-
-int dir_aff_log(const dir_data_t *dir_data, const file_data_t*dir_list);
+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_data_t *file_list);
-void delete_list_file_info(struct td_list_head *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 mode_string (const unsigned int mode, char *str);
int set_mode(const char *pathname, unsigned int mode);
diff --git a/src/dirn.c b/src/dirn.c
index 0f0bd1e..bd9a4ff 100644
--- a/src/dirn.c
+++ b/src/dirn.c
@@ -47,9 +47,7 @@
extern const char *monstr[];
-static int dir_partition_aux(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const unsigned long int inode, const unsigned int depth, char **current_cmd);
-static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, file_data_t*dir_list, const unsigned long int inode, const unsigned int depth);
-static void copy_dir(WINDOW *window, disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const file_data_t *dir, unsigned int *copy_ok, unsigned int *copy_bad);
+static void copy_dir(WINDOW *window, disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const file_info_t *dir, unsigned int *copy_ok, unsigned int *copy_bad);
#define INTER_DIR (LINES-25+15)
@@ -93,7 +91,7 @@ static void copy_done(WINDOW *window, const unsigned int copy_ok, const unsigned
wrefresh(window);
}
-static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, file_data_t*dir_list, const unsigned long int inode, const unsigned int depth)
+static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, file_info_t*dir_list, const unsigned long int inode, const unsigned int depth)
{
/* Return value
* -1: quit
@@ -107,7 +105,7 @@ static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_
{
int offset=0;
int pos_num=0;
- file_data_t *pos=dir_list;
+ struct td_list_head *pos=dir_list->list.next;
const int old_LINES=LINES;
unsigned int status=FILE_STATUS_MARKED;
aff_copy(window);
@@ -119,15 +117,20 @@ static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_
{
int i;
int car;
- const file_data_t *current_file;
- for(i=0,current_file=dir_list;(current_file!=NULL) && (i<offset);current_file=current_file->next,i++);
- for(i=offset;(current_file!=NULL) &&((i-offset)<INTER_DIR);i++,current_file=current_file->next)
+ struct td_list_head *file_walker = NULL;
+ for(i=0, file_walker=dir_list->list.next;
+ file_walker!=&dir_list->list && i<offset;
+ file_walker=file_walker->next,i++);
+ for(i=offset;
+ file_walker!=&dir_list->list && (i-offset)<INTER_DIR;
+ file_walker=file_walker->next,i++)
{
+ const file_info_t *current_file=td_list_entry(file_walker, file_info_t, list);
char str[11];
char datestr[80];
wmove(window, 6+i-offset, 0);
wclrtoeol(window); /* before addstr for BSD compatibility */
- if(current_file==pos)
+ if(&current_file->list==pos)
{
wattrset(window, A_REVERSE);
waddstr(window, ">");
@@ -159,7 +162,7 @@ static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_
if(((current_file->status&FILE_STATUS_DELETED)!=0 ||
(current_file->status&FILE_STATUS_MARKED)!=0) && has_colors())
wbkgdset(window,' ' | COLOR_PAIR(0));
- if(current_file==pos)
+ if(&current_file->list==pos)
wattroff(window, A_REVERSE);
}
wmove(window, 6-1, 51);
@@ -171,9 +174,9 @@ static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_
wclrtoeol(window);
wmove(window, 6+INTER_DIR, 51);
wclrtoeol(window);
- if(current_file!=NULL)
+ if(file_walker->next!=&dir_list->list)
wprintw(window, "Next");
- if(dir_list==NULL)
+ if(td_list_empty(&dir_list->list))
{
wmove(window,6,0);
wprintw(window,"No file found, filesystem may be damaged.");
@@ -290,13 +293,13 @@ static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_
wrefresh(window);
break;
}
- if(dir_list!=NULL)
+ if(!td_list_empty(&dir_list->list))
{
switch(car)
{
case KEY_UP:
case '8':
- if(pos->prev!=NULL)
+ if(pos->prev!=&dir_list->list)
{
pos=pos->prev;
pos_num--;
@@ -304,17 +307,21 @@ static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_
break;
case KEY_DOWN:
case '2':
- if(pos->next!=NULL)
+ if(pos->next!=&dir_list->list)
{
pos=pos->next;
pos_num++;
}
break;
case ':':
- if(!(pos->name[0]=='.' && pos->name[1]=='\0') &&
- !(pos->name[0]=='.' && pos->name[1]=='.' && pos->name[2]=='\0'))
- pos->status^=FILE_STATUS_MARKED;
- if(pos->next!=NULL)
+ {
+ file_info_t *selected_file;
+ selected_file=td_list_entry(pos, file_info_t, list);
+ if(!(selected_file->name[0]=='.' && selected_file->name[1]=='\0') &&
+ !(selected_file->name[0]=='.' && selected_file->name[1]=='.' && selected_file->name[2]=='\0'))
+ selected_file->status^=FILE_STATUS_MARKED;
+ }
+ if(pos->next!=&dir_list->list)
{
pos=pos->next;
pos_num++;
@@ -322,9 +329,10 @@ static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_
break;
case 'a':
{
- file_data_t *tmp;
- for(tmp=dir_list; tmp!=NULL; tmp=tmp->next)
+ struct td_list_head *tmpw= NULL;
+ td_list_for_each(tmpw, &dir_list->list)
{
+ file_info_t *tmp=td_list_entry(tmpw, file_info_t, list);
if((tmp->name[0]=='.' && tmp->name[1]=='\0') ||
(tmp->name[0]=='.' && tmp->name[1]=='.' && tmp->name[2]=='\0'))
{
@@ -351,32 +359,35 @@ static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_
#ifdef PADENTER
case PADENTER:
#endif
- if((pos!=NULL) && (LINUX_S_ISDIR(pos->st_mode)!=0))
{
- unsigned long int new_inode=pos->st_ino;
- if((new_inode!=inode) &&(strcmp(pos->name,".")!=0))
+ file_info_t *tmp=td_list_entry(pos, file_info_t, list);
+ if(pos!=&dir_list->list && (LINUX_S_ISDIR(tmp->st_mode)!=0))
{
- if(strcmp(pos->name,"..")==0)
- return 1;
- if(strlen(dir_data->current_directory)+1+strlen(pos->name)+1<=sizeof(dir_data->current_directory))
+ unsigned long int new_inode=tmp->st_ino;
+ if((new_inode!=inode) &&(strcmp(tmp->name,".")!=0))
{
- if(strcmp(dir_data->current_directory,"/"))
- strcat(dir_data->current_directory,"/");
- strcat(dir_data->current_directory,pos->name);
- return (long int)new_inode;
+ if(strcmp(tmp->name,"..")==0)
+ return 1;
+ if(strlen(dir_data->current_directory)+1+strlen(tmp->name)+1<=sizeof(dir_data->current_directory))
+ {
+ if(strcmp(dir_data->current_directory,"/"))
+ strcat(dir_data->current_directory,"/");
+ strcat(dir_data->current_directory,tmp->name);
+ return (long int)new_inode;
+ }
}
}
}
break;
case KEY_PPAGE:
- for(i=0;(i<INTER_DIR-1)&&(pos->prev!=NULL);i++)
+ for(i=0; i<INTER_DIR-1 && pos->prev!=&dir_list->list; i++)
{
pos=pos->prev;
pos_num--;
}
break;
case KEY_NPAGE:
- for(i=0;(i<INTER_DIR-1)&&(pos->next!=NULL);i++)
+ for(i=0; i<INTER_DIR-1 && pos->next!=&dir_list->list; i++)
{
pos=pos->next;
pos_num++;
@@ -386,17 +397,19 @@ static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_
if(dir_data->copy_file!=NULL)
{
const unsigned int current_directory_namelength=strlen(dir_data->current_directory);
- if(strcmp(pos->name,"..")!=0 &&
- current_directory_namelength+1+strlen(pos->name)<sizeof(dir_data->current_directory)-1)
+ file_info_t *tmp=td_list_entry(pos, file_info_t, list);
+ if(pos!=&dir_list->list &&
+ strcmp(tmp->name,"..")!=0 &&
+ current_directory_namelength+1+strlen(tmp->name)<sizeof(dir_data->current_directory)-1)
{
if(strcmp(dir_data->current_directory,"/"))
strcat(dir_data->current_directory,"/");
- if(strcmp(pos->name,".")!=0)
- strcat(dir_data->current_directory,pos->name);
+ if(strcmp(tmp->name,".")!=0)
+ strcat(dir_data->current_directory,tmp->name);
if(dir_data->local_dir==NULL || ask_destination>0)
{
char *local_dir=dir_data->local_dir;
- if(LINUX_S_ISDIR(pos->st_mode)!=0)
+ if(LINUX_S_ISDIR(tmp->st_mode)!=0)
dir_data->local_dir=ask_location("Please select a destination where %s and any files below will be copied.",
dir_data->current_directory, local_dir);
else
@@ -409,13 +422,14 @@ static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_
{
unsigned int copy_bad=0;
unsigned int copy_ok=0;
- if(LINUX_S_ISDIR(pos->st_mode)!=0)
+ if(LINUX_S_ISDIR(tmp->st_mode)!=0)
{
- copy_dir(window, disk, partition, dir_data, pos, &copy_ok, &copy_bad);
+ copy_dir(window, disk, partition, dir_data, tmp, &copy_ok, &copy_bad);
}
- else if(LINUX_S_ISREG(pos->st_mode)!=0)
+ else if(LINUX_S_ISREG(tmp->st_mode)!=0)
{
- if(dir_data->copy_file(disk, partition, dir_data, pos)==0)
+ copy_progress(window, copy_ok, copy_bad);
+ if(dir_data->copy_file(disk, partition, dir_data, tmp)==0)
copy_ok++;
else
copy_bad++;
@@ -438,12 +452,13 @@ static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_
}
if(dir_data->local_dir!=NULL)
{
- file_data_t *tmp;
unsigned int copy_bad=0;
unsigned int copy_ok=0;
const unsigned int current_directory_namelength=strlen(dir_data->current_directory);
- for(tmp=dir_list; tmp!=NULL; tmp=tmp->next)
+ struct td_list_head *tmpw= NULL;
+ td_list_for_each(tmpw, &dir_list->list)
{
+ file_info_t *tmp=td_list_entry(tmpw, file_info_t, list);
if((tmp->status&FILE_STATUS_MARKED)!=0 &&
current_directory_namelength + 1 + strlen(tmp->name) <
sizeof(dir_data->current_directory)-1)
@@ -477,14 +492,18 @@ static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_
const char *needle=ask_string_ncurses("Filename to find ? ");
if(needle!=NULL && needle[0]!='\0')
{
- file_data_t *pos_org=pos;
+ file_info_t *tmp;
+ struct td_list_head *pos_org=pos;
const int pos_num_org=pos_num;
- while(strcmp(pos->name, needle)!=0 && pos->next!=NULL)
+ tmp=td_list_entry(pos, file_info_t, list);
+ while(pos->next!=&dir_list->list &&
+ strcmp(tmp->name, needle)!=0)
{
pos=pos->next;
+ tmp=td_list_entry(pos, file_info_t, list);
pos_num++;
}
- if(strcmp(pos->name, needle)!=0)
+ if(pos==&dir_list->list)
{
pos=pos_org;
pos_num=pos_num_org;
@@ -518,22 +537,25 @@ static int dir_partition_aux(disk_t *disk, const partition_t *partition, dir_dat
{
const unsigned int current_directory_namelength=strlen(dir_data->current_directory);
long int new_inode=-1; /* Quit */
- file_data_t *dir_list;
+ file_info_t dir_list = {
+ .list = TD_LIST_HEAD_INIT(dir_list.list),
+ .name = NULL
+ };
/* Not perfect for FAT32 root cluster */
inode_known[depth]=inode;
- dir_list=dir_data->get_dir(disk, partition, dir_data, inode);
- dir_aff_log(dir_data, dir_list);
+ dir_data->get_dir(disk, partition, dir_data, inode, &dir_list);
+ dir_aff_log(dir_data, &dir_list);
if(*current_cmd!=NULL)
{
/* TODO: handle copy_files */
dir_data->current_directory[current_directory_namelength]='\0';
- delete_list_file(dir_list);
+ delete_list_file(&dir_list);
return -1; /* Quit */
}
- new_inode=dir_aff_ncurses(disk, partition, dir_data,dir_list,inode,depth);
+ new_inode=dir_aff_ncurses(disk, partition, dir_data, &dir_list, inode, depth);
if(new_inode==-1 || new_inode==1) /* -1:Quit or 1:Back */
{
- delete_list_file(dir_list);
+ delete_list_file(&dir_list);
return new_inode;
}
if(new_inode>=2)
@@ -550,7 +572,7 @@ static int dir_partition_aux(disk_t *disk, const partition_t *partition, dir_dat
}
/* restore current_directory name */
dir_data->current_directory[current_directory_namelength]='\0';
- delete_list_file(dir_list);
+ delete_list_file(&dir_list);
}
}
@@ -568,21 +590,26 @@ Returns
0: all files has been copied
*/
#define MAX_DIR_NBR 256
-static void copy_dir(WINDOW *window, disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const file_data_t *dir, unsigned int *copy_ok, unsigned int *copy_bad)
+static void copy_dir(WINDOW *window, disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const file_info_t *dir, unsigned int *copy_ok, unsigned int *copy_bad)
{
static unsigned int dir_nbr=0;
static unsigned long int inode_known[MAX_DIR_NBR];
- file_data_t *dir_list;
+ static file_info_t dir_list = {
+ .list = TD_LIST_HEAD_INIT(dir_list.list),
+ .name = NULL
+ };
const unsigned int current_directory_namelength=strlen(dir_data->current_directory);
- file_data_t *current_file;
char *dir_name;
+ struct td_list_head *file_walker = NULL;
if(dir_data->get_dir==NULL || dir_data->copy_file==NULL)
return;
inode_known[dir_nbr++]=dir->st_ino;
dir_name=mkdir_local(dir_data->local_dir, dir_data->current_directory);
- dir_list=dir_data->get_dir(disk, partition, dir_data, (const unsigned long int)dir->st_ino);
- for(current_file=dir_list;current_file!=NULL;current_file=current_file->next)
+ dir_data->get_dir(disk, partition, dir_data, (const unsigned long int)dir->st_ino, &dir_list);
+ td_list_for_each(file_walker, &dir_list.list)
{
+ file_info_t *current_file;
+ current_file=td_list_entry(file_walker, file_info_t, list);
dir_data->current_directory[current_directory_namelength]='\0';
if(current_directory_namelength+1+strlen(current_file->name)<sizeof(dir_data->current_directory)-1)
{
@@ -617,7 +644,7 @@ static void copy_dir(WINDOW *window, disk_t *disk, const partition_t *partition,
}
}
dir_data->current_directory[current_directory_namelength]='\0';
- delete_list_file(dir_list);
+ delete_list_file(&dir_list);
set_date(dir_name, dir->td_atime, dir->td_mtime);
free(dir_name);
dir_nbr--;
diff --git a/src/exfat_dir.c b/src/exfat_dir.c
index e143c20..ac8ee9b 100644
--- a/src/exfat_dir.c
+++ b/src/exfat_dir.c
@@ -61,9 +61,9 @@ struct exfat_dir_struct
};
-static file_data_t *exfat_dir(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const unsigned long int first_cluster);
+static int exfat_dir(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const unsigned long int first_cluster, file_info_t *dir_list);
static inline void exfat16_towchar(wchar_t *dst, const uint8_t *src, size_t len);
-static int exfat_copy(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const file_data_t *file);
+static int exfat_copy(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const file_info_t *file);
static void dir_partition_exfat_close(dir_data_t *dir_data);
static inline void exfat16_towchar(wchar_t *dst, const uint8_t *src, size_t len)
@@ -81,7 +81,7 @@ static inline void exfat16_towchar(wchar_t *dst, const uint8_t *src, size_t len)
#define ATTR_ARCH 32 /* archived */
#define EXFAT_MKMODE(a,m) ((m & (a & ATTR_RO ? LINUX_S_IRUGO|LINUX_S_IXUGO : LINUX_S_IRWXUGO)) | (a & ATTR_DIR ? LINUX_S_IFDIR : LINUX_S_IFREG))
-static file_data_t *dir_exfat_aux(const unsigned char*buffer, const unsigned int size, const unsigned int param)
+static int dir_exfat_aux(const unsigned char*buffer, const unsigned int size, const unsigned int param, file_info_t *dir_list)
{
/*
* 0x83 Volume label
@@ -95,8 +95,7 @@ static file_data_t *dir_exfat_aux(const unsigned char*buffer, const unsigned int
* 0xE2 Windows CE ACL
*
*/
- file_data_t *dir_list=NULL;
- file_data_t *current_file=NULL;
+ file_info_t *current_file=NULL;
unsigned int offset=0;
unsigned int sec_count=0;
for(offset=0; offset<size; offset+=0x20)
@@ -107,8 +106,9 @@ static file_data_t *dir_exfat_aux(const unsigned char*buffer, const unsigned int
if((buffer[offset]&0x7f)==0x05)
{ /* File directory entry */
const struct exfat_file_entry *entry=(const struct exfat_file_entry *)&buffer[offset];
- file_data_t *new_file=(file_data_t *)MALLOC(sizeof(*new_file));
+ file_info_t *new_file=(file_info_t *)MALLOC(sizeof(*new_file));
sec_count=entry->sec_count;
+ new_file->name=(char *)MALLOC(512);
new_file->name[0]=0;
new_file->st_ino=0;
new_file->st_mode = EXFAT_MKMODE(entry->attr,(LINUX_S_IRWXUGO & ~(LINUX_S_IWGRP|LINUX_S_IWOTH)));
@@ -119,14 +119,8 @@ static file_data_t *dir_exfat_aux(const unsigned char*buffer, const unsigned int
new_file->td_ctime=date_dos2unix(le16(entry->ctime),le16(entry->cdate));
new_file->td_mtime=date_dos2unix(le16(entry->mtime),le16(entry->mdate));
new_file->status=((entry->type&0x80)==0x80?0:FILE_STATUS_DELETED);
- new_file->prev=current_file;
- new_file->next=NULL;
- /* log_debug("exfat: new file %s de=%p size=%u\n",new_file->name,de,le32(de->size)); */
- if(current_file!=NULL)
- current_file->next=new_file;
- else
- dir_list=new_file;
current_file=new_file;
+ td_list_add_tail(&new_file->list, &dir_list->list);
}
else if(sec_count>0 && current_file!=NULL)
{
@@ -153,7 +147,7 @@ static file_data_t *dir_exfat_aux(const unsigned char*buffer, const unsigned int
sec_count--;
}
}
- return dir_list;
+ return 0;
}
enum {exFAT_FOLLOW_CLUSTER, exFAT_NEXT_FREE_CLUSTER, exFAT_NEXT_CLUSTER};
@@ -164,12 +158,11 @@ static int is_EOC(const unsigned int cluster)
}
#define NBR_CLUSTER_MAX 30
-static file_data_t *exfat_dir(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const unsigned long int first_cluster)
+static int exfat_dir(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const unsigned long int first_cluster, file_info_t *dir_list)
{
const struct exfat_dir_struct *ls=(const struct exfat_dir_struct*)dir_data->private_dir_data;
const struct exfat_super_block*exfat_header=ls->boot_sector;
const unsigned int cluster_shift=exfat_header->block_per_clus_bits + exfat_header->blocksize_bits;
- file_data_t *dir_list=NULL;
unsigned int cluster;
unsigned char *buffer_dir=(unsigned char *)MALLOC(NBR_CLUSTER_MAX << cluster_shift);
unsigned int nbr_cluster;
@@ -229,9 +222,9 @@ static file_data_t *exfat_dir(disk_t *disk, const partition_t *partition, dir_da
}
}
if(nbr_cluster>0)
- dir_list=dir_exfat_aux(buffer_dir, nbr_cluster<<cluster_shift, dir_data->param);
+ dir_exfat_aux(buffer_dir, nbr_cluster<<cluster_shift, dir_data->param, dir_list);
free(buffer_dir);
- return dir_list;
+ return 0;
}
int dir_partition_exfat_init(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const int verbose)
@@ -286,7 +279,7 @@ static void dir_partition_exfat_close(dir_data_t *dir_data)
free(ls);
}
-static int exfat_copy(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const file_data_t *file)
+static int exfat_copy(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const file_info_t *file)
{
char *new_file;
FILE *f_out;
diff --git a/src/ext2_dir.c b/src/ext2_dir.c
index 28bbe69..ac15a20 100644
--- a/src/ext2_dir.c
+++ b/src/ext2_dir.c
@@ -67,7 +67,7 @@ static errcode_t my_flush(io_channel channel);
static io_channel alloc_io_channel(disk_t *disk_car,my_data_t *my_data);
static void dir_partition_ext2_close(dir_data_t *dir_data);
-static int ext2_copy(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const file_data_t *file);
+static int ext2_copy(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const file_info_t *file);
static struct struct_io_manager my_struct_manager = {
.magic = EXT2_ET_MAGIC_IO_MANAGER,
@@ -83,7 +83,7 @@ static struct struct_io_manager my_struct_manager = {
.set_option= NULL
#endif
};
-static file_data_t *ext2_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int cluster);
+static int ext2_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int cluster, file_info_t *dir_list);
static io_channel *shared_ioch=NULL;
/*
@@ -204,7 +204,7 @@ static int list_dir_proc2(ext2_ino_t dir,
struct ext2_inode inode;
ext2_ino_t ino;
struct ext2_dir_struct *ls = (struct ext2_dir_struct *) privateinfo;
- file_data_t *new_file;
+ file_info_t *new_file;
if(entry==DIRENT_DELETED_FILE && (ls->dir_data->param & FLAG_LIST_DELETED)==0)
return 0;
ino = dirent->inode;
@@ -219,15 +219,12 @@ static int list_dir_proc2(ext2_ino_t dir,
} else {
memset(&inode, 0, sizeof(struct ext2_inode));
}
- new_file=(file_data_t *)MALLOC(sizeof(*new_file));
- new_file->prev=ls->current_file;
- new_file->next=NULL;
+ new_file=(file_info_t *)MALLOC(sizeof(*new_file));
{
unsigned int thislen;
thislen = ((dirent->name_len & 0xFF) < EXT2_NAME_LEN) ?
(dirent->name_len & 0xFF) : EXT2_NAME_LEN;
- if(thislen>=DIR_NAME_LEN)
- thislen=DIR_NAME_LEN-1;
+ new_file->name=(char *)MALLOC(thislen+1);
memcpy(new_file->name, dirent->name, thislen);
new_file->name[thislen] = '\0';
}
@@ -247,25 +244,21 @@ static int list_dir_proc2(ext2_ino_t dir,
new_file->td_atime=inode.i_atime;
new_file->td_mtime=inode.i_mtime;
new_file->td_ctime=inode.i_ctime;
- if(ls->current_file!=NULL)
- ls->current_file->next=new_file;
- else
- ls->dir_list=new_file;
- ls->current_file=new_file;
+ td_list_add_tail(&new_file->list, &ls->dir_list->list);
return 0;
}
-static file_data_t *ext2_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int cluster)
+static int ext2_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int cluster, file_info_t *dir_list)
{
errcode_t retval;
struct ext2_dir_struct *ls=(struct ext2_dir_struct*)dir_data->private_dir_data;
- ls->dir_list=NULL;
- ls->current_file=NULL;
+ ls->dir_list=dir_list;
if((retval=ext2fs_dir_iterate2(ls->current_fs, cluster, ls->flags, 0, list_dir_proc2, ls))!=0)
{
log_error("ext2fs_dir_iterate failed with error %ld.\n",(long)retval);
+ return -1;
}
- return ls->dir_list;
+ return 0;
}
static void dir_partition_ext2_close(dir_data_t *dir_data)
@@ -276,7 +269,7 @@ static void dir_partition_ext2_close(dir_data_t *dir_data)
free(ls);
}
-static int ext2_copy(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const file_data_t *file)
+static int ext2_copy(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const file_info_t *file)
{
int error=0;
FILE *f_out;
@@ -350,7 +343,6 @@ int dir_partition_ext2_init(disk_t *disk_car, const partition_t *partition, dir_
io_channel ioch;
my_data_t *my_data;
ls->dir_list=NULL;
- ls->current_file=NULL;
/* ls->flags = DIRENT_FLAG_INCLUDE_EMPTY; */
ls->flags = DIRENT_FLAG_INCLUDE_REMOVED;
ls->dir_data=dir_data;
diff --git a/src/ext2_inc.h b/src/ext2_inc.h
index f0a6d3c..ca2421b 100644
--- a/src/ext2_inc.h
+++ b/src/ext2_inc.h
@@ -21,8 +21,7 @@
*/
#if defined(HAVE_LIBEXT2FS)
struct ext2_dir_struct {
- file_data_t *dir_list;
- file_data_t *current_file;
+ file_info_t *dir_list;
ext2_filsys current_fs;
int flags;
dir_data_t *dir_data;
diff --git a/src/fat_adv.c b/src/fat_adv.c
index 04793aa..1455f59 100644
--- a/src/fat_adv.c
+++ b/src/fat_adv.c
@@ -89,7 +89,7 @@ static unsigned long int get_subdirectory(disk_t *disk_car,const uint64_t hd_off
#ifdef HAVE_NCURSES
static void fat_date_unix2dos(int unix_date,unsigned short *mstime, unsigned short *msdate);
-static int fat32_create_rootdir(disk_t *disk_car,const partition_t *partition, const unsigned int reserved, const unsigned int fat_length, const unsigned int root_cluster, const unsigned int sectors_per_cluster, const int verbose, file_data_t *rootdir_list, const unsigned int fats);
+static int fat32_create_rootdir(disk_t *disk_car,const partition_t *partition, const unsigned int reserved, const unsigned int fat_length, const unsigned int root_cluster, const unsigned int sectors_per_cluster, const int verbose, file_info_t *rootdir_list, const unsigned int fats);
static upart_type_t select_fat_info(const info_offset_t *info_offset, const unsigned int nbr_offset,unsigned int*reserved, unsigned int*fat_length, const unsigned long int max_sector_offset, unsigned int *fats);
#endif
@@ -176,7 +176,7 @@ static unsigned long int get_subdirectory(disk_t *disk_car,const uint64_t hd_off
#ifdef HAVE_NCURSES
#define INTER_DIR 16
-static int ask_root_directory(disk_t *disk_car, const partition_t *partition, const file_data_t*dir_list, const unsigned long int cluster)
+static int ask_root_directory(disk_t *disk_car, const partition_t *partition, const file_info_t*dir_list, const unsigned long int cluster)
{
/* Return value
* -1: quit
@@ -187,8 +187,7 @@ static int ask_root_directory(disk_t *disk_car, const partition_t *partition, co
int quit=0;
int offset=0;
int pos_num=0;
- const file_data_t *current_file;
- const file_data_t *pos=dir_list;
+ struct td_list_head *pos=dir_list->list.next;
WINDOW *window;
window=newwin(LINES, COLS, 0, 0); /* full screen */
aff_copy(window);
@@ -200,14 +199,20 @@ static int ask_root_directory(disk_t *disk_car, const partition_t *partition, co
do
{
int i;
- for(i=0,current_file=dir_list;(current_file!=NULL) && (i<offset);current_file=current_file->next,i++);
- for(i=offset;(current_file!=NULL) &&((i-offset)<INTER_DIR);i++,current_file=current_file->next)
- {
+ struct td_list_head *file_walker = NULL;
+ for(i=0, file_walker=dir_list->list.next;
+ file_walker!=&dir_list->list && i<offset;
+ file_walker=file_walker->next,i++);
+ for(i=offset;
+ file_walker!=&dir_list->list && (i-offset)<INTER_DIR;
+ file_walker=file_walker->next,i++)
+ {
+ const file_info_t *current_file=td_list_entry(file_walker, file_info_t, list);
char str[11];
char datestr[80];
wmove(window,8+i-offset,0);
wclrtoeol(window); /* before addstr for BSD compatibility */
- if(current_file==pos)
+ if(&current_file->list==pos)
{
wattrset(window, A_REVERSE);
waddstr(window, ">");
@@ -230,7 +235,7 @@ static int ask_root_directory(disk_t *disk_car, const partition_t *partition, co
wprintw(window, "%9llu", (long long unsigned int)current_file->st_size);
/* FIXME: screen overlaps due to long filename */
wprintw(window, " %s %s\n", datestr, current_file->name);
- if(current_file==pos)
+ if(&current_file->list==pos)
wattroff(window, A_REVERSE);
}
/* Clear the last line, useful if overlapping */
@@ -255,33 +260,33 @@ static int ask_root_directory(disk_t *disk_car, const partition_t *partition, co
quit=1;
break;
}
- if(dir_list!=NULL)
+ if(!td_list_empty(&dir_list->list))
{
switch(car)
{
case KEY_UP:
- if(pos->prev!=NULL)
+ if(pos->prev!=&dir_list->list)
{
pos=pos->prev;
pos_num--;
}
break;
case KEY_DOWN:
- if(pos->next!=NULL)
+ if(pos->next!=&dir_list->list)
{
pos=pos->next;
pos_num++;
}
break;
case KEY_PPAGE:
- for(i=0; i<INTER_DIR-1 && pos->prev!=NULL; i++)
+ for(i=0; i<INTER_DIR-1 && pos->prev!=&dir_list->list; i++)
{
pos=pos->prev;
pos_num--;
}
break;
case KEY_NPAGE:
- for(i=0; i<INTER_DIR-1 && pos->next!=NULL; i++)
+ for(i=0; i<INTER_DIR-1 && pos->next!=&dir_list->list; i++)
{
pos=pos->next;
pos_num++;
@@ -315,14 +320,16 @@ static unsigned int fat32_find_root_cluster(disk_t *disk_car,const partition_t *
if(sectors_per_cluster==0)
return 0;
{
- file_data_t *rootdir_list=NULL;
- file_data_t *current_file=NULL;
unsigned int dir_nbr=0;
#ifdef HAVE_NCURSES
int interactive=1;
#endif
unsigned char *buffer;
int ind_stop=0;
+ static file_info_t rootdir_list= {
+ .list = TD_LIST_HEAD_INIT(rootdir_list.list),
+ .name = NULL
+ };
buffer=(unsigned char *)MALLOC(cluster_size);
#ifdef HAVE_NCURSES
if(interface)
@@ -366,27 +373,26 @@ static unsigned int fat32_find_root_cluster(disk_t *disk_car,const partition_t *
(buffer[1*0x20+0xB]!=ATTR_EXT && (buffer[1*0x20+0xB]&ATTR_DIR)!=0) && (cluster==0)
&& (buffer[0x40]!=0)) /* First-level directory */
{
- file_data_t *dir_list;
+ static file_info_t dir_list = {
+ .list = TD_LIST_HEAD_INIT(dir_list.list),
+ .name = NULL
+ };
log_info("First-level directory found at cluster %lu\n",root_cluster);
/* dump_ncurses(buffer,cluster_size); */
- dir_list=dir_fat_aux(buffer, cluster_size, cluster_size, 0);
+ dir_fat_aux(buffer, cluster_size, cluster_size, 0, &dir_list);
if(verbose>0)
{
- dir_aff_log(NULL, dir_list);
+ dir_aff_log(NULL, &dir_list);
}
{
- file_data_t *new_file=(file_data_t *)MALLOC(sizeof(*new_file));
- memcpy(new_file,dir_list,sizeof(*new_file));
- new_file->prev=current_file;
- new_file->next=NULL;
- if(current_file!=NULL)
- current_file->next=new_file;
- else
- rootdir_list=new_file;
- current_file=new_file;
- snprintf(new_file->name,sizeof(new_file->name),"DIR%05u",++dir_nbr);
+ const file_info_t *first_entry=td_list_entry(&dir_list.list, file_info_t, list);
+ file_info_t *new_file=(file_info_t *)MALLOC(sizeof(*new_file));
+ memcpy(new_file, first_entry, sizeof(*new_file));
+ new_file->name=(char*)MALLOC(32);
+ snprintf(new_file->name, 32,"DIR%05u",++dir_nbr);
+ td_list_add_tail(&new_file->list, &rootdir_list.list);
}
- delete_list_file(dir_list);
+ delete_list_file(&dir_list);
}
}
else if( memcmp(&buffer[0*0x20],&buffer[1*0x20],0x20)!=0)
@@ -498,30 +504,35 @@ static unsigned int fat32_find_root_cluster(disk_t *disk_car,const partition_t *
}
}
{
- file_data_t *dir_list;
- dir_list=dir_fat_aux(buffer, cluster_size, cluster_size, 0);
- if(dir_list!=NULL && (dir_list->next==NULL || dir_list->st_ino!=dir_list->next->st_ino))
+ static file_info_t dir_list = {
+ .list = TD_LIST_HEAD_INIT(dir_list.list),
+ .name = NULL
+ };
+ const file_info_t *file1=td_list_entry(dir_list.list.next, file_info_t, list);
+ const file_info_t *file2=td_list_entry(file1->list.next, file_info_t, list);
+ dir_fat_aux(buffer, cluster_size, cluster_size, 0, &dir_list);
+ if(!td_list_empty(&dir_list.list) && (&file2->list==&dir_list.list || file1->st_ino!=file2->st_ino))
{
int test_date=1;
if(verbose>0)
{
log_verbose("Potential root_cluster %lu\n",root_cluster);
- test_date=dir_aff_log(NULL, dir_list);
+ test_date=dir_aff_log(NULL, &dir_list);
}
#ifdef HAVE_NCURSES
if(interface>0 && interactive>0 && test_date>0)
{
- switch(ask_root_directory(disk_car,partition,dir_list,root_cluster))
+ switch(ask_root_directory(disk_car, partition, &dir_list, root_cluster))
{
case c_YES:
- delete_list_file(dir_list);
+ delete_list_file(&dir_list);
free(buffer);
return root_cluster;
case 'A':
interactive=0;
break;
case 'Q':
- delete_list_file(dir_list);
+ delete_list_file(&dir_list);
free(buffer);
return 0;
default:
@@ -530,7 +541,7 @@ static unsigned int fat32_find_root_cluster(disk_t *disk_car,const partition_t *
}
#endif
}
- delete_list_file(dir_list);
+ delete_list_file(&dir_list);
}
}
}
@@ -542,24 +553,24 @@ static unsigned int fat32_find_root_cluster(disk_t *disk_car,const partition_t *
else
log_error("Search root cluster failed\n");
root_cluster=0;
- if(rootdir_list==NULL)
+ if(td_list_empty(&rootdir_list.list))
{
log_warning("No first-level directory found.\n");
}
else
{
- dir_aff_log(NULL, rootdir_list);
+ dir_aff_log(NULL, &rootdir_list);
#ifdef HAVE_NCURSES
if(interface && expert>0)
{
if(ask_confirmation("Create a new root cluster with %u first-level directories (Expert only) (Y/N)",dir_nbr)!=0 && ask_confirmation("Write root cluster, confirm ? (Y/N)")!=0)
{
root_cluster=first_free_cluster;
- fat32_create_rootdir(disk_car, partition, reserved, fat_length, root_cluster, sectors_per_cluster, verbose, rootdir_list, fats);
+ fat32_create_rootdir(disk_car, partition, reserved, fat_length, root_cluster, sectors_per_cluster, verbose, &rootdir_list, fats);
}
}
#endif
- delete_list_file(rootdir_list);
+ delete_list_file(&rootdir_list);
}
free(buffer);
}
@@ -598,7 +609,7 @@ static void fat_date_unix2dos(int unix_date,unsigned short *mstime, unsigned sho
*msdate = le16(nl_day-day_n[month-1]+1+(month << 5)+(year << 9));
}
-static int file2entry(struct msdos_dir_entry *de, const file_data_t *current_file)
+static int file2entry(struct msdos_dir_entry *de, const file_info_t *current_file)
{
unsigned int i,j;
/* Name */
@@ -628,14 +639,14 @@ static int file2entry(struct msdos_dir_entry *de, const file_data_t *current_fil
return 0;
}
-static int fat32_create_rootdir(disk_t *disk_car,const partition_t *partition, const unsigned int reserved, const unsigned int fat_length, const unsigned int root_cluster, const unsigned int sectors_per_cluster, const int verbose, file_data_t *rootdir_list, const unsigned int fats)
+static int fat32_create_rootdir(disk_t *disk_car,const partition_t *partition, const unsigned int reserved, const unsigned int fat_length, const unsigned int root_cluster, const unsigned int sectors_per_cluster, const int verbose, file_info_t *rootdir_list, const unsigned int fats)
{
const uint64_t start_data=reserved+fats*fat_length;
const unsigned int cluster_size=disk_car->sector_size*sectors_per_cluster;
unsigned int current_entry=0;
unsigned int cluster;
unsigned char *buffer;
- file_data_t *current_file;
+ struct td_list_head *file_walker = NULL;
if(verbose>0)
{
log_trace("fat32_create_rootdir(reserved=%u,fat_length=%u,root_cluster=%u,sectors_per_cluster=%u)\n",reserved,fat_length,root_cluster,sectors_per_cluster);
@@ -643,8 +654,9 @@ static int fat32_create_rootdir(disk_t *disk_car,const partition_t *partition, c
cluster=root_cluster;
buffer=(unsigned char *)MALLOC(cluster_size);
memset(buffer,0,cluster_size);
- for(current_file=rootdir_list;current_file!=NULL;current_file=current_file->next)
+ td_list_for_each(file_walker, &rootdir_list->list)
{
+ const file_info_t *current_file=td_list_entry(file_walker, file_info_t, list);
file2entry((struct msdos_dir_entry*)buffer+current_entry,current_file);
if(++current_entry==(cluster_size/sizeof(struct msdos_dir_entry)))
{
@@ -666,7 +678,7 @@ static int fat32_create_rootdir(disk_t *disk_car,const partition_t *partition, c
{
display_message("Can't modify the FAT entries.\n");
}
-cluster=next_cluster;
+ cluster=next_cluster;
}
}
if((unsigned)disk_car->pwrite(disk_car, buffer, cluster_size, partition->part_offset + (start_data + (uint64_t)(cluster - 2) * sectors_per_cluster) * disk_car->sector_size) != cluster_size)
@@ -683,7 +695,7 @@ cluster=next_cluster;
}
#ifdef DEBUG
{
- file_data_t *dir_list;
+ file_info_t *dir_list;
dir_list=dir_fat_aux(buffer, cluster_size, cluster_size, 0);
dir_aff_log(NULL, dir_list);
delete_list_file(dir_list);
@@ -807,10 +819,13 @@ static int analyse_dir_entries(disk_t *disk_car,const partition_t *partition, co
static int analyse_dir_entries2(disk_t *disk_car,const partition_t *partition, const unsigned int reserved, const unsigned int fat_length,const int verbose, unsigned int root_size_max,const upart_type_t upart_type, const unsigned int fats)
{
- file_data_t *dir_list=NULL;
- file_data_t *current_file;
unsigned char *buffer_dir;
unsigned int root_dir_size;
+ static file_info_t dir_list = {
+ .list = TD_LIST_HEAD_INIT(dir_list.list),
+ .name = NULL
+ };
+ struct td_list_head *file_walker = NULL;
if(root_size_max==0)
{
root_size_max=4096;
@@ -825,61 +840,64 @@ static int analyse_dir_entries2(disk_t *disk_car,const partition_t *partition, c
return 0;
}
{
- uint64_t start_data=reserved+fats*fat_length+(root_size_max+(disk_car->sector_size/32)-1)/(disk_car->sector_size/32);
- unsigned int sectors_per_cluster=calcul_sectors_per_cluster(upart_type,partition->part_size/disk_car->sector_size-start_data,fat_length,disk_car->sector_size);
- dir_list=dir_fat_aux(buffer_dir, root_dir_size, sectors_per_cluster*disk_car->sector_size,
- (partition->upart_type==UP_FAT12?FLAG_LIST_MASK12:FLAG_LIST_MASK16));
+ const uint64_t start_data=reserved+fats*fat_length+(root_size_max+(disk_car->sector_size/32)-1)/(disk_car->sector_size/32);
+ const unsigned int sectors_per_cluster=calcul_sectors_per_cluster(upart_type,partition->part_size/disk_car->sector_size-start_data,fat_length,disk_car->sector_size);
+ dir_fat_aux(buffer_dir, root_dir_size, sectors_per_cluster*disk_car->sector_size,
+ (partition->upart_type==UP_FAT12?FLAG_LIST_MASK12:FLAG_LIST_MASK16), &dir_list);
}
if(verbose>1)
{
- dir_aff_log(NULL, dir_list);
+ dir_aff_log(NULL, &dir_list);
}
- for(current_file=dir_list;(current_file!=NULL)&&(LINUX_S_ISDIR(current_file->st_mode)==0);current_file=current_file->next);
- if(current_file!=NULL)
+ td_list_for_each(file_walker, &dir_list.list)
{
- unsigned long int new_inode=current_file->st_ino;
- unsigned int dir_entries;
- if(verbose>1)
- {
- log_verbose("Directory %s used inode=%lu\n",current_file->name,new_inode);
- }
- for(dir_entries=(disk_car->sector_size/32);dir_entries<=root_size_max;dir_entries+=(disk_car->sector_size/32))
+ const file_info_t *current_file=td_list_entry(file_walker, file_info_t, list);
+ if(LINUX_S_ISDIR(current_file->st_mode) && (current_file->status&FILE_STATUS_DELETED)==0)
{
- uint64_t start_data=reserved+fats*fat_length+(dir_entries+(disk_car->sector_size/32)-1)/(disk_car->sector_size/32);
- unsigned int sectors_per_cluster=calcul_sectors_per_cluster(upart_type,partition->part_size/disk_car->sector_size-start_data,fat_length,disk_car->sector_size);
+ const unsigned long int new_inode=current_file->st_ino;
+ unsigned int dir_entries;
if(verbose>1)
{
- log_verbose("dir_entries %u, sectors_per_cluster %u\n",dir_entries,sectors_per_cluster);
+ log_verbose("Directory %s used inode=%lu\n",current_file->name,new_inode);
}
- if((unsigned)disk_car->pread(disk_car, buffer_dir, disk_car->sector_size,
- partition->part_offset + (start_data + (uint64_t)(new_inode - 2) * sectors_per_cluster) * disk_car->sector_size) == disk_car->sector_size)
+ for(dir_entries=disk_car->sector_size/32;
+ dir_entries <= root_size_max;
+ dir_entries+=disk_car->sector_size/32)
{
- if((memcmp(&buffer_dir[0],". ",8+3)==0)&&(memcmp(&buffer_dir[0x20],".. ",8+3)==0))
- {
- unsigned long int cluster=(buffer_dir[0*0x20+0x15]<<24)+(buffer_dir[0*0x20+0x14]<<16)+
- (buffer_dir[0*0x20+0x1B]<<8)+buffer_dir[0*0x20+0x1A];
- unsigned long int cluster_prev=(buffer_dir[1*0x20+0x15]<<24)+(buffer_dir[1*0x20+0x14]<<16)+
- (buffer_dir[1*0x20+0x1B]<<8)+buffer_dir[1*0x20+0x1A];
- if(verbose>1)
- {
- log_verbose("Cluster %lu, directory .. found link to %lu\n",cluster,cluster_prev);
- }
- if(cluster_prev==0 && cluster==new_inode)
- {
- free(buffer_dir);
- delete_list_file(dir_list);
- return ((dir_entries+(disk_car->sector_size/32)-1)/(disk_car->sector_size/32))*(disk_car->sector_size/32);
- }
- }
+ const uint64_t start_data=reserved+fats*fat_length+(dir_entries+(disk_car->sector_size/32)-1)/(disk_car->sector_size/32);
+ const unsigned int sectors_per_cluster=calcul_sectors_per_cluster(upart_type,partition->part_size/disk_car->sector_size-start_data,fat_length,disk_car->sector_size);
+ if(verbose>1)
+ {
+ log_verbose("dir_entries %u, sectors_per_cluster %u\n",dir_entries,sectors_per_cluster);
+ }
+ if((unsigned)disk_car->pread(disk_car, buffer_dir, disk_car->sector_size,
+ partition->part_offset + (start_data + (uint64_t)(new_inode - 2) * sectors_per_cluster) * disk_car->sector_size) == disk_car->sector_size)
+ {
+ if(memcmp(&buffer_dir[0],". ",8+3)==0 &&
+ memcmp(&buffer_dir[0x20],".. ",8+3)==0)
+ {
+ const unsigned long int cluster=(buffer_dir[0*0x20+0x15]<<24)+(buffer_dir[0*0x20+0x14]<<16)+
+ (buffer_dir[0*0x20+0x1B]<<8)+buffer_dir[0*0x20+0x1A];
+ const unsigned long int cluster_prev=(buffer_dir[1*0x20+0x15]<<24)+(buffer_dir[1*0x20+0x14]<<16)+
+ (buffer_dir[1*0x20+0x1B]<<8)+buffer_dir[1*0x20+0x1A];
+ if(verbose>1)
+ {
+ log_verbose("Cluster %lu, directory .. found link to %lu\n",cluster,cluster_prev);
+ }
+ if(cluster_prev==0 && cluster==new_inode)
+ {
+ free(buffer_dir);
+ delete_list_file(&dir_list);
+ return ((dir_entries+(disk_car->sector_size/32)-1)/(disk_car->sector_size/32))*(disk_car->sector_size/32);
+ }
+ }
+ }
}
}
}
- else
- {
- log_warning("No directory found\n");
- }
+ log_warning("No directory found\n");
free(buffer_dir);
- delete_list_file(dir_list);
+ delete_list_file(&dir_list);
return root_size_max;
}
diff --git a/src/fat_dir.c b/src/fat_dir.c
index f63298b..df12027 100644
--- a/src/fat_dir.c
+++ b/src/fat_dir.c
@@ -55,10 +55,10 @@ struct fat_dir_struct
};
-static file_data_t *fat1x_rootdir(disk_t *disk_car, const partition_t *partition, const dir_data_t *dir_data, const struct fat_boot_sector*fat_header);
-static file_data_t *fat_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int first_cluster);
+static int fat1x_rootdir(disk_t *disk_car, const partition_t *partition, const dir_data_t *dir_data, const struct fat_boot_sector*fat_header, file_info_t *dir_list);
+static int fat_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int first_cluster, file_info_t *dir_list);
static inline void fat16_towchar(wchar_t *dst, const uint8_t *src, size_t len);
-static int fat_copy(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const file_data_t *file);
+static int fat_copy(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const file_info_t *file);
static void dir_partition_fat_close(dir_data_t *dir_data);
static inline void fat16_towchar(wchar_t *dst, const uint8_t *src, size_t len)
@@ -69,13 +69,11 @@ static inline void fat16_towchar(wchar_t *dst, const uint8_t *src, size_t len)
}
}
-file_data_t *dir_fat_aux(const unsigned char*buffer, const unsigned int size, const unsigned int cluster_size, const unsigned int param)
+int dir_fat_aux(const unsigned char*buffer, const unsigned int size, const unsigned int cluster_size, const unsigned int param, file_info_t *dir_list)
{
const struct msdos_dir_entry *de=(const struct msdos_dir_entry*)buffer;
wchar_t unicode[1000];
unsigned char long_slots;
- file_data_t *dir_list=NULL;
- file_data_t *current_file=NULL;
unsigned int status;
unsigned int inode;
int utf8=1;
@@ -106,7 +104,7 @@ ParseLongDeleted:
while (1)
{
if((const void*)de>=(const void*)(buffer+size))
- goto EODir;
+ return 0;
ds = (const struct msdos_dir_slot *) de;
if(de->name[0] != (int8_t) DELETED_FLAG)
goto GetNew;
@@ -186,7 +184,7 @@ ParseLong:
}
de++;
if((const void*)de>=(const void*)(buffer+size))
- goto EODir;
+ return 0;
if (slot == 0)
break;
ds = (const struct msdos_dir_slot *) de;
@@ -245,8 +243,8 @@ RecEnd:
{
status=FILE_STATUS_DELETED;
if((de->attr&ATTR_DIR)==ATTR_DIR &&
- ((dir_list==NULL && unicode[1]=='\0') ||
- (dir_list!=NULL && dir_list->next==NULL && unicode[1]=='.' && unicode[2]=='\0')))
+ ((td_list_empty(&dir_list->list) && unicode[1]=='\0') ||
+ (!td_list_empty(&dir_list->list) && dir_list->list.next==dir_list->list.prev && unicode[1]=='.' && unicode[2]=='\0')))
unicode[0]='.'; /* "." and ".." are the first two entries */
else
unicode[0]='_';
@@ -256,12 +254,13 @@ RecEnd:
!(de->attr & ATTR_VOLUME))
{
if(unicode[0]==0)
- return dir_list;
+ return 0;
if((int8_t) unicode[0] != (int8_t) DELETED_FLAG)
{
unsigned int i,o;
- file_data_t *new_file=(file_data_t *)MALLOC(sizeof(*new_file));
- for(i=0,o=0; unicode[i]!=0 && o<sizeof(new_file->name)-1; i++)
+ file_info_t *new_file=(file_info_t *)MALLOC(sizeof(*new_file));
+ new_file->name=(char*)MALLOC(DIR_NAME_LEN);
+ for(i=0,o=0; unicode[i]!=0 && o<DIR_NAME_LEN-1; i++)
{
if(utf8 && unicode[i]>0x7f)
{
@@ -290,22 +289,15 @@ RecEnd:
// new_file->st_blksize=cluster_size;
new_file->td_atime=new_file->td_ctime=new_file->td_mtime=date_dos2unix(le16(de->time),le16(de->date));
new_file->status=status;
- new_file->prev=current_file;
- new_file->next=NULL;
/* log_debug("fat: new file %s de=%p size=%u\n",new_file->name,de,le32(de->size)); */
- if(current_file!=NULL)
- current_file->next=new_file;
- else
- dir_list=new_file;
- current_file=new_file;
+ td_list_add_tail(&new_file->list, &dir_list->list);
}
}
de++;
if((const void *)de<(const void *)(buffer+size-1) &&
de->name[0] != (int8_t) 0)
goto GetNew;
-EODir:
- return dir_list;
+ return 0;
}
enum {FAT_FOLLOW_CLUSTER, FAT_NEXT_FREE_CLUSTER, FAT_NEXT_CLUSTER};
@@ -321,7 +313,7 @@ static int is_EOC(const unsigned int cluster, const upart_type_t upart_type)
}
#define NBR_CLUSTER_MAX 30
-static file_data_t *fat_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int first_cluster)
+static int fat_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int first_cluster, file_info_t *dir_list)
{
const struct fat_dir_struct *ls=(const struct fat_dir_struct*)dir_data->private_dir_data;
const struct fat_boot_sector*fat_header=ls->boot_sector;
@@ -329,26 +321,25 @@ static file_data_t *fat_dir(disk_t *disk_car, const partition_t *partition, dir_
if(fat_header->sectors_per_cluster<1)
{
log_error("FAT: Can't list files, bad cluster size.\n");
- return NULL;
+ return -1;
}
if(fat_sector_size(fat_header)==0)
{
log_error("FAT: Can't list files, bad sector size.\n");
- return NULL;
+ return -1;
}
if(cluster==0)
{
if(partition->upart_type!=UP_FAT32)
- return fat1x_rootdir(disk_car, partition, dir_data, fat_header);
+ return fat1x_rootdir(disk_car, partition, dir_data, fat_header, dir_list);
if(le32(fat_header->root_cluster)<2)
{
log_error("FAT32: Can't list files, bad root cluster.\n");
- return NULL;
+ return -1;
}
cluster=le32(fat_header->root_cluster);
}
{
- file_data_t *dir_list=NULL;
const unsigned int cluster_size=fat_header->sectors_per_cluster * fat_sector_size(fat_header);
unsigned char *buffer_dir=(unsigned char *)MALLOC(cluster_size*NBR_CLUSTER_MAX);
unsigned int nbr_cluster;
@@ -415,23 +406,23 @@ static file_data_t *fat_dir(disk_t *disk_car, const partition_t *partition, dir_
}
}
if(nbr_cluster>0)
- dir_list=dir_fat_aux(buffer_dir, cluster_size*nbr_cluster, cluster_size, dir_data->param);
+ dir_fat_aux(buffer_dir, cluster_size*nbr_cluster, cluster_size, dir_data->param, dir_list);
free(buffer_dir);
- return dir_list;
+ return 0;
}
}
-static file_data_t *fat1x_rootdir(disk_t *disk_car, const partition_t *partition, const dir_data_t *dir_data, const struct fat_boot_sector*fat_header)
+static int fat1x_rootdir(disk_t *disk_car, const partition_t *partition, const dir_data_t *dir_data, const struct fat_boot_sector*fat_header, file_info_t *dir_list)
{
const unsigned int root_size=(get_dir_entries(fat_header)*32+disk_car->sector_size-1)/disk_car->sector_size*disk_car->sector_size;
if(root_size==0)
- return NULL;
+ return -1;
if(dir_data->verbose>1)
{
log_trace("fat1x_rootdir root_size=%u sectors\n",root_size/disk_car->sector_size);
}
{
- file_data_t *res=NULL;
+ int res;
uint64_t start;
unsigned char *buffer_dir;
buffer_dir=(unsigned char*)MALLOC(root_size);
@@ -441,7 +432,7 @@ static file_data_t *fat1x_rootdir(disk_t *disk_car, const partition_t *partition
log_error("FAT 1x: Can't read root directory.\n");
/* Don't return yet, it may have been a partial read */
}
- res=dir_fat_aux(buffer_dir, root_size, fat_header->sectors_per_cluster * fat_sector_size(fat_header), dir_data->param);
+ res=dir_fat_aux(buffer_dir, root_size, fat_header->sectors_per_cluster * fat_sector_size(fat_header), dir_data->param, dir_list);
free(buffer_dir);
return res;
}
@@ -486,7 +477,7 @@ static void dir_partition_fat_close(dir_data_t *dir_data)
free(ls);
}
-static int fat_copy(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const file_data_t *file)
+static int fat_copy(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const file_info_t *file)
{
char *new_file;
FILE *f_out;
diff --git a/src/fat_dir.h b/src/fat_dir.h
index 3c80083..4b3c384 100644
--- a/src/fat_dir.h
+++ b/src/fat_dir.h
@@ -23,7 +23,7 @@
extern "C" {
#endif
-file_data_t *dir_fat_aux(const unsigned char*buffer, const unsigned int size, const unsigned int cluster_size, const unsigned int param);
+int dir_fat_aux(const unsigned char*buffer, const unsigned int size, const unsigned int cluster_size, const unsigned int param, file_info_t *dir_list);
int dir_partition_fat_init(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const int verbose);
#ifdef __cplusplus
diff --git a/src/fat_unformat.c b/src/fat_unformat.c
index ebc4119..a10528b 100644
--- a/src/fat_unformat.c
+++ b/src/fat_unformat.c
@@ -131,7 +131,7 @@ static int pfind_sectors_per_cluster(disk_t *disk, partition_t *partition, const
return find_sectors_per_cluster_aux(sector_cluster,nbr_subdir,sectors_per_cluster,offset_org,verbose,partition->part_size/disk->sector_size, UP_UNK);
}
-static int fat_copy_file(disk_t *disk, const partition_t *partition, const unsigned int cluster_size, const uint64_t start_data, const char *recup_dir, const unsigned int dir_num, const unsigned int inode_num, const file_data_t *file)
+static int fat_copy_file(disk_t *disk, const partition_t *partition, const unsigned int cluster_size, const uint64_t start_data, const char *recup_dir, const unsigned int dir_num, const unsigned int inode_num, const file_info_t *file)
{
char *new_file;
FILE *f_out;
@@ -241,36 +241,43 @@ static int fat_unformat_aux(struct ph_param *params, const struct ph_options *op
memcmp(buffer, ". ", 8+3)==0 &&
memcmp(&buffer[0x20], ".. ", 8+3)==0)
{
- file_data_t *dir_list;
- dir_list=dir_fat_aux(buffer,read_size,0,0);
- if(dir_list!=NULL)
+ static file_info_t dir_list = {
+ .list = TD_LIST_HEAD_INIT(dir_list.list),
+ .name = NULL
+ };
+ dir_fat_aux(buffer,read_size,0,0, &dir_list);
+ if(!td_list_empty(&dir_list.list))
{
+ struct td_list_head *file_walker = NULL;
unsigned int dir_inode=0;
- const file_data_t *current_file;
+ unsigned int nbr;
+ int stop=0;
log_info("Sector %llu\n", (long long unsigned)offset/disk->sector_size);
- dir_aff_log(NULL, dir_list);
+ dir_aff_log(NULL, &dir_list);
del_search_space(list_search_space, offset, offset + cluster_size -1);
- current_file=dir_list;
- while(current_file!=NULL)
+ for(file_walker=dir_list.list.next, nbr=0;
+ stop==0 && file_walker!=&dir_list.list;
+ file_walker=file_walker->next, nbr++)
{
+ const file_info_t *current_file=td_list_entry(file_walker, file_info_t, list);
if(current_file->st_ino==1 ||
current_file->st_ino >= no_of_cluster+2)
- current_file=NULL;
+ stop=1;
else if(LINUX_S_ISDIR(current_file->st_mode)!=0)
{
if(strcmp(current_file->name,"..")==0)
{
- if(current_file!=dir_list->next)
- current_file=NULL;
+ if(nbr!=1)
+ stop=1;
}
else if(current_file->st_ino==0)
- current_file=NULL;
+ stop=1;
else if(strcmp(current_file->name,".")==0)
{
- if(current_file==dir_list)
+ if(nbr==0)
dir_inode=current_file->st_ino;
else
- current_file=NULL;
+ stop=1;
}
else
{
@@ -301,12 +308,10 @@ static int fat_unformat_aux(struct ph_param *params, const struct ph_options *op
}
}
else
- current_file=NULL;
+ stop=1;
}
- if(current_file!=NULL)
- current_file=current_file->next;
}
- delete_list_file(dir_list);
+ delete_list_file(&dir_list);
}
}
buffer+=cluster_size;
diff --git a/src/filegen.h b/src/filegen.h
index b9ea6c4..436ae18 100644
--- a/src/filegen.h
+++ b/src/filegen.h
@@ -113,9 +113,9 @@ typedef struct
typedef struct
{
+ file_check_t file_checks[256];
struct td_list_head list;
unsigned int offset;
- file_check_t file_checks[256];
} file_check_list_t;
#define NL_BARENL (1 << 0)
diff --git a/src/ntfs_dir.c b/src/ntfs_dir.c
index 779b6df..d606c6f 100644
--- a/src/ntfs_dir.c
+++ b/src/ntfs_dir.c
@@ -71,6 +71,7 @@
#include "common.h"
#include "intrf.h"
#include "ntfs.h"
+#include "list.h"
#include "dir.h"
#include "ntfs_dir.h"
#include "ntfs_utl.h"
@@ -104,8 +105,8 @@ extern int ntfs_readdir(ntfs_inode *dir_ni, s64 *pos,
static int ntfs_td_list_entry( struct ntfs_dir_struct *ls, const ntfschar *name,
const int name_len, const int name_type, const s64 pos,
const MFT_REF mref, const unsigned dt_type);
-static file_data_t *ntfs_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int cluster);
-static int ntfs_copy(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const file_data_t *file);
+static int ntfs_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int cluster, file_info_t *dir_list);
+static int ntfs_copy(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const file_info_t *file);
static void dir_partition_ntfs_close(dir_data_t *dir_data);
/**
@@ -194,17 +195,16 @@ static int ntfs_td_list_entry( struct ntfs_dir_struct *ls, const ntfschar *name
{
ntfs_inode *ni;
ntfs_attr_search_ctx *ctx_si = NULL;
- file_data_t *new_file=NULL;
+ file_info_t *new_file=NULL;
result = -1; /* Everything else is bad */
ni = ntfs_inode_open(ls->vol, mref);
if (!ni)
goto release;
- new_file=(file_data_t *)MALLOC(sizeof(*new_file));
+ new_file=(file_info_t*)MALLOC(sizeof(*new_file));
new_file->status=0;
- new_file->prev=ls->current_file;
- new_file->next=NULL;
+ td_list_add_tail(&new_file->list, &ls->dir_list->list);
new_file->st_ino=MREF(mref);
new_file->st_uid=0;
new_file->st_gid=0;
@@ -232,16 +232,10 @@ static int ntfs_td_list_entry( struct ntfs_dir_struct *ls, const ntfschar *name
ntfs_attr_search_ctx *ctx = NULL;
if (dt_type == NTFS_DT_DIR)
{
- snprintf(new_file->name, sizeof(new_file->name), "%s", filename);
+ new_file->name=strdup(filename);
new_file->st_mode = LINUX_S_IFDIR| LINUX_S_IRUGO | LINUX_S_IXUGO;
new_file->st_size=0;
- new_file->prev=ls->current_file;
- new_file->next=NULL;
- if(ls->current_file!=NULL)
- ls->current_file->next=new_file;
- else
- ls->dir_list=new_file;
- ls->current_file=new_file;
+ td_list_add_tail(&new_file->list, &ls->dir_list->list);
first=0;
}
ctx = ntfs_attr_get_search_ctx(ni, ni->mrec);
@@ -255,8 +249,8 @@ static int ntfs_td_list_entry( struct ntfs_dir_struct *ls, const ntfschar *name
continue;
if(first==0)
{
- const file_data_t *old_file=new_file;
- new_file=(file_data_t *)MALLOC(sizeof(*new_file));
+ const file_info_t *old_file=new_file;
+ new_file=(file_info_t *)MALLOC(sizeof(*new_file));
memcpy(new_file, old_file, sizeof(*new_file));
}
new_file->st_mode = LINUX_S_IFREG | LINUX_S_IRUGO;
@@ -265,30 +259,24 @@ static int ntfs_td_list_entry( struct ntfs_dir_struct *ls, const ntfschar *name
{
char *stream_name=NULL;
new_file->status=FILE_STATUS_ADS;
+ new_file->name = (char *)MALLOC(MAX_PATH);
if (ntfs_ucstombs((ntfschar *) ((char *) rec + le16_to_cpu(rec->name_offset)),
rec->name_length, &stream_name, 0) < 0)
{
log_error("ERROR: Cannot translate name into current locale.\n");
- snprintf(new_file->name, sizeof(new_file->name), "%s:???", filename);
+ snprintf(new_file->name, MAX_PATH, "%s:???", filename);
}
else
{
- snprintf(new_file->name, sizeof(new_file->name), "%s:%s", filename, stream_name);
+ snprintf(new_file->name, MAX_PATH, "%s:%s", filename, stream_name);
}
free(stream_name);
}
else
{
- snprintf(new_file->name,sizeof(new_file->name), "%s", filename);
+ new_file->name=strdup(filename);
}
- new_file->prev=ls->current_file;
- new_file->next=NULL;
- if(ls->current_file!=NULL)
- ls->current_file->next=new_file;
- else
- ls->dir_list=new_file;
- ls->current_file=new_file;
-
+ td_list_add_tail(&new_file->list, &ls->dir_list->list);
first=0;
}
ntfs_attr_put_search_ctx(ctx);
@@ -305,18 +293,17 @@ free:
return result;
}
-static file_data_t *ntfs_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int cluster)
+static int ntfs_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int cluster, file_info_t *dir_list)
{
ntfs_inode *inode;
s64 pos;
struct ntfs_dir_struct *ls=(struct ntfs_dir_struct*)dir_data->private_dir_data;
- ls->dir_list=NULL;
- ls->current_file=NULL;
+ ls->dir_list=dir_list;
inode = ntfs_inode_open (ls->vol, cluster);
if (!inode) {
log_error("ntfs_dir: ntfs_inode_open failed\n");
- return NULL;
+ return -1;
}
/*
@@ -334,12 +321,12 @@ static file_data_t *ntfs_dir(disk_t *disk_car, const partition_t *partition, dir
log_critical("ntfs_readdir BUG not MFT_RECORD_IS_DIRECTORY\n");
/* Finished with the inode; release it. */
ntfs_inode_close(inode);
- return ls->dir_list;
+ return 0;
}
enum { bufsize = 4096 };
-static int ntfs_copy(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const file_data_t *file)
+static int ntfs_copy(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const file_info_t *file)
{
const unsigned long int first_inode=file->st_ino;
ntfs_inode *inode;
@@ -519,7 +506,6 @@ int dir_partition_ntfs_init(disk_t *disk_car, const partition_t *partition, dir_
{
struct ntfs_dir_struct *ls=(struct ntfs_dir_struct *)MALLOC(sizeof(*ls));
ls->dir_list=NULL;
- ls->current_file=NULL;
ls->vol=vol;
ls->my_data=my_data;
ls->dir_data=dir_data;
diff --git a/src/ntfs_fix.c b/src/ntfs_fix.c
index 24d3298..432954b 100644
--- a/src/ntfs_fix.c
+++ b/src/ntfs_fix.c
@@ -171,13 +171,16 @@ int repair_MFT(disk_t *disk_car, partition_t *partition, const int verbose, cons
}
if(res1==0)
{
- file_data_t *dir_list;
- dir_list=dir_data.get_dir(disk_car,partition,&dir_data,dir_data.current_inode);
- if(dir_list!=NULL)
+ static file_info_t dir_list = {
+ .list = TD_LIST_HEAD_INIT(dir_list.list),
+ .name = NULL
+ };
+ dir_data.get_dir(disk_car,partition,&dir_data,dir_data.current_inode, &dir_list);
+ if(!td_list_empty(&dir_list.list))
{
log_info("NTFS listing using MFT:\n");
- dir_aff_log(&dir_data, dir_list);
- if(delete_list_file(dir_list)>2)
+ dir_aff_log(&dir_data, &dir_list);
+ if(delete_list_file(&dir_list)>2)
res1++;
}
dir_data.close(&dir_data);
@@ -188,13 +191,16 @@ int repair_MFT(disk_t *disk_car, partition_t *partition, const int verbose, cons
res2=dir_partition_ntfs_init(disk_car,partition,&dir_data,verbose);
if(res2==0)
{
- file_data_t *dir_list;
- dir_list=dir_data.get_dir(disk_car,partition,&dir_data,dir_data.current_inode);
- if(dir_list!=NULL)
+ static file_info_t dir_list = {
+ .list = TD_LIST_HEAD_INIT(dir_list.list),
+ .name = NULL
+ };
+ dir_data.get_dir(disk_car,partition,&dir_data,dir_data.current_inode, &dir_list);
+ if(!td_list_empty(&dir_list.list))
{
log_info("NTFS listing using MFT mirror:\n");
- dir_aff_log(&dir_data, dir_list);
- if(delete_list_file(dir_list)>2)
+ dir_aff_log(&dir_data, &dir_list);
+ if(delete_list_file(&dir_list)>2)
res2++;
}
dir_data.close(&dir_data);
diff --git a/src/ntfs_inc.h b/src/ntfs_inc.h
index c8786b7..2f37110 100644
--- a/src/ntfs_inc.h
+++ b/src/ntfs_inc.h
@@ -21,8 +21,7 @@
*/
#if defined(HAVE_LIBNTFS) || defined(HAVE_LIBNTFS3G)
struct ntfs_dir_struct {
- file_data_t *dir_list;
- file_data_t *current_file;
+ file_info_t *dir_list;
ntfs_volume *vol;
my_data_t *my_data;
dir_data_t *dir_data;
diff --git a/src/ntfs_udl.c b/src/ntfs_udl.c
index 9f3c4eb..b0aec9f 100644
--- a/src/ntfs_udl.c
+++ b/src/ntfs_udl.c
@@ -1668,7 +1668,7 @@ int ntfs_undelete_part(disk_t *disk_car, const partition_t *partition, const int
struct ntfs_dir_struct *ls=(struct ntfs_dir_struct *)dir_data.private_dir_data;
scan_disk(ls->vol, &dir_list);
ntfs_undelete_menu(disk_car, partition, &dir_data, &dir_list, current_cmd);
- delete_list_file_info(&dir_list.list);
+ delete_list_file(&dir_list);
dir_data.close(&dir_data);
}
break;
diff --git a/src/phrecn.c b/src/phrecn.c
index ede75c8..eb62a29 100644
--- a/src/phrecn.c
+++ b/src/phrecn.c
@@ -311,14 +311,17 @@ static int photorec_aux(struct ph_param *params, const struct ph_options *option
if(file_recovery.file_stat->file_hint==&file_hint_dir && options->verbose > 0)
{ /* FAT directory found, list the file */
- file_data_t *dir_list;
- dir_list=dir_fat_aux(buffer,read_size,0,0);
- if(dir_list!=NULL)
+ static file_info_t dir_list = {
+ .list = TD_LIST_HEAD_INIT(dir_list.list),
+ .name = NULL
+ };
+ dir_fat_aux(buffer,read_size,0,0, &dir_list);
+ if(!td_list_empty(&dir_list.list))
{
log_info("Sector %lu\n",
(unsigned long)(file_recovery.location.start/params->disk->sector_size));
- dir_aff_log(NULL, dir_list);
- delete_list_file(dir_list);
+ dir_aff_log(NULL, &dir_list);
+ delete_list_file(&dir_list);
}
}
}
diff --git a/src/rfs_dir.c b/src/rfs_dir.c
index 81882df..f290a20 100644
--- a/src/rfs_dir.c
+++ b/src/rfs_dir.c
@@ -60,13 +60,12 @@
#include "reiserfs/reiserfs.h"
struct rfs_dir_struct {
- file_data_t *dir_list;
- file_data_t *current_file;
+ file_info_t *dir_list;
reiserfs_fs_t *current_fs;
dal_t *dal;
int flags;
};
-static file_data_t *reiser_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int cluster);
+static int reiser_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int cluster, file_info_t *dir_list);
static void dir_partition_reiser_close(dir_data_t *dir_data);
#ifdef HAVE_STRUCT_DAL_OPS_DEV
@@ -419,17 +418,16 @@ blk_t dal_len(dal_t *dal) {
return 0;
}
-static file_data_t *reiser_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int cluster)
+static int reiser_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int cluster, file_info_t *dir_list)
{
struct rfs_dir_struct *ls=(struct rfs_dir_struct*)dir_data->private_dir_data;
reiserfs_dir_t *dir;
reiserfs_dir_entry_t entry;
- ls->dir_list=NULL;
- ls->current_file=NULL;
+ ls->dir_list=dir_list;
if (!(dir = reiserfs_dir_open(ls->current_fs, dir_data->current_directory))) {
screen_buffer_add("Couldn't open dir\n");
log_error("Couldn't open dir\n");
- return NULL;
+ return -1;
}
while (reiserfs_dir_read(dir, &entry))
{
@@ -441,14 +439,12 @@ static file_data_t *reiser_dir(disk_t *disk_car, const partition_t *partition, d
if((entity=reiserfs_object_create(ls->current_fs,name,1)))
{
unsigned int thislen;
- file_data_t *new_file=(file_data_t *)MALLOC(sizeof(*new_file));
+ file_info_t *new_file=(file_info_t *)MALLOC(sizeof(*new_file));
thislen=(MAX_NAME_LEN(DEFAULT_BLOCK_SIZE)<DIR_NAME_LEN?MAX_NAME_LEN(DEFAULT_BLOCK_SIZE):DIR_NAME_LEN);
memcpy(new_file->name,entry.de_name,thislen);
new_file->name[thislen-1]='\0';
new_file->status=0;
- new_file->prev=ls->current_file;
- new_file->next=NULL;
new_file->st_ino=entity->stat.st_ino;
new_file->st_mode=entity->stat.st_mode;
// new_file->st_nlink=entity->stat.st_nlink;
@@ -460,15 +456,11 @@ static file_data_t *reiser_dir(disk_t *disk_car, const partition_t *partition, d
new_file->td_mtime=entity->stat.st_mtime;
new_file->td_ctime=entity->stat.st_ctime;
reiserfs_object_free(entity);
- if(ls->current_file)
- ls->current_file->next=new_file;
- else
- ls->dir_list=new_file;
- ls->current_file=new_file;
+ td_list_add_tail(&new_file->list, &dir_list->list);
}
}
reiserfs_dir_close(dir);
- return ls->dir_list;
+ return 0;
}
static void dir_partition_reiser_close(dir_data_t *dir_data)
@@ -479,7 +471,7 @@ static void dir_partition_reiser_close(dir_data_t *dir_data)
free(ls);
}
-static int reiser_copy(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const file_data_t *file)
+static int reiser_copy(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const file_info_t *file)
{
reiserfs_file_t *in;
FILE *f_out;
@@ -593,7 +585,6 @@ int dir_partition_reiser_init(disk_t *disk_car, const partition_t *partition, di
{
struct rfs_dir_struct *ls=(struct rfs_dir_struct *)MALLOC(sizeof(*ls));
ls->dir_list=NULL;
- ls->current_file=NULL;
ls->current_fs=fs;
ls->dal=dal;
ls->flags = 0; /*DIRENT_FLAG_INCLUDE_EMPTY; */