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