/*
* /giis/dir.c This files deals with gathering vital infomations need for recovery.
*
* Copyright (C) 2006. G.Lakshmipathi.<lakshmipathi_g@rediffmail.com>
*
*/

#include "giis.h"

/*
* set_content_offset() will first set offset of directory and then read it into buffer 
*/

int set_content_offset(){
int i;	
	fs.block_number=iin.in.i_block[0];
	fs.content_offset=(unsigned long long )fs.block_number*fs.block_size; 
	lseek64(fd,fs.content_offset,0);
return 1;
}

/*
* read_dir() Loads directory into buffer 
*/

int read_dir(){
	int i;
		i=read(fd,ide.buffer,DIR_SIZE);
		CHECK
return 1;
}

/*
* record_dir() enters directory informations into a file 
*
* Modification for giis2.1:
*
* Makes a call to check4dir_dups().
*
*/

int record_dir(unsigned long parent)
{
int fp,i;
	fp=open(DIR_INFO_FILE,2);	
	if(fp==-1){
		perror("open:");
		printf("\nError No:%d",errno);
		close(fp);
		return -1;
		}
				
	lseek(fp,0,2);				/* Set file pointer to end */
	
	/*  Don't Call during installation.*/
	
	if(install==0){
	i=check4dir_dups(parent);
	CHECK
		if(i==0){	/* Already we have it */
		close(fp);
		return 1;
		}
	}

						/* date n time */
		result = time(NULL);
                strcpy(date_time,asctime(localtime(&result)));
		strcpy(giis_d.info.date_time,date_time);	
		
	if(entry==0){				/* entry and found are Global */
		giis_d.info.inode_number=ide.de.inode; /* current inode */
		for(i=0;i<ide.de.name_len;i++)
		giis_d.info.name[i]=ide.de.name[i];
		giis_d.info.name[i]='\0';
		close(fp);
		return 1;
	}
	if(entry==1){
		giis_d.info.parent_inode_number=ide.de.inode;
		giis_d.info.search_flag=0;
		i=write(fp,giis_d.buffer,GIIS_DSIZE);
		if(i!=GIIS_DSIZE){
			perror("write():");
			printf("\nError No:%d",errno);
			close(fp);
			return -1;
		}
	close(fp);
	return 1;
	}
	if(entry>=2 && !found)
		giis_d.info.parent_inode_number=giis_d.info.inode_number;
		found=1;
		for(i=0;i<ide.de.name_len;i++)
		giis_d.info.name[i]=ide.de.name[i];
		giis_d.info.name[i]='\0';
		
		giis_d.info.inode_number=ide.de.inode;
		if(giis_d.info.name[0]=='.'){	/* don't save system files except . and .. */
		close(fp);return 1;
		} 
	giis_d.info.search_flag=0;

	if((strcmp(giis_d.info.name,"root")==0 )){
			giis_d.info.search_flag=1;
			root_inode=giis_d.info.inode_number;
			}
		
	if((strcmp(giis_d.info.name,"home")==0 )){
			giis_d.info.search_flag=1;
			home_inode=giis_d.info.inode_number;
			}

	
	if(update_dir){	/* Record all dir found during updates */
	giis_d.info.search_flag=1;
	giis_d.info.parent_inode_number=parent;

	}
	
				
		i=write(fp,giis_d.buffer,GIIS_DSIZE);
		if(i!=GIIS_DSIZE){
			perror(" write()");
			printf("\nError No:%d \t fp=%d",errno,fp);
			close(fp);
			return -1;
		}
close(fp);
return 1;
}

/*
* record_file() records  file informations necessary for recovery.
* file is system file which often begins with "." then don't record it for obvious reason.
* Since that's not created by any users.
*
* Modification for giis2.1:
*
* Makes a call to check4file_dups().
*/

