]>
Commit | Line | Data |
---|---|---|
583a1ce5 TT |
1 | /* |
2 | ||
3 | /usr/src/ext2ed/disk.c | |
4 | ||
5 | A part of the extended file system 2 disk editor. | |
6 | ||
7 | ------------------------------------------------- | |
8 | The filesystem's disk activity pass through here. | |
9 | ------------------------------------------------- | |
10 | ||
11 | This file is acting as a filter - Before we pass an actual read or write request to the operating system, we | |
12 | double check the various permissions and possible errors here. | |
13 | ||
14 | The major update which needs to be done here is switching to the use of the llseek system call, so that we will | |
15 | be able to support ext2 filesystems up to 4 TB. Currently, due to the standard fseek usage, we can't handle | |
16 | filesystems bigger than 4 GB. The limit is actually 2 GB because I used long rather than unsigned long long at too | |
055866d8 | 17 | many places in the program. To conclude - This upgrade needs to be done carefully; There are many places to change. |
583a1ce5 TT |
18 | |
19 | First written on: April 9 1995 | |
20 | ||
21 | Copyright (C) 1995 Gadi Oxman | |
22 | ||
23 | */ | |
24 | ||
d1154eb4 | 25 | #include "config.h" |
583a1ce5 TT |
26 | #include <stdio.h> |
27 | #include <stdlib.h> | |
28 | #include <string.h> | |
29 | #include <time.h> | |
30 | ||
31 | #include "ext2ed.h" | |
32 | ||
33 | int write_access; | |
34 | ||
35 | int low_read (unsigned char *buffer,unsigned long length,unsigned long offset) | |
36 | ||
37 | /* | |
38 | ||
39 | This function is used when we need to read something from the filesystem. | |
40 | ||
41 | */ | |
42 | ||
43 | { | |
44 | ||
45 | #ifdef DEBUG | |
46 | ||
47 | char temp [80]; | |
48 | ||
49 | if (device_handle==NULL) { /* Check that a device is indeed open */ | |
50 | internal_error ("No device opened yet read requested","disk","low_read"); | |
51 | return (0); | |
52 | } | |
53 | if (offset > file_system_info.file_system_size) { /* Check that the offset is within limits */ | |
54 | sprintf (temp,"Seek offset %ld is out of range",offset); | |
55 | internal_error (temp,"disk","low_read"); | |
56 | return (0); | |
57 | } | |
58 | ||
efc6f628 | 59 | #endif |
583a1ce5 TT |
60 | |
61 | if ( (fseek (device_handle,offset,SEEK_SET))==-1) { /* Seek to the required offset */ | |
62 | wprintw (command_win,"Error - Failed to seek to offset %ld in device %s\n",offset,device_name); | |
63 | refresh_command_win (); | |
64 | return (0); | |
65 | }; | |
66 | ||
67 | if ( (fread (buffer,1,length,device_handle))==-1) { /* And do the actual reading */ | |
68 | wprintw (command_win,"Error - Failed to read from offset %ld in device %s\n",offset,device_name); | |
69 | refresh_command_win ();return (0); | |
70 | }; | |
efc6f628 | 71 | |
583a1ce5 TT |
72 | return (1); |
73 | } | |
74 | ||
75 | int low_write (unsigned char *buffer,unsigned long length,unsigned long offset) | |
76 | ||
77 | /* | |
78 | ||
79 | This is used to change something in the filesystem. | |
80 | write_access is checked to see if we are allowed to do the actual writing. | |
81 | As a double safety measure, AllowChanges is rechecked here. | |
82 | If logging is enabled, we log the change before writing it to the device. | |
83 | ||
84 | */ | |
85 | { | |
86 | char temp [80]; | |
efc6f628 | 87 | |
583a1ce5 | 88 | if (!write_access) { |
ce20096f | 89 | wprintw (command_win,"Error - Write access not available (use enablewrite)\n"); |
583a1ce5 TT |
90 | return (0); |
91 | } | |
92 | ||
93 | #ifdef DEBUG | |
94 | ||
95 | if (!AllowChanges) { | |
96 | internal_error ("AllowChanges=0 yet enablewrite succeeded","disk","low_write"); | |
97 | return (0); | |
98 | } | |
efc6f628 | 99 | |
583a1ce5 TT |
100 | if (device_handle==NULL) { |
101 | internal_error ("No device opened yet read requested","disk","low_write"); | |
102 | return (0); | |
103 | } | |
104 | ||
105 | if (offset > file_system_info.file_system_size) { | |
106 | sprintf (temp,"Seek offset %ld is out of range",offset); | |
107 | internal_error (temp,"disk","low_write"); | |
108 | return (0); | |
109 | } | |
110 | ||
efc6f628 | 111 | #endif |
583a1ce5 TT |
112 | |
113 | if (LogChanges) | |
114 | if (!log_changes (buffer,length,offset)) | |
115 | return (0); | |
116 | ||
117 | if ( (fseek (device_handle,offset,SEEK_SET))==-1) { | |
118 | wprintw (command_win,"Error - Failed to seek to offset %ld in device %s\n",offset,device_name); | |
119 | refresh_command_win ();return (0); | |
120 | }; | |
121 | ||
122 | ||
123 | if ( (fwrite (buffer,1,length,device_handle))==-1) { | |
124 | wprintw (command_win,"Error - Failed to write to offset %ld in device %s\n",offset,device_name); | |
125 | refresh_command_win ();return (0); | |
126 | }; | |
127 | ||
efc6f628 | 128 | wprintw (command_win,"Data written");refresh_command_win (); |
583a1ce5 TT |
129 | return (1); |
130 | } | |
131 | ||
132 | int log_changes (unsigned char *buffer,unsigned long length,unsigned long offset) | |
133 | ||
134 | /* | |
135 | ||
136 | Log the change in a primitive form - An hex dump of the data before the change and after the change. | |
137 | The hex bytes are converted to text, so that they will be readable with a standard text editor. | |
138 | ||
139 | */ | |
140 | ||
141 | { | |
142 | unsigned char *original; | |
efc6f628 | 143 | |
583a1ce5 TT |
144 | int i; |
145 | time_t current_time; | |
146 | FILE *fp; | |
efc6f628 | 147 | |
583a1ce5 TT |
148 | if ((fp=fopen (LogFile,"a+"))==NULL) { |
149 | wprintw (command_win,"Error - Unable to open log file %s\n",LogFile); | |
150 | refresh_command_win ();return (0); | |
151 | }; | |
152 | ||
153 | current_time=time (NULL); | |
efc6f628 | 154 | |
583a1ce5 TT |
155 | fprintf (fp,"\n----- EXT2ED log begin -----\n\n"); |
156 | fprintf (fp,"Time: %s\nDevice: %s\n",ctime ((time_t *) ¤t_time),device_name); | |
157 | fprintf (fp,"Offset: %lu\nLength: %lu\n",offset,length); | |
efc6f628 | 158 | |
583a1ce5 TT |
159 | original=(unsigned char *) malloc (length*sizeof (unsigned char)); |
160 | ||
161 | if (original==NULL) { | |
598ff014 | 162 | wprintw (command_win,"Fatal error - Can\'t allocate %lu bytes!"); |
583a1ce5 TT |
163 | refresh_command_win ();fclose (fp);return (0); |
164 | } | |
efc6f628 | 165 | |
583a1ce5 TT |
166 | if (!low_read (original,length,offset)) { |
167 | fclose (fp);return (0); | |
168 | } | |
169 | ||
170 | fprintf (fp,"\nOriginal data:\n\n"); | |
171 | ||
172 | for (i=0;i<length;i++) { | |
173 | if (i%16==0 && i!=0) fprintf (fp,"\n"); | |
174 | fprintf (fp,"%02x ",original [i]); | |
175 | } | |
efc6f628 TT |
176 | |
177 | fprintf (fp,"\n\nNew data:\n\n"); | |
178 | ||
583a1ce5 TT |
179 | for (i=0;i<length;i++) { |
180 | if (i%16==0 && i!=0) fprintf (fp,"\n"); | |
181 | fprintf (fp,"%02x ",buffer [i]); | |
182 | } | |
efc6f628 | 183 | |
583a1ce5 TT |
184 | fprintf (fp,"\n----- EXT2ED log end -----\n"); |
185 | ||
efc6f628 | 186 | fclose (fp); |
583a1ce5 TT |
187 | return (1); |
188 | } | |
189 | ||
190 | int load_type_data (void) | |
191 | ||
192 | /* | |
193 | ||
194 | Just read from the current position into type data. | |
195 | ||
196 | */ | |
197 | ||
198 | { | |
199 | if (device_handle==NULL) { | |
200 | printf ("Error - No device opened\n"); | |
efc6f628 | 201 | return (0); |
583a1ce5 TT |
202 | } |
203 | ||
204 | if (device_offset==-1) { | |
205 | printf ("Error - No offset set\n"); | |
206 | return (0); | |
207 | } | |
efc6f628 | 208 | |
583a1ce5 TT |
209 | if (low_read (type_data.u.buffer,EXT2_MAX_BLOCK_SIZE,device_offset)==0) |
210 | return (0); | |
efc6f628 | 211 | |
583a1ce5 TT |
212 | if (current_type!=NULL) |
213 | if (strcmp (current_type->name,"ext2_dir_entry")==0) | |
214 | current_type->length=type_data.u.t_ext2_dir_entry.rec_len; | |
215 | ||
216 | return (1); | |
217 | } | |
218 | ||
219 | int write_type_data (void) | |
220 | ||
221 | { | |
222 | if (device_handle==NULL) { | |
223 | wprintw (command_win,"Error - No device opened\n"); | |
224 | refresh_command_win (); | |
efc6f628 | 225 | return (0); |
583a1ce5 TT |
226 | } |
227 | ||
228 | if (device_offset==-1) { | |
229 | wprintw (command_win,"Error - No offset set\n"); | |
230 | refresh_command_win (); | |
231 | return (0); | |
232 | } | |
efc6f628 | 233 | |
583a1ce5 TT |
234 | if (low_write (type_data.u.buffer,file_system_info.block_size,device_offset)==0) |
235 | return (0); | |
efc6f628 | 236 | |
583a1ce5 TT |
237 | return (1); |
238 | } | |
239 |