|
|
1.1 root 1: /*
2: * Perform initialization for phases of fsck
3: */
4: #include "fsck.h"
5: #include <mnttab.h>
6: #include <mtab.h>
7:
8: int fsfd; /* file system file descriptor */
9: int writeflg; /* write ok or read-only flag */
10: daddr_t fsize = SUPERI+1; /* file system size in blocks */
11: /* Allows for read of Super Block */
12: int isize; /* First block not in inode list */
13: daddr_t totfree; /* Running total free block count */
14: unsigned ninodes; /* number of inodes */
15: int numfiles; /* number of files in file system */
16:
17: char superb[BSIZE]; /* Super Block */
18: struct filsys *sbp = superb;
19: int sbpfix; /* flag for super block fixes */
20:
21: int offsets[] = /* table of offsets for the levels */
22: { ND, ND+NI, ND+NI+NII, /* of indirection of blocks in the */
23: ND+NI+NII+NIII }; /* inode block list */
24:
25: daddr_t dupblck[DUPTBLSIZE]; /* duplicate referenced blocks */
26: int totdups; /* number of dup blocks so far */
27:
28: #if !SMALLMODEL
29: unsigned short *linkPtr;
30: unsigned char *flagptr, *blockPtr, *dupPtr;
31: #endif
32:
33: init()
34: {
35: int mode;
36: struct stat status;
37: unsigned short stmode;
38:
39: mode = (mdaction == NO) ? 0 : 2;
40:
41: if ( (fsfd = open(fsname, mode)) == (-1) ) {
42: mode = 0;
43: if ( (fsfd = open(fsname, mode)) == (-1) ) {
44: nonfatal("Can't open: %s", fsname);
45: return;
46: }
47: }
48:
49: if (mode == 0) {
50: daction = NO;
51: writeflg = FALSE;
52: } else {
53: daction = mdaction;
54: writeflg = TRUE;
55: }
56:
57: printf("%s: %s\n", fsname, (mode == 0) ? "(NO WRITE)" : "");
58:
59: if ( fstat(fsfd, &status) == (-1) ) {
60: nonfatal("Can't stat: %s", fsname);
61: return;
62: }
63:
64: stmode = status.st_mode & S_IFMT;
65: if ( (stmode != S_IFBLK) && (stmode != S_IFCHR) )
66: switch(query("file is not a block or character device; OK?")){
67: case YES:
68: break;
69: case NO:
70: errflag = TRUE;
71: return;
72: }
73:
74: domount();
75: sbpfix = FALSE;
76: readsuper();
77: checksuper();
78: if ( !errflag )
79: alloctables();
80: }
81:
82: /*
83: * Read in the super block and canonicalize
84: */
85:
86: readsuper()
87: {
88: register int i;
89:
90: bread((daddr_t)SUPERI, superb);
91: sbp = superb;
92:
93: canshort(sbp->s_isize);
94: candaddr(sbp->s_fsize);
95: canshort(sbp->s_nfree);
96: for(i=0; i<NICFREE; i++)
97: candaddr(sbp->s_free[i]);
98: canshort(sbp->s_ninode);
99: for(i=0; i<NICINOD; i++)
100: canino(sbp->s_inode[i]);
101: cantime(sbp->s_time);
102: candaddr(sbp->s_tfree);
103: canino(sbp->s_tinode);
104: canshort(sbp->s_m);
105: canshort(sbp->s_n);
106: canlong(sbp->s_unique);
107:
108: }
109:
110: /*
111: * Check super block for obvious inconsistencies
112: */
113:
114: checksuper()
115: {
116: fsize = sbp->s_fsize;
117: isize = sbp->s_isize;
118: totfree = fsize - isize;
119:
120: if ( (isize<=INODEI) || (isize>=fsize) || (fsize<=INODEI) ) {
121: badsuper("Size check: fsize %U isize %u", fsize, isize);
122: errflag = TRUE;
123: }
124:
125: if ( sbp->s_nfree > NICFREE )
126: badsuper("Too large free block count");
127:
128: if ( sbp->s_ninode > NICINOD )
129: badsuper("Too large free i-node count");
130: }
131:
132: /*
133: * Super Block Error Functions
134: */
135: badsuper(x)
136: {
137: printf("%r\n", &x);
138: printf("fsck: %s: Bad Super Block: %u\n", fsname, SUPERI);
139: }
140:
141: /*
142: * Allocate the necessary buffers for tables
143: */
144: alloctables()
145: {
146: unsigned num, numl;
147:
148: numl = 0;
149: if (!fflag) {
150: ninodes = (unsigned) (isize - INODEI) * INOPB;
151: numl = (unsigned) ninodes;
152: }
153:
154: num = (unsigned) ((fsize+NBPC-1)/NBPC) * sizeof(char);
155: #if SMALLMODEL
156: initV(numl, numl, num, num); /* virtual allocation */
157: #else
158: if (NULL != linkPtr) {
159: free(linkPtr);
160: free(flagPtr);
161: free(blockPtr);
162: free(dupPtr);
163: }
164: linkPtr = calloc(numl, sizeof(unsigned short));
165: flagPtr = calloc(numl, sizeof(unsigned char));
166: blockPtr = calloc(num, sizeof(unsigned char));
167: dupPtr = calloc(num, sizeof(unsigned char));
168: #endif
169: numfiles = /* number of files in the file system */
170: totdups = 0; /* num dup blocks */
171: }
172:
173: /*
174: * domount() checks the files /etc/mnttab and /etc/mtab to find
175: * out where the file system is mounted (if at all). It then
176: * reports where (and when if possible) it was last mounted.
177: */
178: char *mnttab_name = "/etc/mnttab";
179: char *mtab_name = "/etc/mtab";
180: char *bttime_name = "/etc/boottime";
181:
182: domount()
183: {
184: int fd;
185: struct mnttab mnttab;
186: struct mtab mtab;
187: register char *name;
188: struct stat sbuf;
189: time_t boottime;
190: int nothing();
191: char devname[MNTNSIZ+6] = "/dev/";
192:
193: mounted = FALSE;
194: name = fsname; /* strip off all initial */
195: while (*name++ != '\0') ; /* directories in fsname */
196: while ( (*--name != '/') && (name>fsname) ) ;
197: if (*name == '/') name++;
198:
199: if ( stat(bttime_name, &sbuf) == -1 )
200: boottime = (time_t)0;
201: else
202: boottime = sbuf.st_mtime;
203:
204: if ( (fd=open(mnttab_name, 0)) != (-1) ) {
205: while ( read(fd, &mnttab, sizeof(mnttab))==sizeof(mnttab) )
206: if ( mnttab.mt_dev[0] && mnttab.mt_filsys[0] ) {
207: strncpy(&devname[5], mnttab.mt_filsys, MNTNSIZ);
208: devname[MNTNSIZ+5] = '\0';
209: statit(devname, nothing);
210: if (stats.st_rdev != fsysrdev)
211: continue;
212: statit(mnttab.mt_dev, nothing);
213: mounted = (stats.st_dev == fsysrdev);
214: prmnttab(&mnttab, boottime);
215: return;
216: }
217: }
218: if ( (fd=open(mtab_name, 0)) != (-1) ) {
219: while ( read(fd, &mtab, sizeof(mtab))==sizeof(mtab) )
220: if ( mtab.mt_name[0] && mtab.mt_special[0] ) {
221: strncpy(&devname[5], mtab.mt_special, MNAMSIZ);
222: devname[MNAMSIZ+5] = '\0';
223: statit(devname, nothing);
224: if (stats.st_rdev != fsysrdev)
225: continue;
226: statit(mtab.mt_name, nothing);
227: mounted = (stats.st_dev == fsysrdev);
228: prmtab(&mtab);
229: return;
230: }
231: }
232:
233: if (fsysrdev == rootdev)
234: mounted = TRUE;
235: else
236: mounted = FALSE;
237:
238: }
239:
240: prmnttab(ptr, boottime)
241: struct mnttab *ptr;
242: time_t boottime;
243: {
244: if (mounted) {
245: if (boottime < ptr->mt_time)
246: boottime = ptr->mt_time;
247: printf("%s mounted on %.*s as of %s", fsname, MNTNSIZ,
248: ptr->mt_dev, ctime(&boottime));
249: } else
250: printf("%s unmounted. Last mounted on %.*s -- %s",
251: fsname, MNTNSIZ, ptr->mt_dev,
252: ctime(&ptr->mt_time));
253: }
254:
255:
256: prmtab(ptr)
257: struct mtab *ptr;
258: {
259: if (mounted)
260: printf("%s mounted on %.*s\n", fsname, MNAMSIZ, ptr->mt_name);
261: else
262: printf("%s unmounted. Last mounted on %.*s\n", fsname,
263: MNAMSIZ, ptr->mt_name);
264: }
265:
266: nothing()
267: {}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.