diff options
author | Christophe Grenier <[email protected]> | 2008-11-16 12:45:19 +0100 |
---|---|---|
committer | Christophe Grenier <[email protected]> | 2008-11-16 12:45:19 +0100 |
commit | 8453cfff02206ad932e8ddd3c24b34aa7c42af62 (patch) | |
tree | 4ba3e71e551023fc1c73f75483f17aa6adcfc7cd | |
parent | af127dc90c383786b598d8fce215aa8c4d03b233 (diff) |
When copying filenames, try to deal more efficently with filename restriction
-rw-r--r-- | src/common.c | 210 | ||||
-rw-r--r-- | src/common.h | 2 | ||||
-rw-r--r-- | src/dir.c | 349 | ||||
-rw-r--r-- | src/dir.h | 5 | ||||
-rw-r--r-- | src/ext2_dir.c | 23 | ||||
-rw-r--r-- | src/fat_dir.c | 70 | ||||
-rw-r--r-- | src/ntfs_dir.c | 3 | ||||
-rw-r--r-- | src/ntfs_udl.c | 16 |
8 files changed, 393 insertions, 285 deletions
diff --git a/src/common.c b/src/common.c index a111eb88..5eaa1cbf 100644 --- a/src/common.c +++ b/src/common.c @@ -155,214 +155,4 @@ void set_part_name(partition_t *partition,const char *src,const int max_size) partition->fsname[i--]='\0'; } -#ifdef DJGPP -static inline unsigned char convert_char_dos(unsigned char car) -{ - if(car<0x20) - return '_'; - switch(car) - { - /* Forbidden */ - case '<': - case '>': - case ':': - case '"': - /* case '/': subdirectory */ - case '\\': - case '|': - case '?': - case '*': - /* Not recommanded */ - case '[': - case ']': - case ';': - case ',': - case '+': - case '=': - return '_'; - } - /* 'a' */ - if(car>=224 && car<=230) - return 'a'; - /* 'c' */ - if(car==231) - return 'c'; - /* 'e' */ - if(car>=232 && car<=235) - return 'e'; - /* 'i' */ - if(car>=236 && car<=239) - return 'n'; - /* n */ - if(car==241) - return 'n'; - /* 'o' */ - if((car>=242 && car<=246) || car==248) - return 'o'; - /* 'u' */ - if(car>=249 && car<=252) - return 'u'; - /* 'y' */ - if(car>=253) - return 'y'; - return car; -} - -static unsigned int filename_convert_dos(char *dst, const char*src, const unsigned int n) -{ - unsigned int i; - for(i=0;i<n-1 && src[i]!='\0';i++) - dst[i]=convert_char_dos(src[i]); - while(i>0 && (dst[i-1]==' '||dst[i-1]=='.')) - i--; - if(i==0 && (dst[i]==' '||dst[i]=='.')) - dst[i++]='_'; - dst[i]='\0'; - return i; -} -#endif - -#if defined(__CYGWIN__) || defined(__MINGW32__) -static inline unsigned char convert_char_win(unsigned char car) -{ - if(car<0x20) - return '_'; - switch(car) - { - /* Forbidden */ - case '<': - case '>': - case ':': - case '"': - /* case '/': subdirectory */ - case '\\': - case '|': - case '?': - case '*': - /* Not recommanded */ - case '[': - case ']': - case ';': - case ',': - case '+': - case '=': - return '_'; - } - return car; -} - -static unsigned int filename_convert_win(char *dst, const char*src, const unsigned int n) -{ - unsigned int i; - for(i=0;i<n-1 && src[i]!='\0';i++) - dst[i]=convert_char_win(src[i]); - while(i>0 && (dst[i-1]==' '||dst[i-1]=='.')) - i--; - if(i==0 && (dst[i]==' '||dst[i]=='.')) - dst[i++]='_'; - dst[i]='\0'; - return i; -} -#endif - -#if defined(__APPLE__) -static unsigned int filename_convert_mac(char *dst, const char*src, const unsigned int n) -{ - unsigned int i,j; - const unsigned char *p; /* pointers to actual position in source buffer */ - unsigned char *q; /* pointers to actual position in destination buffer */ - p=(const unsigned char *)src; - q=(unsigned char *)dst; - for(i=0,j=0; (*p)!='\0' && i<n; i++) - { - if((*p & 0x80)==0x00) - { - *q++=*p++; - j++; - } - else if((*p & 0xe0)==0xc0 && (*(p+1) & 0xc0)==0x80) - { - *q++=*p++; - *q++=*p++; - j+=2; - } - else if((*p & 0xf0)==0xe0 && (*(p+1) & 0xc0)==0x80 && (*(p+2) & 0xc0)==0x80) - { - *q++=*p++; - *q++=*p++; - *q++=*p++; - j+=3; - } - else - { - *q++='_'; - p++; - j++; - } - } - *q='\0'; - return j; -} -#endif - -char *gen_local_filename(const char *dir, const char*src) -{ - int l1=strlen(dir); - int l2=(src==NULL?0:strlen(src)); - char *dst=(char *)MALLOC(l1+l2+1); -#if defined(DJGPP) - l1=filename_convert_dos(dst, dir, l1+1); - if(src!=NULL) - filename_convert_dos(dst+l1, src, l2+1); - if(dir[0]!='\0' && dir[1]==':') - dst[1]=':'; -#elif defined(__CYGWIN__) || defined(__MINGW32__) - l1=filename_convert_win(dst, dir, l1+1); - if(src!=NULL) - filename_convert_win(dst+l1, src, l2+1); - if(dir[0]!='\0' && dir[1]==':') - dst[1]=':'; -#elif defined(__APPLE__) - l1=filename_convert_mac(dst, dir, l1+1); - if(src!=NULL) - filename_convert_mac(dst+l1, src, l2+1); -#else - memcpy(dst, dir, l1); - if(src!=NULL) - memcpy(dst+l1, src,l2+1); -#endif - return dst; -} -void create_dir(const char *dir_name, const unsigned int is_dir_name) -{ - /* create all sub-directories */ - char *pos; - char *path=strdup(dir_name); - if(path==NULL) - return; - pos=path+1; - do - { - strcpy(path,dir_name); - pos=strchr(pos+1,'/'); - if(pos!=NULL) - *pos='\0'; - if(pos!=NULL || is_dir_name!=0) - { -#ifdef __CYGWIN__ - if(memcmp(&path[1],":/cygdrive",10)!=0) -#endif -#ifdef HAVE_MKDIR -#ifdef __MINGW32__ - mkdir(path); -#else - mkdir(path, 0775); -#endif -#else -#warning You need a mkdir function! -#endif - } - } while(pos!=NULL); - free(path); -} diff --git a/src/common.h b/src/common.h index ba27329e..a8f91a17 100644 --- a/src/common.h +++ b/src/common.h @@ -425,8 +425,6 @@ int vsnprintf(char *str, size_t size, const char *format, va_list ap); #ifndef HAVE_STRNCASECMP int strncasecmp(const char * s1, const char * s2, size_t len); #endif -void create_dir(const char *dir_name, const unsigned int is_dir_name); -char *gen_local_filename(const char *dir, const char*src); /* * td_min()/td_max() macros that also do * strict type-checking.. See the @@ -39,6 +39,7 @@ #ifdef HAVE_UTIME_H #include <utime.h> #endif +#include <errno.h> #include "common.h" #include "fat.h" #include "lang.h" @@ -175,7 +176,6 @@ int dir_aff_log(const disk_t *disk, const partition_t *partition, const dir_data } for(current_file=dir_list;current_file!=NULL;current_file=current_file->next) { - struct tm *tm_p; char datestr[80]; char str[11]; if((current_file->status&FILE_STATUS_DELETED)!=0) @@ -184,6 +184,7 @@ int dir_aff_log(const disk_t *disk, const partition_t *partition, const dir_data log_info(" "); if(current_file->stat.st_mtime) { + struct tm *tm_p; tm_p = localtime(¤t_file->stat.st_mtime); snprintf(datestr, sizeof(datestr),"%2d-%s-%4d %02d:%02d", @@ -191,7 +192,7 @@ int dir_aff_log(const disk_t *disk, const partition_t *partition, const dir_data 1900 + tm_p->tm_year, tm_p->tm_hour, tm_p->tm_min); /* FIXME: a check using current_file->name will be better */ - if(1900+tm_p->tm_year>=2000 && 1900+tm_p->tm_year<=2010) + if(1900+tm_p->tm_year>=2000 && 1900+tm_p->tm_year<=2012) { test_date=1; } @@ -230,7 +231,6 @@ int log_list_file(const disk_t *disk, const partition_t *partition, const dir_da td_list_for_each(tmp, &list->list) { file_info_t *current_file; - struct tm *tm_p; char datestr[80]; char str[11]; current_file=td_list_entry(tmp, file_info_t, list); @@ -240,6 +240,7 @@ int log_list_file(const disk_t *disk, const partition_t *partition, const dir_da log_info(" "); if(current_file->stat.st_mtime) { + struct tm *tm_p; tm_p = localtime(¤t_file->stat.st_mtime); snprintf(datestr, sizeof(datestr),"%2d-%s-%4d %02d:%02d", @@ -247,7 +248,7 @@ int log_list_file(const disk_t *disk, const partition_t *partition, const dir_da 1900 + tm_p->tm_year, tm_p->tm_hour, tm_p->tm_min); /* FIXME: a check using current_file->name will be better */ - if(1900+tm_p->tm_year>=2000 && 1900+tm_p->tm_year<=2010) + if(1900+tm_p->tm_year>=2000 && 1900+tm_p->tm_year<=2012) { test_date=1; } @@ -295,7 +296,6 @@ static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_ 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 tm *tm_p; char str[11]; char datestr[80]; wmove(window, 6+i-offset, 0); @@ -306,6 +306,7 @@ static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_ wbkgdset(window,' ' | COLOR_PAIR(1)); if(current_file->stat.st_mtime!=0) { + struct tm *tm_p; tm_p = localtime(¤t_file->stat.st_mtime); snprintf(datestr, sizeof(datestr),"%2d-%s-%4d %02d:%02d", tm_p->tm_mday, monstr[tm_p->tm_mon], @@ -624,7 +625,7 @@ static int dir_partition_aux(disk_t *disk, const partition_t *partition, dir_dat new_inode_ok=0; if(new_inode_ok>0) { - new_inode=dir_partition_aux(disk, partition, dir_data, (unsigned long int)new_inode, depth+1, current_cmd); + dir_partition_aux(disk, partition, dir_data, (unsigned long int)new_inode, depth+1, current_cmd); } } /* restore current_directory name */ @@ -702,8 +703,7 @@ static int copy_dir(disk_t *disk, const partition_t *partition, dir_data_t *dir_ int copy_ok=0; if(dir_data->get_dir==NULL || dir_data->copy_file==NULL) return -2; - dir_name=gen_local_filename(dir_data->local_dir, dir_data->current_directory); - create_dir(dir_name,1); + 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->stat.st_ino); for(current_file=dir_list;current_file!=NULL;current_file=current_file->next) { @@ -743,18 +743,6 @@ static int copy_dir(disk_t *disk, const partition_t *partition, dir_data_t *dir_ return (copy_bad>0?(copy_ok>0?-1:-2):0); } -FILE *create_file(const char *filename) -{ - FILE *f_out; - f_out=fopen(filename,"wb"); - if(!f_out) - { - create_dir(filename,0); - f_out=fopen(filename,"wb"); - } - return f_out; -} - /** * set_date - Set the file's date and time * @pathname: Path and name of the file to alter @@ -870,3 +858,324 @@ int set_mode(const char *pathname, unsigned int mode) return 0; #endif } + +#ifdef DJGPP +static inline unsigned char convert_char_dos(unsigned char car) +{ + if(car<0x20) + return '_'; + switch(car) + { + /* Forbidden */ + case '<': + case '>': + case ':': + case '"': + /* case '/': subdirectory */ + case '\\': + case '|': + case '?': + case '*': + /* Not recommanded */ + case '[': + case ']': + case ';': + case ',': + case '+': + case '=': + return '_'; + } + /* 'a' */ + if(car>=224 && car<=230) + return 'a'; + /* 'c' */ + if(car==231) + return 'c'; + /* 'e' */ + if(car>=232 && car<=235) + return 'e'; + /* 'i' */ + if(car>=236 && car<=239) + return 'n'; + /* n */ + if(car==241) + return 'n'; + /* 'o' */ + if((car>=242 && car<=246) || car==248) + return 'o'; + /* 'u' */ + if(car>=249 && car<=252) + return 'u'; + /* 'y' */ + if(car>=253) + return 'y'; + return car; +} + +/* + * filename_convert reads a maximum of n and writes a maximum of n+1 bytes + * dst string will be null-terminated + */ +static unsigned int filename_convert(char *dst, const char*src, const unsigned int n) +{ + unsigned int i; + for(i=0;i<n && src[i]!='\0';i++) + dst[i]=convert_char_dos(src[i]); + while(i>0 && (dst[i-1]==' '||dst[i-1]=='.')) + i--; + if(i==0 && (dst[i]==' '||dst[i]=='.')) + dst[i++]='_'; + dst[i]='\0'; + return i; +} +#elif defined(__CYGWIN__) || defined(__MINGW32__) +static inline unsigned char convert_char_win(unsigned char car) +{ + if(car<0x20) + return '_'; + switch(car) + { + /* Forbidden */ + case '<': + case '>': + case ':': + case '"': + /* case '/': subdirectory */ + case '\\': + case '|': + case '?': + case '*': + /* Not recommanded, valid for NTFS, invalid for FAT */ + case '[': + case ']': + case '+': + /* Not recommanded */ + case ';': + case ',': + case '=': + return '_'; + } + return car; +} + +static unsigned int filename_convert(char *dst, const char*src, const unsigned int n) +{ + unsigned int i; + for(i=0;i<n && src[i]!='\0';i++) + dst[i]=convert_char_win(src[i]); + while(i>0 && (dst[i-1]==' '||dst[i-1]=='.')) + i--; + if(i==0 && (dst[i]==' '||dst[i]=='.')) + dst[i++]='_'; + dst[i]='\0'; + return i; +} +#elif defined(__APPLE__) +static unsigned int filename_convert(char *dst, const char*src, const unsigned int n) +{ + unsigned int i,j; + const unsigned char *p; /* pointers to actual position in source buffer */ + unsigned char *q; /* pointers to actual position in destination buffer */ + p=(const unsigned char *)src; + q=(unsigned char *)dst; + for(i=0,j=0; (*p)!='\0' && i<n; i++) + { + if((*p & 0x80)==0x00) + { + *q++=*p++; + j++; + } + else if((*p & 0xe0)==0xc0 && (*(p+1) & 0xc0)==0x80) + { + *q++=*p++; + *q++=*p++; + j+=2; + } + else if((*p & 0xf0)==0xe0 && (*(p+1) & 0xc0)==0x80 && (*(p+2) & 0xc0)==0x80) + { + *q++=*p++; + *q++=*p++; + *q++=*p++; + j+=3; + } + else + { + *q++='_'; + p++; + j++; + } + } + *q='\0'; + return j; +} +#else +static unsigned int filename_convert(char *dst, const char*src, const unsigned int n) +{ + unsigned int i; + for(i=0;i<n && src[i]!='\0';i++) + dst[i]=src[i]; + dst[i]='\0'; + return i; +} +#endif + +char *gen_local_filename(const char *filename) +{ + int l=strlen(filename); + char *dst=(char *)MALLOC(l+1); + filename_convert(dst, filename, l); +#if defined(DJGPP) || defined(__CYGWIN__) || defined(__MINGW32__) + if(filename[0]!='\0' && filename[1]==':') + dst[1]=':'; +#endif + return dst; +} + +char *mkdir_local(const char *localroot, const char *pathname) +{ + const int l1=(localroot==NULL?0:strlen(localroot)); + const int l2=strlen(pathname); + char *localdir=(char *)MALLOC(l1+l2+1); + const char *src; + char *dst; + if(localroot!=NULL) + memcpy(localdir, localroot, l1); + memcpy(localdir+l1, pathname, l2+1); +#ifdef HAVE_MKDIR +#ifdef __MINGW32__ + if(mkdir(localdir)>=0 || errno==EEXIST) + return localdir; +#else + if(mkdir(localdir, 0775)>=0 || errno==EEXIST) + return localdir; +#endif + /* Need to create the parent and maybe convert the pathname */ + if(localroot!=NULL) + memcpy(localdir, localroot, l1); + localdir[l1]='\0'; + src=pathname; + dst=localdir+l1; + while(*src!='\0') + { + unsigned int n=0; + unsigned int l; + const char *src_org=src; + char *dst_org=dst; + for(n=0; + *src!='\0' && (n==0 || *src!='/'); + dst++, src++, n++) + *dst=*src; + *dst='\0'; +#ifdef __MINGW32__ + if(mkdir(localdir)<0 && errno==EINVAL) + { + l=filename_convert(dst_org, src_org, n); + dst=dst_org+l; + mkdir(localdir); + } +#elif defined(__CYGWIN__) + if(memcmp(&localdir[1],":/cygdrive",11)!=0 && + mkdir(localdir, 0775)<0 && errno==EINVAL) + { + l=filename_convert(dst_org, src_org, n); + dst=dst_org+l; + mkdir(localdir, 0775); + } +#else + if(mkdir(localdir, 0775)<0 && errno==EINVAL) + { + l=filename_convert(dst_org, src_org, n); + dst=dst_org+l; + mkdir(localdir, 0775); + } +#endif + } +#else +#warning You need a mkdir function! +#endif + return localdir; +} + +void mkdir_local_for_file(const char *filename) +{ + char *dir=strdup(filename); + char *sep=NULL; + char *oldsep; + do + { + oldsep=sep; + sep=strchr(dir,'/'); + } while(sep!=NULL); + if(oldsep!=NULL) + { + *oldsep='\0'; + free(mkdir_local(NULL, dir)); + } + free(dir); +} + +FILE *fopen_local(char **localfilename, const char *localroot, const char *filename) +{ + const int l1=strlen(localroot); + const int l2=strlen(filename); + const char *src; + char *dst=(char *)MALLOC(l1+l2+1); + const char *src_org=filename; + char *dst_org=dst; + FILE *f_out; + memcpy(dst, localroot, l1); + memcpy(dst+l1, filename, l2+1); + *localfilename=dst; + f_out=fopen(dst,"wb"); + if(f_out) + return f_out; + /* Need to create the parent and maybe convert the pathname */ + src=filename; + memcpy(dst, localroot, l1+1); + dst+=l1; + while(*src!='\0') + { + unsigned int n; + src_org=src; + dst_org=dst; + for(n=0; + *src!='\0' && (n==0 || *src!='/'); + dst++, src++, n++) + *dst=*src; + *dst='\0'; + if(*src!='\0') + { +#ifdef __MINGW32__ + if(mkdir(*localfilename)<0 && errno==EINVAL) + { + unsigned int l; + l=filename_convert(dst_org, src_org, n); + dst=dst_org+l; + mkdir(*localfilename); + } +#elif defined(__CYGWIN__) + if(memcmp(&localfilename[1],":/cygdrive",11)!=0 && + mkdir(*localfilename, 0775)<0 && errno==EINVAL) + { + unsigned int l; + l=filename_convert(dst_org, src_org, n); + dst=dst_org+l; + mkdir(*localfilename, 0775); + } +#else + if(mkdir(*localfilename, 0775)<0 && errno==EINVAL) + { + unsigned int l; + l=filename_convert(dst_org, src_org, n); + dst=dst_org+l; + mkdir(*localfilename, 0775); + } +#endif + } + } + f_out=fopen(*localfilename,"wb"); + if(f_out) + return f_out; + filename_convert(dst_org, src_org, l2); + return fopen(*localfilename,"wb"); +} @@ -78,9 +78,12 @@ void delete_list_file_info(struct td_list_head *list); int dir_partition_aff(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int inode, char **current_cmd); 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); -FILE *create_file(const char *filename); int set_date(const char *pathname, time_t actime, time_t modtime); int set_mode(const char *pathname, unsigned int mode); +FILE *fopen_local(char **localfilename, const char *localroot, const char *filename); +char *gen_local_filename(const char *filename); +char *mkdir_local(const char *localroot, const char *pathname); +void mkdir_local_for_file(const char *filename); #define LINUX_S_IFMT 00170000 #define LINUX_S_IFSOCK 0140000 diff --git a/src/ext2_dir.c b/src/ext2_dir.c index 569c26ea..e547ff07 100644 --- a/src/ext2_dir.c +++ b/src/ext2_dir.c @@ -178,11 +178,17 @@ static errcode_t my_read_blk(io_channel channel, unsigned long block, int count, static errcode_t my_write_blk(io_channel channel, unsigned long block, int count, const void *buf) { - my_data_t *my_data=(my_data_t*)channel; EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL); -/* if(my_data->disk_car->write(my_data->disk_car,count*channel->block_size,buf,my_data->partition->part_offset+(uint64_t)block*channel->block_size))!=0) */ - return 1; -/* return 0; */ +#if 1 + { + my_data_t *my_data=(my_data_t*)channel; + if(my_data->disk_car->write(my_data->disk_car,count*channel->block_size,buf,my_data->partition->part_offset+(uint64_t)block*channel->block_size)!=0) + return 1; + return 0; + } +#else + return 1; +#endif } static errcode_t my_flush(io_channel channel) @@ -283,8 +289,7 @@ static int ext2_copy(disk_t *disk_car, const partition_t *partition, dir_data_t FILE *f_out; struct ext2_dir_struct *ls = (struct ext2_dir_struct *)dir_data->private_dir_data; char *new_file; - new_file=gen_local_filename(dir_data->local_dir, dir_data->current_directory); - f_out=create_file(new_file); + f_out=fopen_local(&new_file, dir_data->local_dir, dir_data->current_directory); if(!f_out) { log_critical("Can't create file %s: %s\n", new_file, strerror(errno)); @@ -317,7 +322,7 @@ static int ext2_copy(disk_t *disk_car, const partition_t *partition, dir_data_t if (retval) { log_error("Error while reading ext2 file %s\n", dir_data->current_directory); - error=-3; + error = -3; } if (got == 0) break; @@ -325,14 +330,14 @@ static int ext2_copy(disk_t *disk_car, const partition_t *partition, dir_data_t if ((unsigned) nbytes != got) { log_error("Error while writing file %s\n", new_file); - error=-5; + error = -5; } } retval = ext2fs_file_close(e2_file); if (retval) { log_error("Error while closing ext2 file\n"); - error=-6; + error = -6; } fclose(f_out); set_date(new_file, file->stat.st_atime, file->stat.st_mtime); diff --git a/src/fat_dir.c b/src/fat_dir.c index 77be1039..ed2f9300 100644 --- a/src/fat_dir.c +++ b/src/fat_dir.c @@ -153,50 +153,51 @@ ParseLongDeletedNext: unsigned int i; const struct msdos_dir_slot *ds; unsigned char id; - unsigned char slot; - unsigned char slots; unsigned char sum; unsigned char alias_checksum; ParseLong: - slots = 0; ds = (const struct msdos_dir_slot *) de; id = ds->id; if ((id & 0x40)==0) goto RecEnd; - slots = id & ~0x40; - if (slots > 20 || slots==0) /* ceil(256 * 2 / 26) */ - goto RecEnd; - long_slots = slots; - alias_checksum = ds->alias_checksum; + { + unsigned char slots; + unsigned char slot; + slots = id & ~0x40; + if (slots > 20 || slots==0) /* ceil(256 * 2 / 26) */ + goto RecEnd; + long_slots = slots; + alias_checksum = ds->alias_checksum; - slot = slots; - while (1) { - int offset; + slot = slots; + while (1) { + int offset; - slot--; - offset = slot * 13; - fat16_towchar(unicode + offset, ds->name0_4, 5); - fat16_towchar(unicode + offset + 5, ds->name5_10, 6); - fat16_towchar(unicode + offset + 11, ds->name11_12, 2); + slot--; + offset = slot * 13; + fat16_towchar(unicode + offset, ds->name0_4, 5); + fat16_towchar(unicode + offset + 5, ds->name5_10, 6); + fat16_towchar(unicode + offset + 11, ds->name11_12, 2); - if ((ds->id & 0x40)!=0) { - unicode[offset + 13] = 0; - } - de++; - if((const void*)de>=(const void*)(buffer+size)) - goto EODir; - if (slot == 0) - break; - ds = (const struct msdos_dir_slot *) de; - if (ds->attr != ATTR_EXT) - { - long_slots=0; - goto RecEnd; /* XXX */ + if ((ds->id & 0x40)!=0) { + unicode[offset + 13] = 0; + } + de++; + if((const void*)de>=(const void*)(buffer+size)) + goto EODir; + if (slot == 0) + break; + ds = (const struct msdos_dir_slot *) de; + if (ds->attr != ATTR_EXT) + { + long_slots=0; + goto RecEnd; /* XXX */ + } + if ((ds->id & ~0x40) != slot) + goto ParseLong; + if (ds->alias_checksum != alias_checksum) + goto ParseLong; } - if ((ds->id & ~0x40) != slot) - goto ParseLong; - if (ds->alias_checksum != alias_checksum) - goto ParseLong; } if (de->attr == ATTR_EXT) goto ParseLong; @@ -530,8 +531,7 @@ static int fat_copy(disk_t *disk_car, const partition_t *partition, dir_data_t * unsigned int fat_meth=FAT_FOLLOW_CLUSTER; uint64_t start_fat1,start_data,part_size; unsigned long int no_of_cluster,fat_length; - new_file=gen_local_filename(dir_data->local_dir, dir_data->current_directory); - f_out=create_file(new_file); + f_out=fopen_local(&new_file, dir_data->local_dir, dir_data->current_directory); if(!f_out) { log_critical("Can't create file %s: \n",new_file); diff --git a/src/ntfs_dir.c b/src/ntfs_dir.c index 1ac34429..e13b7d4d 100644 --- a/src/ntfs_dir.c +++ b/src/ntfs_dir.c @@ -358,8 +358,7 @@ static int ntfs_copy(disk_t *disk_car, const partition_t *partition, dir_data_t block_size = index_get_size(inode); else block_size = 0; - new_file=gen_local_filename(dir_data->local_dir, dir_data->current_directory); - f_out=create_file(new_file); + f_out=fopen_local(&new_file, dir_data->local_dir, dir_data->current_directory); if(!f_out) { log_critical("Can't create file %s: %s\n",new_file, strerror(errno)); diff --git a/src/ntfs_udl.c b/src/ntfs_udl.c index 5609309a..976104de 100644 --- a/src/ntfs_udl.c +++ b/src/ntfs_udl.c @@ -761,13 +761,13 @@ static int create_pathname(const char *dir, const char *dir2, const char *name, char *namel; if (name==NULL) name = UNKNOWN; - namel=gen_local_filename(name, NULL); + namel=gen_local_filename(name); if(dir2) { - char *dir2l=gen_local_filename(dir2, NULL); + char *dir2l=gen_local_filename(dir2); if (stream) { - char *streaml=gen_local_filename(stream, NULL); + char *streaml=gen_local_filename(stream); snprintf(buffer, bufsize, "%s/%s/%s:%s", dir, dir2l, namel, streaml); free(streaml); } @@ -779,7 +779,7 @@ static int create_pathname(const char *dir, const char *dir2, const char *name, { if (stream) { - char *streaml=gen_local_filename(stream, NULL); + char *streaml=gen_local_filename(stream); snprintf(buffer, bufsize, "%s/%s:%s", dir, namel, streaml); free(streaml); } @@ -803,7 +803,11 @@ static int create_pathname(const char *dir, const char *dir2, const char *name, */ static int open_file(const char *pathname) { - create_dir(pathname, 0); + int fh; + fh=open(pathname, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); + if(fh>=0 || errno!=ENOENT) + return fh; + mkdir_local_for_file(pathname); return open(pathname, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); } @@ -831,7 +835,6 @@ static int open_file(const char *pathname) */ static int undelete_file(ntfs_volume *vol, long long inode) { - char pathname[256]; char *buffer = NULL; unsigned int bufsize; struct ufile *file; @@ -881,6 +884,7 @@ static int undelete_file(ntfs_volume *vol, long long inode) } td_list_for_each(item, &file->data) { + char pathname[256]; struct data *d = td_list_entry(item, struct data, list); name = file->pref_name; |