Fix copyright
[unix-history] / usr / src / sbin / fsck / setup.c
CommitLineData
76797561
DF
1/*
2 * Copyright (c) 1980 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
eb93b62a 7#ifndef lint
76797561
DF
8static char sccsid[] = "@(#)setup.c 5.1 (Berkeley) %G%";
9#endif not lint
eb93b62a
KM
10
11#include <sys/param.h>
12#include <sys/inode.h>
13#include <sys/fs.h>
14#include <sys/stat.h>
15#include "fsck.h"
16
17char *calloc();
18
19setup(dev)
20 char *dev;
21{
22 dev_t rootdev;
23 struct stat statb;
24 daddr_t super = bflag ? bflag : SBLOCK;
7718c0e6 25 int i, j;
eb93b62a
KM
26 long size;
27 BUFAREA asblk;
28# define altsblock asblk.b_un.b_fs
29
30 if (stat("/", &statb) < 0)
31 errexit("Can't stat root\n");
32 rootdev = statb.st_dev;
33 if (stat(dev, &statb) < 0) {
7718c0e6 34 printf("Can't stat %s\n", dev);
eb93b62a
KM
35 return (0);
36 }
37 rawflg = 0;
38 if ((statb.st_mode & S_IFMT) == S_IFBLK)
39 ;
40 else if ((statb.st_mode & S_IFMT) == S_IFCHR)
41 rawflg++;
42 else {
43 if (reply("file is not a block or character device; OK") == 0)
44 return (0);
45 }
46 if (rootdev == statb.st_rdev)
47 hotroot++;
48 if ((dfile.rfdes = open(dev, 0)) < 0) {
7718c0e6 49 printf("Can't open %s\n", dev);
eb93b62a
KM
50 return (0);
51 }
52 if (preen == 0)
53 printf("** %s", dev);
54 if (nflag || (dfile.wfdes = open(dev, 1)) < 0) {
55 dfile.wfdes = -1;
56 if (preen)
57 pfatal("NO WRITE ACCESS");
58 printf(" (NO WRITE)");
59 }
60 if (preen == 0)
61 printf("\n");
eb93b62a 62 dfile.mod = 0;
eb93b62a 63 lfdir = 0;
eb93b62a
KM
64 initbarea(&sblk);
65 initbarea(&fileblk);
66 initbarea(&inoblk);
67 initbarea(&cgblk);
68 initbarea(&asblk);
69 /*
70 * Read in the super block and its summary info.
71 */
49505034 72 if (bread(&dfile, (char *)&sblock, super, (long)SBSIZE) != 0)
eb93b62a
KM
73 return (0);
74 sblk.b_bno = super;
75 sblk.b_size = SBSIZE;
76 /*
77 * run a few consistency checks of the super block
78 */
79 if (sblock.fs_magic != FS_MAGIC)
80 { badsb("MAGIC NUMBER WRONG"); return (0); }
81 if (sblock.fs_ncg < 1)
82 { badsb("NCG OUT OF RANGE"); return (0); }
83 if (sblock.fs_cpg < 1 || sblock.fs_cpg > MAXCPG)
84 { badsb("CPG OUT OF RANGE"); return (0); }
85 if (sblock.fs_ncg * sblock.fs_cpg < sblock.fs_ncyl ||
86 (sblock.fs_ncg - 1) * sblock.fs_cpg >= sblock.fs_ncyl)
87 { badsb("NCYL DOES NOT JIVE WITH NCG*CPG"); return (0); }
88 if (sblock.fs_sbsize > SBSIZE)
89 { badsb("SIZE PREPOSTEROUSLY LARGE"); return (0); }
90 /*
91 * Set all possible fields that could differ, then do check
92 * of whole super block against an alternate super block.
93 * When an alternate super-block is specified this check is skipped.
94 */
95 if (bflag)
96 goto sbok;
49505034
KM
97 getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize);
98 if (asblk.b_errs != NULL)
eb93b62a
KM
99 return (0);
100 altsblock.fs_link = sblock.fs_link;
101 altsblock.fs_rlink = sblock.fs_rlink;
102 altsblock.fs_time = sblock.fs_time;
103 altsblock.fs_cstotal = sblock.fs_cstotal;
104 altsblock.fs_cgrotor = sblock.fs_cgrotor;
105 altsblock.fs_fmod = sblock.fs_fmod;
106 altsblock.fs_clean = sblock.fs_clean;
107 altsblock.fs_ronly = sblock.fs_ronly;
108 altsblock.fs_flags = sblock.fs_flags;
109 altsblock.fs_maxcontig = sblock.fs_maxcontig;
110 altsblock.fs_minfree = sblock.fs_minfree;
111 altsblock.fs_rotdelay = sblock.fs_rotdelay;
112 altsblock.fs_maxbpg = sblock.fs_maxbpg;
113 bcopy((char *)sblock.fs_csp, (char *)altsblock.fs_csp,
114 sizeof sblock.fs_csp);
115 bcopy((char *)sblock.fs_fsmnt, (char *)altsblock.fs_fsmnt,
116 sizeof sblock.fs_fsmnt);
117 if (bcmp((char *)&sblock, (char *)&altsblock, (int)sblock.fs_sbsize))
118 { badsb("TRASHED VALUES IN SUPER BLOCK"); return (0); }
119sbok:
120 fmax = sblock.fs_size;
121 imax = sblock.fs_ncg * sblock.fs_ipg;
eb93b62a
KM
122 /*
123 * read in the summary info.
124 */
125 for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
126 size = sblock.fs_cssize - i < sblock.fs_bsize ?
127 sblock.fs_cssize - i : sblock.fs_bsize;
128 sblock.fs_csp[j] = (struct csum *)calloc(1, (unsigned)size);
129 if (bread(&dfile, (char *)sblock.fs_csp[j],
130 fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag),
49505034 131 size) != 0)
eb93b62a
KM
132 return (0);
133 }
134 /*
135 * allocate and initialize the necessary maps
136 */
137 bmapsz = roundup(howmany(fmax, NBBY), sizeof(short));
138 blockmap = calloc((unsigned)bmapsz, sizeof (char));
139 if (blockmap == NULL) {
140 printf("cannot alloc %d bytes for blockmap\n", bmapsz);
141 goto badsb;
142 }
eb93b62a
KM
143 statemap = calloc((unsigned)(imax + 1), sizeof(char));
144 if (statemap == NULL) {
145 printf("cannot alloc %d bytes for statemap\n", imax + 1);
146 goto badsb;
147 }
148 lncntp = (short *)calloc((unsigned)(imax + 1), sizeof(short));
149 if (lncntp == NULL) {
150 printf("cannot alloc %d bytes for lncntp\n",
151 (imax + 1) * sizeof(short));
152 goto badsb;
153 }
eb93b62a
KM
154
155 return (1);
156
157badsb:
158 ckfini();
159 return (0);
160# undef altsblock
161}
162
163badsb(s)
164 char *s;
165{
166
167 if (preen)
168 printf("%s: ", devname);
169 printf("BAD SUPER BLOCK: %s\n", s);
170 pwarn("USE -b OPTION TO FSCK TO SPECIFY LOCATION OF AN ALTERNATE\n");
171 pfatal("SUPER-BLOCK TO SUPPLY NEEDED INFORMATION; SEE fsck(8).\n");
172}