]> git.sven.stormbind.net Git - sven/exfat-utils.git/blob - repair.c
237ab3ac8242a961571f1d4d036b8ab6fcbc179f
[sven/exfat-utils.git] / repair.c
1 /*
2         repair.c (09.03.17)
3         exFAT file system implementation library.
4
5         Free exFAT implementation.
6         Copyright (C) 2010-2018  Andrew Nayenko
7
8         This program is free software; you can redistribute it and/or modify
9         it under the terms of the GNU General Public License as published by
10         the Free Software Foundation, either version 2 of the License, or
11         (at your option) any later version.
12
13         This program is distributed in the hope that it will be useful,
14         but WITHOUT ANY WARRANTY; without even the implied warranty of
15         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16         GNU General Public License for more details.
17
18         You should have received a copy of the GNU General Public License along
19         with this program; if not, write to the Free Software Foundation, Inc.,
20         51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23 #include "exfat.h"
24 #include <strings.h>
25
26 int exfat_errors_fixed;
27
28 bool exfat_ask_to_fix(const struct exfat* ef)
29 {
30         const char* question = "Fix (Y/N)?";
31         char answer[8];
32         bool yeah, nope;
33
34         switch (ef->repair)
35         {
36         case EXFAT_REPAIR_NO:
37                 return false;
38         case EXFAT_REPAIR_YES:
39                 printf("%s %s", question, "Y\n");
40                 return true;
41         case EXFAT_REPAIR_ASK:
42                 do
43                 {
44                         printf("%s ", question);
45                         fflush(stdout);
46                         if (fgets(answer, sizeof(answer), stdin))
47                         {
48                                 yeah = strcasecmp(answer, "Y\n") == 0;
49                                 nope = strcasecmp(answer, "N\n") == 0;
50                         }
51                         else
52                         {
53                                 yeah = false;
54                                 nope = true;
55                         }
56                 }
57                 while (!yeah && !nope);
58                 return yeah;
59         }
60         exfat_bug("invalid repair option value: %d", ef->repair);
61 }
62
63 bool exfat_fix_invalid_vbr_checksum(const struct exfat* ef, void* sector,
64                 uint32_t vbr_checksum)
65 {
66         size_t i;
67         off_t sector_size = SECTOR_SIZE(*ef->sb);
68
69         for (i = 0; i < sector_size / sizeof(vbr_checksum); i++)
70                 ((le32_t*) sector)[i] = cpu_to_le32(vbr_checksum);
71         if (exfat_pwrite(ef->dev, sector, sector_size, 11 * sector_size) < 0)
72         {
73                 exfat_error("failed to write correct VBR checksum");
74                 return false;
75         }
76         exfat_errors_fixed++;
77         return true;
78 }
79
80 bool exfat_fix_invalid_node_checksum(const struct exfat* ef,
81                 struct exfat_node* node)
82 {
83         /* checksum will be rewritten by exfat_flush_node() */
84         node->is_dirty = true;
85
86         exfat_errors_fixed++;
87         return true;
88 }
89
90 bool exfat_fix_unknown_entry(struct exfat* ef, struct exfat_node* dir,
91                 const struct exfat_entry* entry, off_t offset)
92 {
93         struct exfat_entry deleted = *entry;
94
95         deleted.type &= ~EXFAT_ENTRY_VALID;
96         if (exfat_generic_pwrite(ef, dir, &deleted, sizeof(struct exfat_entry),
97                         offset) != sizeof(struct exfat_entry))
98                 return false;
99
100         exfat_errors_fixed++;
101         return true;
102 }