Commit | Line | Data |
---|---|---|
5d9906c0 KM |
1 | #ifndef lint |
2 | static char version[] = "@(#)utilities.c 3.1 (Berkeley) %G%"; | |
3 | #endif | |
4 | ||
5 | #include <stdio.h> | |
6 | #include <ctype.h> | |
7 | #include <sys/param.h> | |
8 | #include <sys/inode.h> | |
9 | #include <sys/fs.h> | |
10 | #include "fsck.h" | |
11 | ||
12 | long lseek(); | |
13 | ||
14 | ftypeok(dp) | |
15 | DINODE *dp; | |
16 | { | |
17 | switch (dp->di_mode & IFMT) { | |
18 | ||
19 | case IFDIR: | |
20 | case IFREG: | |
21 | case IFBLK: | |
22 | case IFCHR: | |
23 | case IFLNK: | |
24 | case IFSOCK: | |
25 | return (1); | |
26 | ||
27 | default: | |
28 | if (debug) | |
29 | printf("bad file type 0%o\n", dp->di_mode); | |
30 | return (0); | |
31 | } | |
32 | } | |
33 | ||
34 | reply(s) | |
35 | char *s; | |
36 | { | |
37 | char line[80]; | |
38 | ||
39 | if (preen) | |
40 | pfatal("INTERNAL ERROR: GOT TO reply()"); | |
41 | rplyflag = 1; | |
42 | printf("\n%s? ", s); | |
43 | if (nflag || dfile.wfdes < 0) { | |
44 | printf(" no\n\n"); | |
45 | return (0); | |
46 | } | |
47 | if (yflag) { | |
48 | printf(" yes\n\n"); | |
49 | return (1); | |
50 | } | |
51 | if (getline(stdin, line, sizeof(line)) == EOF) | |
52 | errexit("\n"); | |
53 | printf("\n"); | |
54 | if (line[0] == 'y' || line[0] == 'Y') | |
55 | return (1); | |
56 | else | |
57 | return (0); | |
58 | } | |
59 | ||
60 | getline(fp, loc, maxlen) | |
61 | FILE *fp; | |
62 | char *loc; | |
63 | { | |
64 | register n; | |
65 | register char *p, *lastloc; | |
66 | ||
67 | p = loc; | |
68 | lastloc = &p[maxlen-1]; | |
69 | while ((n = getc(fp)) != '\n') { | |
70 | if (n == EOF) | |
71 | return (EOF); | |
72 | if (!isspace(n) && p < lastloc) | |
73 | *p++ = n; | |
74 | } | |
75 | *p = 0; | |
76 | return (p - loc); | |
77 | } | |
78 | ||
79 | BUFAREA * | |
80 | getblk(bp, blk, size) | |
81 | register BUFAREA *bp; | |
82 | daddr_t blk; | |
83 | long size; | |
84 | { | |
85 | register struct filecntl *fcp; | |
86 | daddr_t dblk; | |
87 | ||
88 | fcp = &dfile; | |
89 | dblk = fsbtodb(&sblock, blk); | |
90 | if (bp->b_bno == dblk) | |
91 | return (bp); | |
92 | flush(fcp, bp); | |
93 | if (bread(fcp, bp->b_un.b_buf, dblk, size) != 0) { | |
94 | bp->b_bno = dblk; | |
95 | bp->b_size = size; | |
96 | return (bp); | |
97 | } | |
98 | bp->b_bno = (daddr_t)-1; | |
99 | return (NULL); | |
100 | } | |
101 | ||
102 | flush(fcp, bp) | |
103 | struct filecntl *fcp; | |
104 | register BUFAREA *bp; | |
105 | { | |
106 | ||
107 | if (bp->b_dirty) | |
108 | (void)bwrite(fcp, bp->b_un.b_buf, bp->b_bno, (long)bp->b_size); | |
109 | bp->b_dirty = 0; | |
110 | } | |
111 | ||
112 | rwerr(s, blk) | |
113 | char *s; | |
114 | daddr_t blk; | |
115 | { | |
116 | ||
117 | if (preen == 0) | |
118 | printf("\n"); | |
119 | pfatal("CANNOT %s: BLK %ld", s, blk); | |
120 | if (reply("CONTINUE") == 0) | |
121 | errexit("Program terminated\n"); | |
122 | } | |
123 | ||
124 | ckfini() | |
125 | { | |
126 | ||
127 | flush(&dfile, &fileblk); | |
128 | flush(&dfile, &sblk); | |
129 | if (sblk.b_bno != SBLOCK) { | |
130 | sblk.b_bno = SBLOCK; | |
131 | sbdirty(); | |
132 | flush(&dfile, &sblk); | |
133 | } | |
134 | flush(&dfile, &inoblk); | |
135 | (void)close(dfile.rfdes); | |
136 | (void)close(dfile.wfdes); | |
137 | } | |
138 | ||
139 | bread(fcp, buf, blk, size) | |
140 | register struct filecntl *fcp; | |
141 | char *buf; | |
142 | daddr_t blk; | |
143 | long size; | |
144 | { | |
145 | if (lseek(fcp->rfdes, (long)dbtob(blk), 0) < 0) | |
146 | rwerr("SEEK", blk); | |
147 | else if (read(fcp->rfdes, buf, (int)size) == size) | |
148 | return (1); | |
149 | rwerr("READ", blk); | |
150 | return (0); | |
151 | } | |
152 | ||
153 | bwrite(fcp, buf, blk, size) | |
154 | register struct filecntl *fcp; | |
155 | char *buf; | |
156 | daddr_t blk; | |
157 | long size; | |
158 | { | |
159 | ||
160 | if (fcp->wfdes < 0) | |
161 | return (0); | |
162 | if (lseek(fcp->wfdes, (long)dbtob(blk), 0) < 0) | |
163 | rwerr("SEEK", blk); | |
164 | else if (write(fcp->wfdes, buf, (int)size) == size) { | |
165 | fcp->mod = 1; | |
166 | return (1); | |
167 | } | |
168 | rwerr("WRITE", blk); | |
169 | return (0); | |
170 | } | |
171 | ||
172 | catch() | |
173 | { | |
174 | ||
175 | ckfini(); | |
176 | exit(12); | |
177 | } | |
178 | ||
179 | /* | |
180 | * determine whether an inode should be fixed. | |
181 | */ | |
182 | dofix(idesc) | |
183 | register struct inodesc *idesc; | |
184 | { | |
185 | ||
186 | switch (idesc->id_fix) { | |
187 | ||
188 | case DONTKNOW: | |
189 | direrr(idesc->id_number, "DIRECTORY CORRUPTED"); | |
190 | if (reply("SALVAGE") == 0) { | |
191 | idesc->id_fix = NOFIX; | |
192 | return (0); | |
193 | } | |
194 | idesc->id_fix = FIX; | |
195 | return (ALTERED); | |
196 | ||
197 | case FIX: | |
198 | return (ALTERED); | |
199 | ||
200 | case NOFIX: | |
201 | return (0); | |
202 | ||
203 | default: | |
204 | errexit("UNKNOWN INODESC FIX MODE %d\n", idesc->id_fix); | |
205 | } | |
206 | /* NOTREACHED */ | |
207 | } | |
208 | ||
209 | /* VARARGS1 */ | |
210 | error(s1, s2, s3, s4) | |
211 | char *s1; | |
212 | { | |
213 | ||
214 | printf(s1, s2, s3, s4); | |
215 | } | |
216 | ||
217 | /* VARARGS1 */ | |
218 | errexit(s1, s2, s3, s4) | |
219 | char *s1; | |
220 | { | |
221 | error(s1, s2, s3, s4); | |
222 | exit(8); | |
223 | } | |
224 | ||
225 | /* | |
226 | * An inconsistency occured which shouldn't during normal operations. | |
227 | * Die if preening, otherwise just printf. | |
228 | */ | |
229 | /* VARARGS1 */ | |
230 | pfatal(s, a1, a2, a3) | |
231 | char *s; | |
232 | { | |
233 | ||
234 | if (preen) { | |
235 | printf("%s: ", devname); | |
236 | printf(s, a1, a2, a3); | |
237 | printf("\n"); | |
238 | preendie(); | |
239 | } | |
240 | printf(s, a1, a2, a3); | |
241 | } | |
242 | ||
243 | preendie() | |
244 | { | |
245 | ||
246 | printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", devname); | |
247 | exit(8); | |
248 | } | |
249 | ||
250 | /* | |
251 | * Pwarn is like printf when not preening, | |
252 | * or a warning (preceded by filename) when preening. | |
253 | */ | |
254 | /* VARARGS1 */ | |
255 | pwarn(s, a1, a2, a3, a4, a5, a6) | |
256 | char *s; | |
257 | { | |
258 | ||
259 | if (preen) | |
260 | printf("%s: ", devname); | |
261 | printf(s, a1, a2, a3, a4, a5, a6); | |
262 | } | |
263 | ||
264 | #ifndef lint | |
265 | /* | |
266 | * Stub for routines from kernel. | |
267 | */ | |
268 | panic(s) | |
269 | char *s; | |
270 | { | |
271 | ||
272 | pfatal("INTERNAL INCONSISTENCY: %s\n", s); | |
273 | exit(12); | |
274 | } | |
275 | #endif |