inet6: require RTF_ANNOUNCE to proxy NS
[dragonfly.git] / sbin / fsck_msdosfs / check.c
blob045f085a5aaebee2a5832d0a1fed75565bf22d00
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (C) 1995, 1996, 1997 Wolfgang Solfrank
5 * Copyright (c) 1995 Martin Husemann
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdio.h>
31 #include <unistd.h>
32 #include <fcntl.h>
33 #include <libutil.h>
35 #include "ext.h"
36 #include "fsutil.h"
38 int
39 checkfilesys(const char *fname)
41 int dosfs;
42 struct bootblock boot;
43 struct fat_descriptor *fat = NULL;
44 int finish_dosdirsection=0;
45 int mod = 0;
46 int ret = 8;
47 int64_t freebytes;
48 int64_t badbytes;
50 rdonly = alwaysno;
51 if (!preen)
52 printf("** %s", fname);
54 dosfs = open(fname, rdonly ? O_RDONLY : O_RDWR, 0);
55 if (dosfs < 0 && !rdonly) {
56 dosfs = open(fname, O_RDONLY, 0);
57 if (dosfs >= 0)
58 pwarn(" (NO WRITE)\n");
59 else if (!preen)
60 printf("\n");
61 rdonly = 1;
62 } else if (!preen)
63 printf("\n");
65 if (dosfs < 0) {
66 perr("Can't open `%s'", fname);
67 printf("\n");
68 return 8;
71 if (readboot(dosfs, &boot) == FSFATAL) {
72 close(dosfs);
73 printf("\n");
74 return 8;
77 if (!preen) {
78 printf("** Phase 1 - Read FAT and checking connectivity\n");
81 mod |= readfat(dosfs, &boot, &fat);
82 if (mod & FSFATAL) {
83 close(dosfs);
84 return 8;
87 if (!preen)
88 printf("** Phase 2 - Checking Directories\n");
90 mod |= resetDosDirSection(fat);
91 finish_dosdirsection = 1;
92 if (mod & FSFATAL)
93 goto out;
94 /* delay writing FATs */
96 mod |= handleDirTree(fat);
97 if (mod & FSFATAL)
98 goto out;
100 if (!preen)
101 printf("** Phase 3 - Checking for Lost Files\n");
103 mod |= checklost(fat);
104 if (mod & FSFATAL)
105 goto out;
107 /* now write the FATs */
108 if (mod & FSFATMOD) {
109 if (ask(1, "Update FATs")) {
110 mod |= writefat(fat);
111 if (mod & FSFATAL)
112 goto out;
113 } else
114 mod |= FSERROR;
117 freebytes = (int64_t)boot.NumFree * boot.ClusterSize;
118 badbytes = (int64_t)boot.NumBad * boot.ClusterSize;
120 #if 1
121 char freestr[7], badstr[7];
123 humanize_number(freestr, sizeof(freestr), freebytes, "",
124 HN_AUTOSCALE, HN_DECIMAL | HN_IEC_PREFIXES);
125 if (boot.NumBad) {
126 humanize_number(badstr, sizeof(badstr), badbytes, "",
127 HN_AUTOSCALE, HN_B | HN_DECIMAL | HN_IEC_PREFIXES);
129 pwarn("%d files, %sB free (%d clusters), %sB bad (%d clusters)\n",
130 boot.NumFiles, freestr, boot.NumFree,
131 badstr, boot.NumBad);
132 } else {
133 pwarn("%d files, %sB free (%d clusters)\n",
134 boot.NumFiles, freestr, boot.NumFree);
136 #else
137 if (boot.NumBad)
138 pwarn("%d files, %jd KiB free (%d clusters), %jd KiB bad (%d clusters)\n",
139 boot.NumFiles, (intmax_t)freebytes / 1024, boot.NumFree,
140 (intmax_t)badbytes / 1024, boot.NumBad);
141 else
142 pwarn("%d files, %jd KiB free (%d clusters)\n",
143 boot.NumFiles, (intmax_t)freebytes / 1024, boot.NumFree);
144 #endif
146 if (mod && (mod & FSERROR) == 0) {
147 if (mod & FSDIRTY) {
148 if (ask(1, "MARK FILE SYSTEM CLEAN") == 0)
149 mod &= ~FSDIRTY;
151 if (mod & FSDIRTY) {
152 pwarn("MARKING FILE SYSTEM CLEAN\n");
153 mod |= cleardirty(fat);
154 } else {
155 pwarn("\n***** FILE SYSTEM IS LEFT MARKED AS DIRTY *****\n");
156 mod |= FSERROR; /* file system not clean */
161 if (mod & (FSFATAL | FSERROR))
162 goto out;
164 ret = 0;
166 out:
167 if (finish_dosdirsection)
168 finishDosDirSection();
169 free(fat);
170 close(dosfs);
172 if (mod & (FSFATMOD|FSDIRMOD))
173 pwarn("\n***** FILE SYSTEM WAS MODIFIED *****\n");
175 return ret;