OSDN Git Service

9d210493bb6fda5666ef2367e294c52c9758bea7
[android-x86/external-exfat.git] / fsck / main.c
1 /*
2  *  main.c
3  *  exFAT file system checker.
4  *
5  *  Created by Andrew Nayenko on 02.09.09.
6  *  This software is distributed under the GNU General Public License 
7  *  version 3 or any later.
8  */
9
10 #include <stdio.h>
11 #include <string.h>
12 #include <exfat.h>
13 #include <exfatfs.h>
14 #include <inttypes.h>
15
16 #define exfat_debug(format, ...)
17
18 #define MB (1024 * 1024)
19
20 uint64_t files_count, directories_count;
21
22 static uint64_t bytes2mb(uint64_t bytes)
23 {
24         return (bytes + MB / 2) / MB;
25 }
26
27 static void sbck(const struct exfat* ef)
28 {
29         const uint32_t block_size = (1 << ef->sb->block_bits); /* in bytes */
30         const uint32_t cluster_size = CLUSTER_SIZE(*ef->sb); /* in bytes */
31         const uint64_t total = (uint64_t) le32_to_cpu(ef->sb->cluster_count) *
32                 cluster_size;
33
34 #if 0 /* low-level info */
35         printf("First block           %8"PRIu64"\n",
36                         le64_to_cpu(ef->sb->block_start));
37         printf("Blocks count          %8"PRIu64"\n",
38                         le64_to_cpu(ef->sb->block_count));
39         printf("FAT first block       %8u\n",
40                         le32_to_cpu(ef->sb->fat_block_start));
41         printf("FAT blocks count      %8u\n",
42                         le32_to_cpu(ef->sb->fat_block_count));
43         printf("First cluster block   %8u\n",
44                         le32_to_cpu(ef->sb->cluster_block_start));
45         printf("Clusters count        %8u\n",
46                         le32_to_cpu(ef->sb->cluster_count));
47         printf("First cluster of root %8u\n",
48                         le32_to_cpu(ef->sb->rootdir_cluster));
49 #endif
50         printf("Block size            %8u bytes\n", block_size);
51         printf("Cluster size          %8u bytes\n", cluster_size);
52         printf("Total space           %8"PRIu64" MB\n", bytes2mb(total));
53         printf("Used space            %8"PRIu64" MB (%hhu%%)\n",
54                         bytes2mb(total * ef->sb->allocated_percent / 100),
55                         ef->sb->allocated_percent);
56         printf("Free space            %8"PRIu64" MB (%hhu%%)\n",
57                         bytes2mb(total * (100 - ef->sb->allocated_percent) / 100),
58                         100 - ef->sb->allocated_percent);
59 }
60
61 static void dirck(struct exfat* ef, const char* path)
62 {
63         struct exfat_node* parent;
64         struct exfat_node* node;
65         struct exfat_iterator it;
66         int rc;
67         char subpath[EXFAT_NAME_MAX + 1];
68
69         if (exfat_lookup(ef, &parent, path) != 0)
70                 exfat_bug("directory `%s' is not found", path);
71         if (!(parent->flags & EXFAT_ATTRIB_DIR))
72                 exfat_bug("`%s' is not a directory (0x%x)", path, parent->flags);
73
74         rc = exfat_opendir(ef, parent, &it);
75         if (rc != 0)
76         {
77                 exfat_put_node(parent);
78                 exfat_error("failed to open directory `%s'", path);
79                 return;
80         }
81         while ((node = exfat_readdir(ef, &it)))
82         {
83                 strcpy(subpath, path);
84                 strcat(subpath, "/");
85                 exfat_get_name(node, subpath + strlen(subpath),
86                                 EXFAT_NAME_MAX - strlen(subpath));
87                 exfat_debug("%s: %s, %llu bytes, cluster %u", subpath,
88                                 IS_CONTIGUOUS(*node) ? "contiguous" : "fragmented",
89                                 node->size, node->start_cluster);
90                 if (node->flags & EXFAT_ATTRIB_DIR)
91                 {
92                         directories_count++;
93                         dirck(ef, subpath);
94                 }
95                 else
96                         files_count++;
97                 exfat_put_node(node);
98         }
99         exfat_closedir(&it);
100         exfat_put_node(parent);
101 }
102
103 static void fsck(struct exfat* ef)
104 {
105         sbck(ef);
106         dirck(ef, "");
107 }
108
109 int main(int argc, char* argv[])
110 {
111         struct exfat ef;
112
113         if (argc != 2)
114         {
115                 fprintf(stderr, "usage: %s <spec>\n", argv[0]);
116                 return 1;
117         }
118         printf("exfatck %u.%u\n",
119                         EXFAT_VERSION_MAJOR, EXFAT_VERSION_MINOR);
120
121         if (exfat_mount(&ef, argv[1]) != 0)
122                 return 1;
123
124         printf("Checking file system on %s.\n", argv[1]);
125         fsck(&ef);
126         exfat_unmount(&ef);
127         printf("Totally %"PRIu64" directories and %"PRIu64" files.\n",
128                         directories_count, files_count);
129
130         fputs("File system checking finished: ", stdout);
131         if (exfat_errors == 0)
132                 puts("seems OK.");
133         else
134                 printf("%d ERROR%s FOUND!!!\n", exfat_errors,
135                                 exfat_errors > 1 ? "S WERE" : " WAS");
136         return 0;
137 }