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