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