struct struct_file_info search_dir_entries (int (*action) (struct struct_file_info *info),int *status) { struct struct_file_info info; /* Temporary variables used to */ struct ext2_dir_entry_2 *dir_entry_ptr; /* contain the current search entries */ int return_code, next; info=first_file_info; /* Start from the first entry - Read it */ low_read (info.buffer,file_system_info.block_size,info.global_block_offset); dir_entry_ptr=(struct ext2_dir_entry_2 *) (info.buffer+info.dir_entry_offset); while (info.file_offset < info.file_length) { /* While we haven't reached the end */ *status=return_code=action (&info); /* Call the client function to test */ /* the current entry */ if (return_code==ABORT || return_code==FOUND) return (info); /* Stop, if so asked */ /* Pass to the next entry */ dir_entry_ptr=(struct ext2_dir_entry_2 *) (info.buffer+info.dir_entry_offset); info.dir_entry_num++; next = dir_entry_ptr->rec_len; if (!next) next = file_system_info.block_size - info.dir_entry_offset; info.dir_entry_offset += next; info.file_offset += next; if (info.file_offset >= info.file_length) break; if (info.dir_entry_offset >= file_system_info.block_size) { /* We crossed a block boundary */ /* Find the next block, */ info.block_num++; info.global_block_num=file_block_to_global_block (info.block_num,&info); info.global_block_offset=info.global_block_num*file_system_info.block_size; info.file_offset=info.block_num*file_system_info.block_size; info.dir_entry_offset=0; /* read it and update the pointer */ low_read (info.buffer,file_system_info.block_size,info.global_block_offset); dir_entry_ptr=(struct ext2_dir_entry_2 *) (info.buffer+info.dir_entry_offset); } } *status=ABORT;return (info); /* There was no match */ }
long inode_offset_to_group_num (long inode_offset) { int found=0; struct ext2_group_desc desc; long block_num,group_offset,group_num; block_num=inode_offset/file_system_info.block_size; group_offset=file_system_info.first_group_desc_offset; group_num=(group_offset-file_system_info.first_group_desc_offset)/sizeof (struct ext2_group_desc); while (!found && group_num>=0 && group_num<file_system_info.groups_count) { low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset); if (block_num>=desc.bg_inode_table && block_num<desc.bg_inode_table+file_system_info.blocks_per_group) found=1; else group_offset+=sizeof (struct ext2_group_desc); group_num=(group_offset-file_system_info.first_group_desc_offset)/sizeof (struct ext2_group_desc); } if (!found) return (-1); return (group_num); }
void type_ext2_inode___entry (char *command_line) { char *ptr,buffer [80]; long group_num,group_offset,entry_num,block_num,wanted_entry; struct ext2_group_desc desc; ptr=parse_word (command_line,buffer); if (*ptr==0) return; ptr=parse_word (ptr,buffer); wanted_entry=atol (buffer); block_num=device_offset/file_system_info.block_size; group_num=inode_offset_to_group_num (device_offset); group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc); low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset); entry_num=(device_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode); if (wanted_entry > entry_num) { sprintf (buffer,"next %ld",wanted_entry-entry_num); dispatch (buffer); } else if (wanted_entry < entry_num) { sprintf (buffer,"prev %ld",entry_num-wanted_entry); dispatch (buffer); } }
int init_file_info (void) { struct ext2_inode *ptr; ptr=&type_data.u.t_ext2_inode; file_info.inode_ptr=ptr; file_info.inode_offset=device_offset; file_info.global_block_num=ptr->i_block [0]; file_info.global_block_offset=ptr->i_block [0]*file_system_info.block_size; file_info.block_num=0; file_info.blocks_count=(ptr->i_size+file_system_info.block_size-1)/file_system_info.block_size; file_info.file_offset=0; file_info.file_length=ptr->i_size; file_info.level=0; file_info.offset_in_block=0; file_info.display=HEX; low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset); return (1); }
int load_type_data (void) /* Just read from the current position into type data. */ { if (device_handle==NULL) { printf ("Error - No device opened\n"); return (0); } if (device_offset==-1) { printf ("Error - No offset set\n"); return (0); } if (low_read (type_data.u.buffer,EXT2_MAX_BLOCK_SIZE,device_offset)==0) return (0); if (current_type!=NULL) if (strcmp (current_type->name,"ext2_dir_entry")==0) current_type->length=type_data.u.t_ext2_dir_entry.rec_len; return (1); }
void type_file___nextblock (char *command_line) { long block_offset=1; char *ptr,buffer [80]; ptr=parse_word (command_line,buffer); if (*ptr!=0) { ptr=parse_word (ptr,buffer); block_offset*=atol (buffer); } if (file_info.block_num+block_offset >= file_info.blocks_count) { wprintw (command_win,"Error - Block offset out of range\n");wrefresh (command_win); return; } file_info.block_num+=block_offset; file_info.global_block_num=file_block_to_global_block (file_info.block_num,&file_info); file_info.global_block_offset=file_info.global_block_num*file_system_info.block_size; file_info.file_offset=file_info.block_num*file_system_info.block_size; low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset); strcpy (buffer,"show");dispatch (buffer); }
long return_indirect (long table_block,long block_num) { long block_table [EXT2_MAX_BLOCK_SIZE/4]; low_read ((char *) block_table,file_system_info.block_size,table_block*file_system_info.block_size); return (block_table [block_num]); }
int log_changes (unsigned char *buffer,unsigned long length,unsigned long offset) /* Log the change in a primitive form - An hex dump of the data before the change and after the change. The hex bytes are converted to text, so that they will be readable with a standard text editor. */ { unsigned char *original; int i; time_t current_time; FILE *fp; if ((fp=fopen (LogFile,"a+"))==NULL) { wprintw (command_win,"Error - Unable to open log file %s\n",LogFile); refresh_command_win ();return (0); }; current_time=time (NULL); fprintf (fp,"\n----- EXT2ED log begin -----\n\n"); fprintf (fp,"Time: %s\nDevice: %s\n",ctime ((time_t *) ¤t_time),device_name); fprintf (fp,"Offset: %lu\nLength: %lu\n",offset,length); original=(unsigned char *) malloc (length*sizeof (unsigned char)); if (original==NULL) { wprintw (command_win,"Fatal error - Can\'t allocate %lu bytes!"); refresh_command_win ();fclose (fp);return (0); } if (!low_read (original,length,offset)) { fclose (fp);return (0); } fprintf (fp,"\nOriginal data:\n\n"); for (i=0;i<length;i++) { if (i%16==0 && i!=0) fprintf (fp,"\n"); fprintf (fp,"%02x ",original [i]); } fprintf (fp,"\n\nNew data:\n\n"); for (i=0;i<length;i++) { if (i%16==0 && i!=0) fprintf (fp,"\n"); fprintf (fp,"%02x ",buffer [i]); } fprintf (fp,"\n----- EXT2ED log end -----\n"); fclose (fp); return (1); }
int log_changes (unsigned char *buffer,unsigned long length,unsigned long offset) { unsigned char *original; int i; time_t current_time; FILE *fp; if ((fp=fopen (LogFile,"a+"))==NULL) { wprintw (command_win,"Error - Unable to open log file %s\n",LogFile); refresh_command_win ();return (0); }; current_time=time (NULL); fprintf (fp,"\n----- EXT2ED log begin -----\n\n"); fprintf (fp,"Time: %s\nDevice: %s\n",ctime ((time_t *) ¤t_time),device_name); fprintf (fp,"Offset: %lu\nLength: %lu\n",offset,length); original=(unsigned char *) malloc (length*sizeof (unsigned char)); if (original==NULL) { wprintw (command_win,"Fatal error - Can\'t allocate %lu bytes!"); refresh_command_win ();fclose (fp);return (0); } if (!low_read (original,length,offset)) { fclose (fp);return (0); } fprintf (fp,"\nOriginal data:\n\n"); for (i=0;i<length;i++) { if (i%16==0 && i!=0) fprintf (fp,"\n"); fprintf (fp,"%02x ",original [i]); } fprintf (fp,"\n\nNew data:\n\n"); for (i=0;i<length;i++) { if (i%16==0 && i!=0) fprintf (fp,"\n"); fprintf (fp,"%02x ",buffer [i]); } fprintf (fp,"\n----- EXT2ED log end -----\n"); fclose (fp); return (1); }
void type_dir___followinode (char *command_line) { long inode_offset; char buffer [80]; struct ext2_dir_entry_2 *dir_entry_ptr; low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset); dir_entry_ptr=(struct ext2_dir_entry_2 *) (file_info.buffer+file_info.dir_entry_offset); inode_offset=inode_num_to_inode_offset (dir_entry_ptr->inode); /* Compute the inode's offset */ sprintf (buffer,"setoffset %ld",inode_offset);dispatch (buffer); /* Move to it */ sprintf (buffer,"settype ext2_inode");dispatch (buffer); /* and set the type to an inode */ }
void type_ext2_inode___next (char *command_line) { char *ptr,buffer [80]; long group_num,group_offset,entry_num,block_num,first_entry,last_entry; long inode_num,mult=1; struct ext2_group_desc desc; ptr=parse_word (command_line,buffer); if (*ptr!=0) { ptr=parse_word (ptr,buffer); mult=atol (buffer); } block_num=device_offset/file_system_info.block_size; group_num=inode_offset_to_group_num (device_offset); group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc); low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset); entry_num=(device_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode); first_entry=0;last_entry=file_system_info.super_block.s_inodes_per_group-1; inode_num=0; if (entry_num+mult-1<last_entry) { device_offset+=sizeof (struct ext2_inode)*mult; entry_num+=mult; sprintf (buffer,"setoffset %ld",device_offset);dispatch (buffer); strcpy (buffer,"show");dispatch (buffer); } else { wprintw (command_win,"Error - Entry out of limits\n");refresh_command_win (); } if (entry_num==last_entry) { wprintw (command_win,"Reached last inode in current group descriptor\n"); refresh_command_win (); } }
long int inode_num_to_inode_offset (long inode_num) { long group_num,group_offset,inode_offset,inode_entry; struct ext2_group_desc desc; inode_num--; group_num=inode_num/file_system_info.super_block.s_inodes_per_group; inode_entry=inode_num%file_system_info.super_block.s_inodes_per_group; group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc); low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset); inode_offset=desc.bg_inode_table*file_system_info.block_size+inode_entry*sizeof (struct ext2_inode); return (inode_offset); }
long int inode_offset_to_inode_num (long inode_offset) { long group_num,group_offset,entry_num,block_num,first_entry,last_entry,inode_num; struct ext2_group_desc desc; block_num=inode_offset/file_system_info.block_size; group_num=inode_offset_to_group_num (inode_offset); group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc); low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset); entry_num=(inode_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode); first_entry=0;last_entry=file_system_info.super_block.s_inodes_per_group-1; inode_num=group_num*file_system_info.super_block.s_inodes_per_group+1; inode_num+=entry_num; return (inode_num); }
void type_dir___followinode (char *command_line) /* Here we pass to the inode pointed by the current entry. It involves computing the device offset of the inode and using directly the setoffset and settype commands. */ { long inode_offset; char buffer [80]; struct ext2_dir_entry_2 *dir_entry_ptr; low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset); dir_entry_ptr=(struct ext2_dir_entry_2 *) (file_info.buffer+file_info.dir_entry_offset); inode_offset=inode_num_to_inode_offset (dir_entry_ptr->inode); /* Compute the inode's offset */ sprintf (buffer,"setoffset %ld",inode_offset);dispatch (buffer); /* Move to it */ sprintf (buffer,"settype ext2_inode");dispatch (buffer); /* and set the type to an inode */ }
/*! * Liest ein Kommando ein, ist blockierend! * Greift auf low_read() zurueck * @see low_read() */ int command_read(void){ int bytesRcvd; int start=0; // start of command sequence int i; command_t * command; // Pointer to Cast rceceived data char * ptr; // helper char buffer[RCVBUFSIZE]; // Buffer #if BYTE_ORDER == BIG_ENDIAN uint16 store; //store for endian conversion #endif buffer[0]=0; // Start with clean data // uint8 tmp=uart_data_available(); // Den ganzen Puffer abholen bytesRcvd=low_read(buffer,sizeof(command_t)); // LOG_DEBUG(("%d/%d read/av",bytesRcvd,tmp)); // LOG_DEBUG(("%x %x %x",buffer[0],buffer[1],buffer[2])); // Search for frame start while ((start<bytesRcvd)&&(buffer[start] != CMD_STARTCODE)) { // printf("."); start++; } // if no STARCODE ==> discard if (buffer[start] != CMD_STARTCODE){ // LOG_DEBUG(("start not found")); return -1; } // LOG_DEBUG(("Start @%d",start)); //is any chance, that the packet will still fit to buffer? if ((RCVBUFSIZE-start) < sizeof(command_t)){ // LOG_DEBUG(("not enough space")); return -1; // no ==> discard } i=sizeof(command_t) - (bytesRcvd-start); // get rest of package as long as buffer is full while (i > 0){ // LOG_DEBUG(("%d bytes missing",i)); i= low_read(buffer+bytesRcvd,i); // LOG_DEBUG(("%d read",i)); bytesRcvd+=i; i=sizeof(command_t) - (bytesRcvd-start); } // LOG_DEBUG(("%d/%d read/start",bytesRcvd,start)); // LOG_DEBUG(("%x %x %x",buffer[start],buffer[start+1],buffer[start+2])); // Cast to command_t command= (command_t *) ( buffer +start); // LOG_DEBUG(("start: %x ",command->startCode)); // command_display(command); // validate (startcode is already ok, or we won't be here) if (command->CRC==CMD_STOPCODE){ // LOG_DEBUG(("Command is valid")); // Transfer #ifdef PC command_lock(); // on PC make storage threadsafe #endif ptr = (char *) &received_command; for (i=0; i<sizeof(command_t);i++){ *ptr=buffer[i+start]; ptr++; } #if BYTE_ORDER == BIG_ENDIAN /* Umwandeln der 16 bit Werte in Big Endian */ store = received_command.data_l; received_command.data_l = store << 8; received_command.data_l |= (store >> 8) & 0xff; store = received_command.data_r; received_command.data_r = store << 8; received_command.data_r |= (store >> 8) & 0xff; store = received_command.seq; received_command.seq = store << 8; received_command.seq |= (store >> 8) & 0xff; /* "Umdrehen" des Bitfields */ store = received_command.request.subcommand; received_command.request.subcommand = store << 1; received_command.request.direction = store >> 7; #endif #ifdef PC command_unlock(); // on PC make storage threadsafe #endif return 0; } else { // Command not valid
void type_ext2_inode___show (char *command_line) { struct ext2_inode *inode_ptr; unsigned short temp; int i; long group_num,group_offset,entry_num,block_num,first_entry,last_entry,inode_num; struct ext2_group_desc desc; block_num=device_offset/file_system_info.block_size; group_num=inode_offset_to_group_num (device_offset); group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc); low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset); entry_num=(device_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode); first_entry=0;last_entry=file_system_info.super_block.s_inodes_per_group-1; inode_num=group_num*file_system_info.super_block.s_inodes_per_group+1; inode_num+=entry_num; inode_ptr=&type_data.u.t_ext2_inode; show (command_line); wmove (show_pad,0,40);wprintw (show_pad,"octal = %06o ",inode_ptr->i_mode); for (i=6;i>=0;i-=3) { temp=inode_ptr->i_mode & 0x1ff; temp=temp >> i; if (temp & 4) wprintw (show_pad,"r"); else wprintw (show_pad,"-"); if (temp & 2) wprintw (show_pad,"w"); else wprintw (show_pad,"-"); if (temp & 1) wprintw (show_pad,"x"); else wprintw (show_pad,"-"); } wmove (show_pad,3,40);wprintw (show_pad,"%s",ctime ((time_t *) &type_data.u.t_ext2_inode.i_atime)); wmove (show_pad,4,40);wprintw (show_pad,"%s",ctime ((time_t *) &type_data.u.t_ext2_inode.i_ctime)); wmove (show_pad,5,40);wprintw (show_pad,"%s",ctime ((time_t *) &type_data.u.t_ext2_inode.i_mtime)); wmove (show_pad,6,40);wprintw (show_pad,"%s",ctime ((time_t *) &type_data.u.t_ext2_inode.i_dtime)); wmove (show_pad,10,40); temp=inode_ptr->i_flags; if (temp & EXT2_SECRM_FL) wprintw (show_pad,"s"); else wprintw (show_pad,"-"); if (temp & EXT2_UNRM_FL) wprintw (show_pad,"u"); else wprintw (show_pad,"-"); if (temp & EXT2_COMPR_FL) wprintw (show_pad,"c"); else wprintw (show_pad,"-"); if (temp & EXT2_SYNC_FL) wprintw (show_pad,"S"); else wprintw (show_pad,"-"); if (temp & EXT2_IMMUTABLE_FL) wprintw (show_pad,"i"); else wprintw (show_pad,"-"); if (temp & EXT2_APPEND_FL) wprintw (show_pad,"a"); else wprintw (show_pad,"-"); if (temp & EXT2_NODUMP_FL) wprintw (show_pad,"d"); else wprintw (show_pad,"-"); refresh_show_pad (); wmove (show_win,1,0); wprintw (show_win,"Inode %ld of %ld. Entry %ld of %ld in group descriptor %ld.\n" ,inode_num,file_system_info.super_block.s_inodes_count,entry_num,last_entry,group_num); wprintw (show_win,"Inode type: "); if (inode_num < EXT2_GOOD_OLD_FIRST_INO) { switch (inode_num) { case EXT2_BAD_INO: wprintw (show_win,"Bad blocks inode - "); break; case EXT2_ROOT_INO: wprintw (show_win,"Root inode - "); break; case EXT2_ACL_IDX_INO: wprintw (show_win,"ACL index inode - "); break; case EXT2_ACL_DATA_INO: wprintw (show_win,"ACL data inode - "); break; case EXT2_BOOT_LOADER_INO: wprintw (show_win,"Boot loader inode - "); break; case EXT2_UNDEL_DIR_INO: wprintw (show_win,"Undelete directory inode - "); break; default: wprintw (show_win,"Reserved inode - "); break; } } if (type_data.u.t_ext2_inode.i_mode==0) wprintw (show_win,"Free. "); if (S_ISREG (type_data.u.t_ext2_inode.i_mode)) wprintw (show_win,"File. "); if (S_ISDIR (type_data.u.t_ext2_inode.i_mode)) wprintw (show_win,"Directory. "); if (S_ISLNK (type_data.u.t_ext2_inode.i_mode)) { wprintw (show_win,"Symbolic link. "); wmove (show_pad,12,40); if (inode_ptr->i_size <= 60) wprintw (show_pad,"-> %s",(char *) &type_data.u.t_ext2_inode.i_block [0]); else wprintw (show_pad,"Slow symbolic link\n"); refresh_show_pad (); } if (S_ISCHR (type_data.u.t_ext2_inode.i_mode)) wprintw (show_win,"Character device."); if (S_ISBLK (type_data.u.t_ext2_inode.i_mode)) wprintw (show_win,"Block device. "); wprintw (show_win,"\n");refresh_show_win (); if (entry_num==last_entry) { wprintw (command_win,"Reached last inode in current group descriptor\n"); refresh_command_win (); } if (entry_num==first_entry) { wprintw (command_win,"Reached first inode in current group descriptor\n"); refresh_command_win (); } }
struct struct_file_info search_dir_entries (int (*action) (struct struct_file_info *info),int *status) /* This is the main function in this source file. Various actions are implemented using this basic function. This routine runs on all directory entries in the current directory. For each entry, action is called. We'll act according to the return code of action: ABORT - Current dir entry is returned. CONTINUE - Continue searching. FOUND - Current dir entry is returned. If the last entry is reached, it is returned, along with an ABORT status. status is updated to the returned code of action. */ { struct struct_file_info info; /* Temporary variables used to */ struct ext2_dir_entry_2 *dir_entry_ptr; /* contain the current search entries */ int return_code, next; info=first_file_info; /* Start from the first entry - Read it */ low_read (info.buffer,file_system_info.block_size,info.global_block_offset); dir_entry_ptr=(struct ext2_dir_entry_2 *) (info.buffer+info.dir_entry_offset); while (info.file_offset < info.file_length) { /* While we haven't reached the end */ *status=return_code=action (&info); /* Call the client function to test */ /* the current entry */ if (return_code==ABORT || return_code==FOUND) return (info); /* Stop, if so asked */ /* Pass to the next entry */ dir_entry_ptr=(struct ext2_dir_entry_2 *) (info.buffer+info.dir_entry_offset); info.dir_entry_num++; next = dir_entry_ptr->rec_len; if (!next) next = file_system_info.block_size - info.dir_entry_offset; info.dir_entry_offset += next; info.file_offset += next; if (info.file_offset >= info.file_length) break; if (info.dir_entry_offset >= file_system_info.block_size) { /* We crossed a block boundary */ /* Find the next block, */ info.block_num++; info.global_block_num=file_block_to_global_block (info.block_num,&info); info.global_block_offset=info.global_block_num*file_system_info.block_size; info.file_offset=info.block_num*file_system_info.block_size; info.dir_entry_offset=0; /* read it and update the pointer */ low_read (info.buffer,file_system_info.block_size,info.global_block_offset); dir_entry_ptr=(struct ext2_dir_entry_2 *) (info.buffer+info.dir_entry_offset); } } *status=ABORT;return (info); /* There was no match */ }