int record_file(unsigned long parent)
{
	int fp,i;

	if(ide.de.name[0]=='.')	
	return 1;
	
	fp=open(FILE_INFO_FILE,1);	
	if(fp==-1){
		perror("open:");
		printf("\nError No:%d",errno);
		close(fp);
		return -1;
		}
	lseek(fp,0,2);				/* Set file pointer to end */
						/* date n time */
		result = time(NULL);
                strcpy(date_time,asctime(localtime(&result)));
		strcpy(giis_f.info.date_time,date_time);	
		

		/* Get  inode  details */
		
		fs.inode_number=ide.de.inode;
		i=find_inode_offset();
		CHECK

		i=read_inode();
		CHECK
	
	/* Store files iff it's a new one or it's old one with some contents modified and
	   Don't Called during installation.*/
	if(install==0){
	i=check4file_dups(parent);
	CHECK
		if(i==0){	/* Already we have it */
		close(fp);
		return 1;
		}
	}
		
		for(i=0;i<ide.de.name_len;i++)
		giis_f.info.name[i]=ide.de.name[i];
		giis_f.info.name[i]='\0';
		giis_f.info.inode_number=ide.de.inode;
		giis_f.info.parent_inode_number=parent;	/*Same parent 4 all files in dir*/ 
	        giis_f.info.mode=iin.in.i_mode;		  
		giis_f.info.owner=iin.in.i_uid;
		giis_f.info.file_blocks_count=iin.in.i_blocks;	  
		giis_f.info.file_size=iin.in.i_size;		
		giis_f.info.file_flags=iin.in.i_flags;	
		giis_f.info.search_flag=0;



	giis_f.info.last_data_block=0;
	for(i=0;i<15;i++){
		giis_f.info.data_block[i]=iin.in.i_block[i];
		/* Store block number of files<48KB size */
		if(iin.in.i_block[i]==0 && i<=12 &&!giis_f.info.last_data_block)
        	giis_f.info.last_data_block=iin.in.i_block[i-1];
	}
	
			/* Error check 4 some raw error check details */
			
	if(iin.in.i_block[0]==iin.in.i_block[1])
	return 1;
	if(iin.in.i_size>49152 && (iin.in.i_block[12]==0) )
	return 1;
	if(iin.in.i_size<49512 && (iin.in.i_block[12]!=0))
	return 1;
	if(iin.in.i_block[14]!=0)	/* Not supported */
	return 1;
	
	
	
			/* Set flags */
			
	giis_f.info.sfragment_flag=0;		/* Fragment level for single indirect*/
	giis_f.info.dfragment_flag=0;		/* Do the Same for double */
	giis_f.info.is_offset=0;
	giis_f.info.id_offset=0;

	
	if(iin.in.i_size>=49152 ){

		if(giis_f.info.data_block[12]!=0){
		i=search4sequence12();
		CHECK
		}
	
	if(giis_f.info.data_block[13]!=0){

		round=0;hole=0;	/* used in search4sequence13 */
		giis_f.info.last_data_block=0;
		i=search4sequence13();
		CHECK
		}

	}	



		i=write(fp,giis_f.buffer,GIIS_FSIZE);
		if(i!=GIIS_FSIZE){
			perror(" write():");
			printf("\nError No:%d",errno);
			close(fp);
			return -1;
		}
		
		
		
close(fp);
return 1;
}
	
/*
* show_dir() displays the content of the requested  directory inode.
* And during installation stores file and directory entries.
*
* Modification for giis2:
*
* Introduce new variable  install_file with it's help we first store all directory 
* informations first. Once all directories are recorded then we start to record files
* from these directories.
*
* Modification for giis2.1:
*
* update_dir variable to update directories.
*/

int show_dir(){
int i;
unsigned long long temp_content_offset,parent; /* So that we don't mess up original offset */
		temp_content_offset=fs.content_offset;

		while((ide.de.rec_len!=0)&&(ide.de.rec_len%4==0)){
		
		/*First entry is current directory inode */		

		if((entry==0) && (ide.de.file_type==2)){
				parent=ide.de.inode;
				}
				
	if(update_dir && (ide.de.file_type==2)){
				record_dir(parent);
				entry++;
				}
	if(update_dir==0){
	
	if((update_file==0) && (install_file==0) && (ide.de.file_type==2)){	
			record_dir(parent);	/*Install:Record data in DIR_INFO_FILE*/	
			entry++;
			}
		
	if((update_file || install_file) && (ide.de.file_type!=2) && (ide.de.file_type!=0)){
						/*Record data in FILE_INFO_FILE*/
				record_file(parent);
			}
	}
			temp_content_offset+=ide.de.rec_len; /* Next entry */ 
			i=lseek64(fd,temp_content_offset,0);
			i=read(fd,ide.buffer,DIR_SIZE);
		}
		
		/* reset for next directories */
entry=0;
found=0;
return 1;
}
	
				



