1 /*
2 
3 /usr/src/ext2ed/blockbitmap_com.c
4 
5 A part of the extended file system 2 disk editor.
6 
7 -------------------------
8 Handles the block bitmap.
9 -------------------------
10 
11 This file implements the commands which are specific to the blockbitmap type.
12 
13 First written on: July 5 1995
14 
15 Copyright (C) 1995 Gadi Oxman
16 
17 */
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 
23 #include "ext2ed.h"
24 
25 /*
26 
27 The functions in this file use the flobal structure block_bitmap_info. This structure contains the current
28 position in the bitmap.
29 
30 */
31 
type_ext2_block_bitmap___entry(char * command_line)32 void type_ext2_block_bitmap___entry (char *command_line)
33 
34 /*
35 
36 This function changes the current entry in the bitmap. It just changes the entry_num variable in block_bitmap_info
37 and dispatches a show command to show the new entry.
38 
39 */
40 
41 {
42 	unsigned long entry_num;
43 	char *ptr,buffer [80];
44 
45 
46 
47 	ptr=parse_word (command_line,buffer);					/* Get the requested entry */
48 	if (*ptr==0) {
49 		wprintw (command_win,"Error - No argument specified\n");
50 		refresh_command_win ();	return;
51 	}
52 	ptr=parse_word (ptr,buffer);
53 
54 	entry_num=atol (buffer);
55 
56 
57 	if (entry_num >= file_system_info.super_block.s_blocks_per_group) {	/* Check if it is a valid entry number */
58 
59 		wprintw (command_win,"Error - Entry number out of bounds\n");
60 		refresh_command_win ();return;
61 	}
62 
63 
64 
65 	block_bitmap_info.entry_num=entry_num;					/* If it is, just change entry_num and */
66 	strcpy (buffer,"show");dispatch (buffer);				/* dispatch a show command */
67 }
68 
type_ext2_block_bitmap___next(char * command_line)69 void type_ext2_block_bitmap___next (char *command_line)
70 
71 /*
72 
73 This function passes to the next entry in the bitmap. We just call the above entry command.
74 
75 */
76 
77 {
78 	long entry_offset=1;
79 	char *ptr,buffer [80];
80 
81 	ptr=parse_word (command_line,buffer);
82 	if (*ptr!=0) {
83 		ptr=parse_word (ptr,buffer);
84 		entry_offset=atol (buffer);
85 	}
86 
87 	sprintf (buffer,"entry %ld",block_bitmap_info.entry_num+entry_offset);
88 	dispatch (buffer);
89 }
90 
type_ext2_block_bitmap___prev(char * command_line)91 void type_ext2_block_bitmap___prev (char *command_line)
92 
93 {
94 	long entry_offset=1;
95 	char *ptr,buffer [80];
96 
97 	ptr=parse_word (command_line,buffer);
98 	if (*ptr!=0) {
99 		ptr=parse_word (ptr,buffer);
100 		entry_offset=atol (buffer);
101 	}
102 
103 	sprintf (buffer,"entry %ld",block_bitmap_info.entry_num-entry_offset);
104 	dispatch (buffer);
105 }
106 
type_ext2_block_bitmap___allocate(char * command_line)107 void type_ext2_block_bitmap___allocate (char *command_line)
108 
109 /*
110 
111 This function starts allocating block from the current position. Allocating involves setting the correct bits
112 in the bitmap. This function is a vector version of allocate_block below - We just run on the blocks that
113 we need to allocate, and call allocate_block for each one.
114 
115 */
116 
117 {
118 	long entry_num,num=1;
119 	char *ptr,buffer [80];
120 
121 	ptr=parse_word (command_line,buffer);					/* Get the number of blocks to allocate */
122 	if (*ptr!=0) {
123 		ptr=parse_word (ptr,buffer);
124 		num=atol (buffer);
125 	}
126 
127 	entry_num=block_bitmap_info.entry_num;
128 										/* Check for limits */
129 	if (num > file_system_info.super_block.s_blocks_per_group-entry_num) {
130 		wprintw (command_win,"Error - There aren't that much blocks in the group\n");
131 		refresh_command_win ();return;
132 	}
133 
134 	while (num) {								/* And call allocate_block */
135 		allocate_block (entry_num);					/* for each block */
136 		num--;entry_num++;
137 	}
138 
139 	dispatch ("show");							/* Show the result */
140 }
141 
type_ext2_block_bitmap___deallocate(char * command_line)142 void type_ext2_block_bitmap___deallocate (char *command_line)
143 
144 /* This is the opposite of the above function - We call deallocate_block instead of allocate_block */
145 
146 {
147 	long entry_num,num=1;
148 	char *ptr,buffer [80];
149 
150 	ptr=parse_word (command_line,buffer);
151 	if (*ptr!=0) {
152 		ptr=parse_word (ptr,buffer);
153 		num=atol (buffer);
154 	}
155 
156 	entry_num=block_bitmap_info.entry_num;
157 	if (num > file_system_info.super_block.s_blocks_per_group-entry_num) {
158 		wprintw (command_win,"Error - There aren't that much blocks in the group\n");
159 		refresh_command_win ();return;
160 	}
161 
162 	while (num) {
163 		deallocate_block (entry_num);
164 		num--;entry_num++;
165 	}
166 
167 	dispatch ("show");
168 }
169 
170 
allocate_block(long entry_num)171 void allocate_block (long entry_num)
172 
173 /* In this function we convert the bit number into the right byte and inner bit positions. */
174 
175 {
176 	unsigned char bit_mask=1;
177 	int byte_offset,j;
178 
179 	byte_offset=entry_num/8;					/* Find the correct byte - entry_num/8 */
180 									/* The position inside the byte is entry_num %8 */
181 	for (j=0;j<entry_num%8;j++)
182 		bit_mask*=2;						/* Generate the or mask - 1 at the right place */
183 	type_data.u.buffer [byte_offset] |= bit_mask;			/* And apply it */
184 }
185 
deallocate_block(long entry_num)186 void deallocate_block (long entry_num)
187 
188 /* This is the opposite of allocate_block above. We use an and mask instead of an or mask. */
189 
190 {
191 	unsigned char bit_mask=1;
192 	int byte_offset,j;
193 
194 	byte_offset=entry_num/8;
195 	for (j=0;j<entry_num%8;j++)
196 		bit_mask*=2;
197 	bit_mask^=0xff;
198 
199 	type_data.u.buffer [byte_offset] &= bit_mask;
200 }
201 
type_ext2_block_bitmap___show(char * command_line)202 void type_ext2_block_bitmap___show (char *command_line)
203 
204 /*
205 
206 We show the bitmap as a series of bits, grouped at 8-bit intervals. We display 8 such groups on each line.
207 The current position (as known from block_bitmap_info.entry_num) is highlighted.
208 
209 */
210 
211 {
212 	int i,j;
213 	unsigned char *ptr;
214 	unsigned long block_num,entry_num;
215 
216 	ptr=type_data.u.buffer;
217 	show_pad_info.line=0;show_pad_info.max_line=-1;
218 
219 	wmove (show_pad,0,0);
220 	for (i=0,entry_num=0;i<file_system_info.super_block.s_blocks_per_group/8;i++,ptr++) {
221 		for (j=1;j<=128;j*=2) {						/* j contains the and bit mask */
222 			if (entry_num==block_bitmap_info.entry_num) {		/* Highlight the current entry */
223 				wattrset (show_pad,A_REVERSE);
224 				show_pad_info.line=show_pad_info.max_line-show_pad_info.display_lines/2;
225 			}
226 
227 			if ((*ptr) & j)						/* Apply the mask */
228 				wprintw (show_pad,"1");
229 			else
230 				wprintw (show_pad,"0");
231 
232 			if (entry_num==block_bitmap_info.entry_num)
233 				wattrset (show_pad,A_NORMAL);
234 
235 			entry_num++;						/* Pass to the next entry */
236 		}
237 		wprintw (show_pad," ");
238 		if (i%8==7) {							/* Display 8 groups in a row */
239 			wprintw (show_pad,"\n");
240 			show_pad_info.max_line++;
241 		}
242 	}
243 
244 	refresh_show_pad ();
245 	show_info ();								/* Show the usual information */
246 
247 										/* Show the group number */
248 	wmove (show_win,1,0);
249 	wprintw (show_win,"Block bitmap of block group %ld\n",block_bitmap_info.group_num);
250 										/* Show the block number */
251 
252 	block_num=block_bitmap_info.entry_num+block_bitmap_info.group_num*file_system_info.super_block.s_blocks_per_group;
253 	block_num+=file_system_info.super_block.s_first_data_block;
254 
255 	wprintw (show_win,"Status of block %ld - ",block_num);			/* and the allocation status */
256 	ptr=type_data.u.buffer+block_bitmap_info.entry_num/8;
257 	j=1;
258 	for (i=block_bitmap_info.entry_num % 8;i>0;i--)
259 		j*=2;
260 	if ((*ptr) & j)
261 		wprintw (show_win,"Allocated\n");
262 	else
263 		wprintw (show_win,"Free\n");
264 	refresh_show_win ();
265 }
266