]> git.ipfire.org Git - thirdparty/e2fsprogs.git/blame - e2fsck/util.c
ADD TAG: E2FSPROGS-1_06
[thirdparty/e2fsprogs.git] / e2fsck / util.c
CommitLineData
3839e657
TT
1/*
2 * util.c --- miscellaneous utilities
3 *
4 * Copyright (C) 1993, 1994 Theodore Ts'o. This file may be
5 * redistributed under the terms of the GNU Public License.
6 */
7
8#include <stdlib.h>
9#include <unistd.h>
10#include <string.h>
11#include <ctype.h>
12#include <termios.h>
3839e657
TT
13
14#include "e2fsck.h"
15
50e1e10f
TT
16#include <sys/time.h>
17#include <sys/resource.h>
18
3839e657
TT
19const char * fix_msg[2] = { "IGNORED", "FIXED" };
20const char * clear_msg[2] = { "IGNORED", "CLEARED" };
21
22void fatal_error (const char *msg)
23{
24 if (msg)
25 fprintf (stderr, "%s: %s\n", program_name, msg);
26 exit(FSCK_ERROR);
27}
28
29void *allocate_memory(int size, const char *description)
30{
31 void *ret;
32 char buf[256];
33
34#ifdef DEBUG_ALLOCATE_MEMORY
35 printf("Allocating %d bytes for %s...\n", size, description);
36#endif
37 ret = malloc(size);
38 if (!ret) {
7f88b043 39 sprintf(buf, "Can't allocate %s\n", description);
3839e657
TT
40 fatal_error(buf);
41 }
42 memset(ret, 0, size);
43 return ret;
44}
45
46
47int ask_yn(const char * string, int def)
48{
49 int c;
50 struct termios termios, tmp;
51 const char *defstr;
52
53 tcgetattr (0, &termios);
54 tmp = termios;
55 tmp.c_lflag &= ~(ICANON | ECHO);
50e1e10f
TT
56 tmp.c_cc[VMIN] = 1;
57 tmp.c_cc[VTIME] = 0;
3839e657
TT
58 tcsetattr (0, TCSANOW, &tmp);
59
60 if (def == 1)
61 defstr = "<y>";
62 else if (def == 0)
63 defstr = "<n>";
64 else
65 defstr = " (y/n)";
66 printf("%s%s? ", string, defstr);
67 while (1) {
68 fflush (stdout);
69 if ((c = getchar()) == EOF)
70 break;
71 c = toupper(c);
72 if (c == 'Y') {
73 def = 1;
74 break;
75 }
76 else if (c == 'N') {
77 def = 0;
78 break;
79 }
80 else if ((c == ' ' || c == '\n') && (def != -1))
81 break;
82 }
83 if (def)
84 printf ("yes\n\n");
85 else
86 printf ("no\n\n");
87 tcsetattr (0, TCSANOW, &termios);
88 return def;
89}
90
91int ask (const char * string, int def)
92{
93 if (nflag) {
94 printf ("%s? no\n\n", string);
95 return 0;
96 }
97 if (yflag) {
98 printf ("%s? yes\n\n", string);
99 return 1;
100 }
101 if (preen) {
102 printf ("%s? %s\n\n", string, def ? "yes" : "no");
103 return def;
104 }
105 return ask_yn(string, def);
106}
107
108void read_bitmaps(ext2_filsys fs)
109{
110 errcode_t retval;
111
f3db3566
TT
112 if (invalid_bitmaps) {
113 com_err(program_name, 0,
114 "read_bitmaps: illegal bitmap block(s) for %s",
115 device_name);
116 fatal_error(0);
3839e657 117 }
f3db3566
TT
118
119 ehandler_operation("reading inode and block bitmaps");
120 retval = ext2fs_read_bitmaps(fs);
121 ehandler_operation(0);
122 if (retval) {
123 com_err(program_name, retval,
124 "while retrying to read bitmaps for %s",
125 device_name);
126 fatal_error(0);
3839e657
TT
127 }
128}
129
130void write_bitmaps(ext2_filsys fs)
131{
132 errcode_t retval;
133
134 if (ext2fs_test_bb_dirty(fs)) {
135 ehandler_operation("writing block bitmaps");
136 retval = ext2fs_write_block_bitmap(fs);
137 ehandler_operation(0);
138 if (retval) {
139 com_err(program_name, retval,
140 "while retrying to write block bitmaps for %s",
141 device_name);
142 fatal_error(0);
143 }
144 }
145
146 if (ext2fs_test_ib_dirty(fs)) {
147 ehandler_operation("writing inode bitmaps");
148 retval = ext2fs_write_inode_bitmap(fs);
149 ehandler_operation(0);
150 if (retval) {
151 com_err(program_name, retval,
152 "while retrying to write inode bitmaps for %s",
153 device_name);
154 fatal_error(0);
155 }
156 }
157}
158
50e1e10f 159void preenhalt(ext2_filsys fs)
3839e657
TT
160{
161 if (!preen)
162 return;
5c576477
TT
163 fprintf(stderr, "\n\n%s: UNEXPECTED INCONSISTENCY; "
164 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n",
3839e657 165 device_name);
50e1e10f
TT
166 if (fs != NULL) {
167 fs->super->s_state |= EXT2_ERROR_FS;
168 ext2fs_mark_super_dirty(fs);
169 ext2fs_close(fs);
170 }
3839e657
TT
171 exit(FSCK_UNCORRECTED);
172}
173
174void init_resource_track(struct resource_track *track)
175{
50e1e10f 176#ifdef HAVE_GETRUSAGE
3839e657 177 struct rusage r;
50e1e10f 178#endif
3839e657
TT
179
180 track->brk_start = sbrk(0);
181 gettimeofday(&track->time_start, 0);
50e1e10f 182#ifdef HAVE_GETRUSAGE
3839e657
TT
183 getrusage(RUSAGE_SELF, &r);
184 track->user_start = r.ru_utime;
185 track->system_start = r.ru_stime;
50e1e10f
TT
186#else
187 track->user_start.tv_sec = track->user_start.tv_usec = 0;
188 track->system_start.tv_sec = track->system_start.tv_usec = 0;
189#endif
3839e657
TT
190}
191
192static __inline__ float timeval_subtract(struct timeval *tv1,
193 struct timeval *tv2)
194{
195 return ((tv1->tv_sec - tv2->tv_sec) +
196 ((float) (tv1->tv_usec - tv2->tv_usec)) / 1000000);
197}
198
199void print_resource_track(struct resource_track *track)
200{
50e1e10f 201#ifdef HAVE_GETRUSAGE
3839e657 202 struct rusage r;
50e1e10f 203#endif
3839e657
TT
204 struct timeval time_end;
205
206 gettimeofday(&time_end, 0);
50e1e10f 207#ifdef HAVE_GETRUSAGE
3839e657
TT
208 getrusage(RUSAGE_SELF, &r);
209
210 printf("Memory used: %d, elapsed time: %6.3f/%6.3f/%6.3f\n",
211 (int) (((char *) sbrk(0)) - ((char *) track->brk_start)),
212 timeval_subtract(&time_end, &track->time_start),
213 timeval_subtract(&r.ru_utime, &track->user_start),
214 timeval_subtract(&r.ru_stime, &track->system_start));
50e1e10f
TT
215#else
216 printf("Memory used: %d, elapsed time: %6.3f\n",
217 (int) (((char *) sbrk(0)) - ((char *) track->brk_start)),
218 timeval_subtract(&time_end, &track->time_start));
219#endif
3839e657
TT
220}
221
f3db3566
TT
222void e2fsck_read_inode(ext2_filsys fs, unsigned long ino,
223 struct ext2_inode * inode, const char *proc)
224{
225 int retval;
226
227 retval = ext2fs_read_inode(fs, ino, inode);
228 if (retval) {
229 com_err("ext2fs_read_inode", retval,
230 "while reading inode %ld in %s", ino, proc);
231 fatal_error(0);
232 }
233}
234
235extern void e2fsck_write_inode(ext2_filsys fs, unsigned long ino,
236 struct ext2_inode * inode, const char *proc)
237{
238 int retval;
239
240 retval = ext2fs_write_inode(fs, ino, inode);
241 if (retval) {
242 com_err("ext2fs_write_inode", retval,
243 "while writing inode %ld in %s", ino, proc);
244 fatal_error(0);
245 }
246}
247
3839e657
TT
248/*
249 * This function returns 1 if the inode's block entries actually
250 * contain block entries.
251 */
252int inode_has_valid_blocks(struct ext2_inode *inode)
253{
254 /*
255 * Only directories, regular files, and some symbolic links
256 * have valid block entries.
257 */
50e1e10f
TT
258 if (!LINUX_S_ISDIR(inode->i_mode) && !LINUX_S_ISREG(inode->i_mode) &&
259 !LINUX_S_ISLNK(inode->i_mode))
3839e657
TT
260 return 0;
261
262 /*
263 * If the symbolic link is a "fast symlink", then the symlink
264 * target is stored in the block entries.
265 */
50e1e10f 266 if (LINUX_S_ISLNK (inode->i_mode) && inode->i_blocks == 0 &&
3839e657
TT
267 inode->i_size < EXT2_N_BLOCKS * sizeof (unsigned long))
268 return 0;
269
270 return 1;
271}
272
273#ifdef MTRACE
274void mtrace_print(char *mesg)
275{
276 FILE *malloc_get_mallstream();
277 FILE *f = malloc_get_mallstream();
278
279 if (f)
280 fprintf(f, "============= %s\n", mesg);
281}
282#endif
283
284