static int list_dir_proc2(ext2_ino_t dir, int entry, struct ext2_dir_entry *dirent, int offset, int blocksize, char *buf, void *privateinfo) { struct ext2_inode inode; ext2_ino_t ino; const struct ext2_dir_struct *ls = (const struct ext2_dir_struct *) privateinfo; file_info_t *new_file; if(entry==DIRENT_DELETED_FILE && (ls->dir_data->param & FLAG_LIST_DELETED)==0) return 0; ino = dirent->inode; if (ino) { errcode_t retval; // log_info("ext2fs_read_inode(ino=%u)\n", ino); if ((retval=ext2fs_read_inode(ls->current_fs,ino, &inode))!=0) { log_error("ext2fs_read_inode(ino=%u) failed with error %ld.\n",(unsigned)ino, (long)retval); memset(&inode, 0, sizeof(struct ext2_inode)); } } else { memset(&inode, 0, sizeof(struct ext2_inode)); } new_file=(file_info_t *)MALLOC(sizeof(*new_file)); { const unsigned int thislen = ((dirent->name_len & 0xFF) < EXT2_NAME_LEN) ? (dirent->name_len & 0xFF) : EXT2_NAME_LEN; new_file->name=(char *)MALLOC(thislen+1); memcpy(new_file->name, dirent->name, thislen); new_file->name[thislen] = '\0'; } if(entry==DIRENT_DELETED_FILE) new_file->status=FILE_STATUS_DELETED; else new_file->status=0; new_file->st_ino=ino; new_file->st_mode=inode.i_mode; // new_file->st_nlink=inode.i_links_count; new_file->st_uid=inode.i_uid; new_file->st_gid=inode.i_gid; new_file->st_size=LINUX_S_ISDIR(inode.i_mode)?inode.i_size: inode.i_size| ((uint64_t)inode.i_size_high << 32); // new_file->st_blksize=blocksize; // new_file->st_blocks=inode.i_blocks; new_file->td_atime=inode.i_atime; new_file->td_mtime=inode.i_mtime; new_file->td_ctime=inode.i_ctime; td_list_add_tail(&new_file->list, &ls->dir_list->list); return 0; }
/** * ntfs_td_list_entry * FIXME: Should we print errors as we go along? (AIA) */ 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) { int result = 0; char *filename; ntfs_inode *ni; ntfs_attr_search_ctx *ctx_si = NULL; file_info_t *new_file=NULL; /* Keep FILE_NAME_WIN32 and FILE_NAME_POSIX */ if ((name_type & FILE_NAME_WIN32_AND_DOS) == FILE_NAME_DOS) return 0; filename = (char *)calloc (1, MAX_PATH); if (!filename) { log_critical("ntfs_td_list_entry calloc failed\n"); return -1; } #ifdef HAVE_ICONV if (ntfs_ucstoutf8(ls->cd, name, name_len, &filename, MAX_PATH) < 0 && ntfs_ucstombs (name, name_len, &filename, MAX_PATH) < 0) { log_error("Cannot represent filename in current locale.\n"); goto freefn; } #else if (ntfs_ucstombs (name, name_len, &filename, MAX_PATH) < 0) { log_error("Cannot represent filename in current locale.\n"); goto freefn; } #endif result = 0; /* These are successful */ if ((ls->dir_data->param & FLAG_LIST_SYSTEM)!=FLAG_LIST_SYSTEM && MREF(mref) < FILE_first_user && filename[0] == '$') /* Hide system file */ goto freefn; result = -1; /* Everything else is bad */ ni = ntfs_inode_open(ls->vol, mref); if (!ni) goto freefn; new_file=(file_info_t*)MALLOC(sizeof(*new_file)); new_file->status=0; new_file->st_ino=MREF(mref); new_file->st_uid=0; new_file->st_gid=0; ctx_si = ntfs_attr_get_search_ctx(ni, ni->mrec); if (ctx_si) { if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED, 0, CASE_SENSITIVE, 0, NULL, 0, ctx_si)==0) { const ATTR_RECORD *attr = ctx_si->attr; const STANDARD_INFORMATION *si = (const STANDARD_INFORMATION*)((const char*)attr + le16_to_cpu(attr->value_offset)); if(si) { new_file->td_atime=td_ntfs2utc(sle64_to_cpu(si->last_access_time)); new_file->td_mtime=td_ntfs2utc(sle64_to_cpu(si->last_data_change_time)); new_file->td_ctime=td_ntfs2utc(sle64_to_cpu(si->creation_time)); } } ntfs_attr_put_search_ctx(ctx_si); } { ATTR_RECORD *rec; int first=1; ntfs_attr_search_ctx *ctx = NULL; if (dt_type == NTFS_DT_DIR) { new_file->name=strdup(filename); new_file->st_mode = LINUX_S_IFDIR| LINUX_S_IRUGO | LINUX_S_IXUGO; new_file->st_size=0; td_list_add_tail(&new_file->list, &ls->dir_list->list); first=0; } ctx = ntfs_attr_get_search_ctx(ni, ni->mrec); /* A file has always an unnamed date stream and * may have named alternate data streams (ADS) */ while((rec = find_attribute(AT_DATA, ctx))) { const s64 filesize = ntfs_get_attribute_value_length(ctx->attr); if(rec->name_length && (ls->dir_data->param & FLAG_LIST_ADS)!=FLAG_LIST_ADS) continue; if(first==0) { 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; new_file->st_size=filesize; if (rec->name_length) { 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, MAX_PATH, "%s:???", filename); } else { snprintf(new_file->name, MAX_PATH, "%s:%s", filename, stream_name); } free(stream_name); } else { new_file->name=strdup(filename); } td_list_add_tail(&new_file->list, &ls->dir_list->list); first=0; } ntfs_attr_put_search_ctx(ctx); if(first) { free(new_file); } } result = 0; /* close the inode. */ ntfs_inode_close(ni); freefn: free (filename); return result; }
backup_disk_t *partition_load(const disk_t *disk_car, const int verbose) { FILE *f_backup; char *buffer; char *pos=NULL; int taille; backup_disk_t *new_backup=NULL; backup_disk_t *list_backup; list_backup=(backup_disk_t*)MALLOC(sizeof(*list_backup)); list_backup->list.prev= &list_backup->list; list_backup->list.next = &list_backup->list; if(verbose>1) { log_trace("partition_load\n"); } f_backup=fopen("backup.log","r"); if(!f_backup) { log_error("Can't open backup.log file: %s\n",strerror(errno)); return list_backup; } buffer=(char *)MALLOC(BACKUP_MAXSIZE); taille=fread(buffer,1,BACKUP_MAXSIZE,f_backup); buffer[(taille<BACKUP_MAXSIZE?taille:BACKUP_MAXSIZE-1)]='\0'; if(verbose>1) { log_info("partition_load backup.log size=%d\n",taille); } for(pos=buffer;pos<buffer+taille;pos++) { if(*pos=='\n') { *pos='\0'; } } pos=buffer; while(pos!=NULL && pos<buffer+taille) { if(*pos=='#') { pos++; if(verbose>1) { log_verbose("new disk: %s\n",pos); } if(new_backup!=NULL) td_list_add_tail(&new_backup->list,&list_backup->list); new_backup=(backup_disk_t*)MALLOC(sizeof(*new_backup)); new_backup->description[0]='\0'; new_backup->list_part=NULL; new_backup->my_time=strtol(pos,&pos,10); if(pos!=NULL) { strncpy(new_backup->description,++pos,sizeof(new_backup->description)); new_backup->description[sizeof(new_backup->description)-1]='\0'; } } else if(new_backup!=NULL) { partition_t *new_partition=partition_new(disk_car->arch); char status; unsigned int part_type; unsigned long part_size; unsigned long part_offset; if(verbose>1) { log_verbose("new partition\n"); } if(sscanf(pos,"%2u : start=%10lu, size=%10lu, Id=%02X, %c\n", &new_partition->order, &part_offset, &part_size,&part_type,&status)==5) { new_partition->part_offset=(uint64_t)part_offset*disk_car->sector_size; new_partition->part_size=(uint64_t)part_size*disk_car->sector_size; if(disk_car->arch->set_part_type!=NULL) disk_car->arch->set_part_type(new_partition,part_type); switch(status) { case 'P': new_partition->status=STATUS_PRIM; break; case '*': new_partition->status=STATUS_PRIM_BOOT; break; case 'L': new_partition->status=STATUS_LOG; break; default: new_partition->status=STATUS_DELETED; break; } { int insert_error=0; new_backup->list_part=insert_new_partition(new_backup->list_part, new_partition, 0, &insert_error); if(insert_error>0) free(new_partition); } } else { log_critical("partition_load: sscanf failed\n"); free(new_partition); pos=NULL; } } if(pos!=NULL) { while(*pos!='\0' && pos<buffer+taille) pos++; pos++; } } if(new_backup!=NULL) td_list_add_tail(&new_backup->list,&list_backup->list); fclose(f_backup); free(buffer); return list_backup; }
static int dir_exfat_aux(const unsigned char*buffer, const unsigned int size, const dir_data_t *dir_data, file_info_t *dir_list) { const struct exfat_dir_struct *ls=(const struct exfat_dir_struct*)dir_data->private_dir_data; /* * 0x83 Volume label * 0x81 Allocation bitmap * 0x82 Upcase tabel * 0x85 File -> 0x05 * 0xC0 Stream extension -> 0x40 * 0xC1 File name extension -> 0x41 * 0xA0 Volume GUID * 0xA1 TexFAT padding * 0xE2 Windows CE ACL * */ file_info_t *current_file=NULL; unsigned int offset=0; unsigned int sec_count=0; for(offset=0; offset<size; offset+=0x20) { if((buffer[offset]&0x80)==0 && (dir_data->param & FLAG_LIST_DELETED)!=FLAG_LIST_DELETED) continue; if((buffer[offset]&0x7f)==0x05) { /* File directory entry */ const struct exfat_file_entry *entry=(const struct exfat_file_entry *)&buffer[offset]; 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))); new_file->st_uid=0; new_file->st_gid=0; new_file->st_size=0; new_file->td_atime=date_dos2unix(le16(entry->atime),le16(entry->adate)); 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); current_file=new_file; td_list_add_tail(&new_file->list, &dir_list->list); } else if(sec_count>0 && current_file!=NULL) { if((buffer[offset]&0x7f)==0x40) { /* Stream extension */ const struct exfat_stream_ext_entry *entry=(const struct exfat_stream_ext_entry*)&buffer[offset]; current_file->st_size=le64(entry->data_length); current_file->st_ino=le32(entry->first_cluster); #if 0 if((entry->first_cluster&2)!=0) current_file->st_size=0; #endif } else if((buffer[offset]&0x7f)==0x41) { #ifdef HAVE_ICONV char *outs; #endif unsigned int i,j; for(j=0; j<255 && current_file->name[j]!='\0'; j++); #ifdef HAVE_ICONV for(i=2; i<32 && (buffer[offset+i]!=0 || buffer[offset+i+1]!=0); i+=2); i-=2; outs=¤t_file->name[j]; if(exfat_ucstoutf8(ls->cd, &buffer[offset+2], i, &outs, 512-j) < 0) #endif { for(i=2; i<32; i+=2) current_file->name[j++]=buffer[offset+i]; current_file->name[j]='\0'; } } sec_count--; } } return 0; }