/* 
* /giis/init.c This file  Initialize file system informations.
*
* Copyright (C)  2005. G.Lakshmipathi.<lakshmipathi_g@rediffmail.com>
*
*/

#include"giis.h"

/*
* init() - Just invokes other init functions
*/

int init()
{
	if(search4fs()==-1){
		printf("\nFile system Not Detected....Aborting\n");
		return -1;
		}
	else
 	printf("found.\n\tDetected file system %s ",device_name);
 	
	printf("\n\nSearching for Superblock....");
	

	if(search4super_block()==-1){
		printf("\nCan't  find Super block...Aborting\n");
		return -1;
		}
	else
		printf("found.\n\tSuper block is at %u.\n\nGathering informations.......",fs.super_block_offset);
		
	
	set_file_system();
	
	if(search4group_desc()==-1){
		printf("\nUnable to initialize Group Descriptor...Aborting\n");
		return -1;
		}
	else
		printf("\n\tGroup Descriptor found.");
		
	if(init_files()==-1){
		printf("\n\n Files not initialized Aborting....");
		return	-1;
		}
	else
		printf("\n\nAll files are Initialized...");

return 1;
}
			
/*
* search4fs() will search for device name in /etc/mtab file. 
*/		

int search4fs(){
	int fp,i=0,c=1;
	char a;
		fp=open("/etc/mtab",0);
		if(fp==-1)
			ERROR	
		do{
		i=read(fp,&a,1);
		CHECK
		}while(a!='/');
		c=0;
		while(a!=' '){
		device_name[c]=a;
		c++;
		i=read(fp,&a,1);
		}
		device_name[c]='\0';
		i=open(device_name,0);
}

/*
* search4super_block() - Search for super block in the file system. 
*/

int search4super_block()
{
int i,offset=DEFAULT_OFFSET_OF_SUPER_BLOCK;
	
	fd=open(device_name,ACCESS);
		if(fd==-1)
			ERROR
	/*
	Now we opened the devide say /dev/hda7 Then search for superblock on its
	offset which is normally at 1024
	*/
	while(offset<4096)
		{
		lseek(fd,offset,0);
		i=read(fd,isb.buffer,SUPER_BLOCK_SIZE);
		if(i==-1)
			ERROR
		if(isb.sb.s_magic==61267)
			{
			fs.super_block_offset=offset;
			return 1;
			}
		offset+=offset;
		}
return -1;
}

/*
* set_file_system()- Initialize  file system details.
*/

	
void set_file_system(){
int i,pow;
	fs.inodes_per_group=isb.sb.s_inodes_per_group;
	fs.blocks_per_group=isb.sb.s_blocks_per_group;
	fs.inodes_count=isb.sb.s_inodes_count;
	fs.blocks_count=isb.sb.s_blocks_count;
	for(i=1,pow=1;i<=isb.sb.s_log_block_size;i++)
	pow=pow*2;	
	fs.block_size=1024*pow;
	fs.inodes_per_block= fs.block_size/INODE_SIZE;
	fs.inode_table_size=fs.inodes_per_group/fs.inodes_per_block;
	fs.first_data_block=isb.sb.s_first_data_block;
	fs.first_group_desc=fs.block_size;
fs.groups_count=(fs.blocks_count-fs.first_data_block+fs.blocks_per_group)/fs.blocks_per_group;
printf(" recorded...proceed...");
}

/* 
* search4group_desc() - Initialize Group descriptor details. 
*/

int search4group_desc(){
int i;
		lseek(fd,fs.first_group_desc,0);
		i=read(fd,igd.buffer,GROUP_DESC_SIZE);
		CHECK
	
return 0;
}
		
/*
* init_files() - Create or open files or directories 
*/

