blob: 5e1cd7e2a6c290848aa5db9b674d781714567d28 [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
Theodore Ts'oefc6f622008-08-27 23:07:54 -040058#endif
Theodore Ts'o583a1ce2002-05-11 13:00:22 -040059
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 };
Theodore Ts'oefc6f622008-08-27 23:07:54 -040070
Theodore Ts'o583a1ce2002-05-11 13:00:22 -040071 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];
Theodore Ts'oefc6f622008-08-27 23:07:54 -040086
Theodore Ts'o583a1ce2002-05-11 13:00:22 -040087 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 }
Theodore Ts'oefc6f622008-08-27 23:07:54 -040098
Theodore Ts'o583a1ce2002-05-11 13:00:22 -040099 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
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400110#endif
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400111
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
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400127 wprintw (command_win,"Data written");refresh_command_win ();
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400128 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;
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400142
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400143 int i;
144 time_t current_time;
145 FILE *fp;
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400146
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400147 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);
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400153
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400154 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);
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400157
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400158 original=(unsigned char *) malloc (length*sizeof (unsigned char));
159
160 if (original==NULL) {
Theodore Ts'o598ff012005-12-09 19:16:40 -0500161 wprintw (command_win,"Fatal error - Can\'t allocate %lu bytes!");
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400162 refresh_command_win ();fclose (fp);return (0);
163 }
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400164
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400165 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 }
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400175
176 fprintf (fp,"\n\nNew data:\n\n");
177
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400178 for (i=0;i<length;i++) {
179 if (i%16==0 && i!=0) fprintf (fp,"\n");
180 fprintf (fp,"%02x ",buffer [i]);
181 }
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400182
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400183 fprintf (fp,"\n----- EXT2ED log end -----\n");
184
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400185 fclose (fp);
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400186 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");
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400200 return (0);
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400201 }
202
203 if (device_offset==-1) {
204 printf ("Error - No offset set\n");
205 return (0);
206 }
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400207
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400208 if (low_read (type_data.u.buffer,EXT2_MAX_BLOCK_SIZE,device_offset)==0)
209 return (0);
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400210
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400211 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 ();
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400224 return (0);
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400225 }
226
227 if (device_offset==-1) {
228 wprintw (command_win,"Error - No offset set\n");
229 refresh_command_win ();
230 return (0);
231 }
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400232
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400233 if (low_write (type_data.u.buffer,file_system_info.block_size,device_offset)==0)
234 return (0);
Theodore Ts'oefc6f622008-08-27 23:07:54 -0400235
Theodore Ts'o583a1ce2002-05-11 13:00:22 -0400236 return (1);
237}
238