/*

/usr/src/ext2ed/inodebitmap_com.c

A part of the extended file system 2 disk editor.

-------------------------
Handles the inode bitmap.
-------------------------

Please refer to the documentation in blockbitmap_com.c - Those two files are almost equal.

First written on: July 25 1995

Copyright (C) 1995 Gadi Oxman

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "ext2ed.h"


void type_ext2_inode_bitmap___entry (char *command_line)

{
	unsigned long entry_num;
	char *ptr,buffer [80];
	
	ptr=parse_word (command_line,buffer);
	if (*ptr==0) {
		wprintw (command_win,"Error - No argument specified\n");refresh_command_win ();return;
	}
	ptr=parse_word (ptr,buffer);

	entry_num=atol (buffer);
	
	if (entry_num >= file_system_info.super_block.s_inodes_per_group) {
		wprintw (command_win,"Error - Entry number out of bounds\n");refresh_command_win ();return;
	}
	
	inode_bitmap_info.entry_num=entry_num;
	strcpy (buffer,"show");dispatch (buffer);
}

void type_ext2_inode_bitmap___next (char *command_line)

{
	long entry_offset=1;
	char *ptr,buffer [80];
	
	ptr=parse_word (command_line,buffer);
	if (*ptr!=0) {
		ptr=parse_word (ptr,buffer);
		entry_offset=atol (buffer);
	}

	sprintf (buffer,"entry %ld",inode_bitmap_info.entry_num+entry_offset);
	dispatch (buffer);
}

void type_ext2_inode_bitmap___prev (char *command_line)

{
	long entry_offset=1;
	char *ptr,buffer [80];
	
	ptr=parse_word (command_line,buffer);
	if (*ptr!=0) {
		ptr=parse_word (ptr,buffer);
		entry_offset=atol (buffer);
	}

	sprintf (buffer,"entry %ld",inode_bitmap_info.entry_num-entry_offset);
	dispatch (buffer);
}

void type_ext2_inode_bitmap___allocate (char *command_line)

{
	long entry_num,num=1;
	char *ptr,buffer [80];
	
	ptr=parse_word (command_line,buffer);
	if (*ptr!=0) {
		ptr=parse_word (ptr,buffer);
		num=atol (buffer);
	}
	
	entry_num=inode_bitmap_info.entry_num;
	if (num > file_system_info.super_block.s_inodes_per_group-entry_num) {
		wprintw (command_win,"Error - There aren't that much inodes in the group\n");	
		refresh_command_win ();return;				
	}
	
	while (num) {
		allocate_inode (entry_num);
		num--;entry_num++;
	}
	
	dispatch ("show");
}

void type_ext2_inode_bitmap___deallocate (char *command_line)

{
	long entry_num,num=1;
	char *ptr,buffer [80];
	
	ptr=parse_word (command_line,buffer);
	if (*ptr!=0) {
		ptr=parse_word (ptr,buffer);
		num=atol (buffer);
	}
	
	entry_num=inode_bitmap_info.entry_num;
	if (num > file_system_info.super_block.s_inodes_per_group-entry_num) {
		wprintw (command_win,"Error - There aren't that much inodes in the group\n");	
		refresh_command_win ();return;				
	}
	
	while (num) {
		deallocate_inode (entry_num);
		num--;entry_num++;
	}
	
	dispatch ("show");
}


void allocate_inode (long entry_num)

{
	unsigned char bit_mask=1;
	int byte_offset,j;
	
	byte_offset=entry_num/8;
	for (j=0;j<entry_num%8;j++)
		bit_mask*=2;
	type_data.u.buffer [byte_offset] |= bit_mask;
}

void deallocate_inode (long entry_num)

{
	unsigned char bit_mask=1;
	int byte_offset,j;
	
	byte_offset=entry_num/8;
	for (j=0;j<entry_num%8;j++)
		bit_mask*=2;
	bit_mask^=0xff;
	
	type_data.u.buffer [byte_offset] &= bit_mask;
}

void type_ext2_inode_bitmap___show (char *command_line)

{
	int i,j;
	unsigned char *ptr;
	unsigned long inode_num,entry_num;

	ptr=type_data.u.buffer;
	show_pad_info.line=0;show_pad_info.max_line=-1;
	
	wmove (show_pad,0,0);
	for (i=0,entry_num=0;i<file_system_info.super_block.s_inodes_per_group/8;i++,ptr++) {
		for (j=1;j<=128;j*=2) {
			if (entry_num==inode_bitmap_info.entry_num) {
				wattrset (show_pad,A_REVERSE);
				show_pad_info.line=show_pad_info.max_line-show_pad_info.display_lines/2;
			}

			if ((*ptr) & j)
				wprintw (show_pad,"1");
			else
				wprintw (show_pad,"0");

			if (entry_num==inode_bitmap_info.entry_num)
				wattrset (show_pad,A_NORMAL);

			entry_num++;
		}
		wprintw (show_pad," ");
		if (i%8==7) {
			wprintw (show_pad,"\n");
			show_pad_info.max_line++;
		}
	}
	
	if (i%8!=7) {
		wprintw (show_pad,"\n");
		show_pad_info.max_line++;
	}

	refresh_show_pad ();	
	show_info ();
	wmove (show_win,1,0);wprintw (show_win,"Inode bitmap of block group %ld\n",inode_bitmap_info.group_num);

	inode_num=1+inode_bitmap_info.entry_num+inode_bitmap_info.group_num*file_system_info.super_block.s_inodes_per_group;
	wprintw (show_win,"Status of inode %ld - ",inode_num);
	ptr=type_data.u.buffer+inode_bitmap_info.entry_num/8;
	j=1;
	for (i=inode_bitmap_info.entry_num % 8;i>0;i--)
		j*=2;
	if ((*ptr) & j)
		wprintw (show_win,"Allocated\n");
	else
		wprintw (show_win,"Free\n");
	refresh_show_win ();
}
