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