int init_files(){
int fp;


	/* Create Directory. one can use O_CREAT | O_EXCL but i prefer...*/

		fp=open(INSTALL_DIR1,2);
		if(errno==ENOENT){
			fp=mkdir(INSTALL_DIR1,040777);
			if(fp==-1){	/* This error is can not be  ENOENT :) */
				perror("creat:");
				return -1;
				}	
			else{
			printf("\n\n Creating files....");
			printf("\n %s created...",INSTALL_DIR1);
			}

			}
		close(fp);
		
			/* Create Directory */
	
		fp=open(INSTALL_DIR2,2);
		if(errno==ENOENT){
			fp=mkdir(INSTALL_DIR2,040777);
			if(fp==-1){	
				perror("creat:");
				return -1;
				}	
			else
			printf("\n %s created...",INSTALL_DIR2);

			}
		close(fp);
		
			/* Create Directory */
	
		fp=open(INSTALL_DIR3,2);
		if(errno==ENOENT){
			fp=mkdir(INSTALL_DIR3,040777);
			if(fp==-1){	
				perror("creat:");
				return -1;
				}
			else
			printf("\n %s created...",INSTALL_DIR3);
	
			}
		close(fp);
		
	
		/* Create or open  DIR_INFO_FILE */
	
		fp=open(DIR_INFO_FILE,2);
		if(errno==ENOENT){
			fp=creat(DIR_INFO_FILE,0700); 
			if(fp==-1){	
				perror("creat:");
				return -1;
				}
			else
			printf("\n %s created...",DIR_INFO_FILE);
	
			}
		close(fp);
			
		/* Create or open  FILE_INFO_FILE */
	
		fp=open(FILE_INFO_FILE,2);
		if(errno==ENOENT){
			fp=creat(FILE_INFO_FILE,0700); 
			if(fp==-1){	
				perror("creat:");
				return -1;
				}	
			else
			printf("\n %s created...",FILE_INFO_FILE);

			}
		close(fp);
			
		/* Same ...  */
	
		fp=open(SIND_INFO_FILE,2);
		if(errno==ENOENT){
			fp=creat(SIND_INFO_FILE,0700); 
			if(fp==-1){	
				perror("creat:");
				return -1;
				}	
			else
			printf("\n %s created...",SIND_INFO_FILE);

			}
		close(fp);
			
		/* Same again.. */
		
		fp=open(DIND_INFO_FILE,2);
		if(errno==ENOENT){
			fp=creat(DIND_INFO_FILE,0700); 
			if(fp==-1){	
				perror("creat:");
				return -1;
				}	
			else
			printf("\n %s created...",DIND_INFO_FILE);
			}
		close(fp);
		
		/* Cut and Pasted  again except file name ;-) */
		
		fp=open(SAMPLE_DATA_FILE,2);
		if(errno==ENOENT){
			fp=creat(SAMPLE_DATA_FILE,0700); 
			if(fp==-1){	
				perror("creat:");
				return -1;
				}	
			else
			printf("\n %s created...",SAMPLE_DATA_FILE);
			}
		close(fp);
			//For Unrecoverable Files
		fp=open(INSTALL_DIR4,2);
		if(errno==ENOENT){
			fp=mkdir(INSTALL_DIR4,040777);
			if(fp==-1){	/* This error is can not be  ENOENT :) */
				perror("creat:");
				return -1;
				}	
			else{
			printf("\n %s created...",INSTALL_DIR4);
			}

			}
		close(fp);
		

			
		
return 1;
}
/*
* fs_display()	: Display file system details 
*/
int fs_display()
{
printf("\n\n");
printf("\n\t\t File System details of Your System ");
printf("\n\t\t -----------------------------------\n");
printf("\n\t Root Device       : %s " ,device_name);
printf("\n\t Magic Number      : %x ",isb.sb.s_magic);
printf("\n\t Root Inode offset : %u ",fs.root_inode_offset); 
printf("\n\t Total Inodes      : %u ",fs.inodes_count);
printf("\n\t Total Blocks      : %u ",fs.blocks_count);
printf("\n\t Inodes per Group  : %u ",fs.inodes_per_group);
printf("\n\t Blocks per Group  : %u ",fs.blocks_per_group);
printf("\n\t Block size        : %u ",fs.block_size);
printf("\n\t Inodes per Block  : %u ",fs.inodes_per_block);
printf("\n\t Inode Table size  : %u ",fs.inode_table_size);
printf("\n\t Groups count      : %u ",fs.groups_count);
return 1;
}


	


	
	
