Whamcloud - gitweb
config: update config.{guess,sub}
[tools/e2fsprogs.git] / e2fsck / ehandler.c
1 /*
2  * ehandler.c --- handle bad block errors which come up during the
3  *      course of an e2fsck session.
4  *
5  * Copyright (C) 1994 Theodore Ts'o.  This file may be redistributed
6  * under the terms of the GNU Public License.
7  */
8
9 #include "config.h"
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <string.h>
13 #include <ctype.h>
14 #include <termios.h>
15
16 #include "e2fsck.h"
17
18 #include <sys/time.h>
19 #include <sys/resource.h>
20
21 static const char *operation;
22
23 static errcode_t e2fsck_handle_read_error(io_channel channel,
24                                           unsigned long block,
25                                           int count,
26                                           void *data,
27                                           size_t size EXT2FS_ATTR((unused)),
28                                           int actual EXT2FS_ATTR((unused)),
29                                           errcode_t error)
30 {
31         int     i;
32         char    *p;
33         ext2_filsys fs = (ext2_filsys) channel->app_data;
34         e2fsck_t ctx;
35
36         ctx = (e2fsck_t) fs->priv_data;
37         if (ctx->flags & E2F_FLAG_EXITING)
38                 return 0;
39         /*
40          * If more than one block was read, try reading each block
41          * separately.  We could use the actual bytes read to figure
42          * out where to start, but we don't bother.
43          */
44         if (count > 1) {
45                 p = (char *) data;
46                 for (i=0; i < count; i++, p += channel->block_size, block++) {
47                         error = io_channel_read_blk64(channel, block,
48                                                     1, p);
49                         if (error)
50                                 return error;
51                 }
52                 return 0;
53         }
54         if (operation)
55                 printf(_("Error reading block %lu (%s) while %s.  "), block,
56                        error_message(error), operation);
57         else
58                 printf(_("Error reading block %lu (%s).  "), block,
59                        error_message(error));
60         preenhalt(ctx);
61
62         /* Don't rewrite a block past the end of the FS. */
63         if (block >= ext2fs_blocks_count(fs->super))
64                 return 0;
65
66         if (ask(ctx, _("Ignore error"), 1)) {
67                 if (ask(ctx, _("Force rewrite"), 1))
68                         io_channel_write_blk64(channel, block, count, data);
69                 return 0;
70         }
71
72         return error;
73 }
74
75 static errcode_t e2fsck_handle_write_error(io_channel channel,
76                                             unsigned long block,
77                                             int count,
78                                             const void *data,
79                                             size_t size EXT2FS_ATTR((unused)),
80                                             int actual EXT2FS_ATTR((unused)),
81                                             errcode_t error)
82 {
83         int             i;
84         const char      *p;
85         ext2_filsys fs = (ext2_filsys) channel->app_data;
86         e2fsck_t ctx;
87
88         ctx = (e2fsck_t) fs->priv_data;
89         if (ctx->flags & E2F_FLAG_EXITING)
90                 return 0;
91
92         /*
93          * If more than one block was written, try writing each block
94          * separately.  We could use the actual bytes read to figure
95          * out where to start, but we don't bother.
96          */
97         if (count > 1) {
98                 p = (const char *) data;
99                 for (i=0; i < count; i++, p += channel->block_size, block++) {
100                         error = io_channel_write_blk64(channel, block,
101                                                      1, p);
102                         if (error)
103                                 return error;
104                 }
105                 return 0;
106         }
107
108         if (operation)
109                 printf(_("Error writing block %lu (%s) while %s.  "), block,
110                        error_message(error), operation);
111         else
112                 printf(_("Error writing block %lu (%s).  "), block,
113                        error_message(error));
114         preenhalt(ctx);
115         if (ask(ctx, _("Ignore error"), 1))
116                 return 0;
117
118         return error;
119 }
120
121 const char *ehandler_operation(const char *op)
122 {
123         const char *ret = operation;
124
125         operation = op;
126         return ret;
127 }
128
129 void ehandler_init(io_channel channel)
130 {
131         channel->read_error = e2fsck_handle_read_error;
132         channel->write_error = e2fsck_handle_write_error;
133 }