new copyright notice
[unix-history] / usr / src / sbin / badsect / badsect.c
CommitLineData
da158ee3 1/*
14955f05
KB
2 * Copyright (c) 1981, 1983 The Regents of the University of California.
3 * All rights reserved.
4 *
6ecf3d85 5 * %sccs.include.redist.c%
da158ee3
DF
6 */
7
8#ifndef lint
9char copyright[] =
14955f05 10"@(#) Copyright (c) 1981, 1983 The Regents of the University of California.\n\
da158ee3 11 All rights reserved.\n";
14955f05 12#endif /* not lint */
da158ee3
DF
13
14#ifndef lint
6ecf3d85 15static char sccsid[] = "@(#)badsect.c 5.9 (Berkeley) %G%";
14955f05 16#endif /* not lint */
c939dd1c
BJ
17
18/*
19 * badsect
20 *
21 * Badsect takes a list of file-system relative sector numbers
22 * and makes files containing the blocks of which these sectors are a part.
23 * It can be used to contain sectors which have problems if these sectors
24 * are not part of the bad file for the pack (see bad144). For instance,
25 * this program can be used if the driver for the file system in question
26 * does not support bad block forwarding.
27 */
28#include <sys/param.h>
3f96c1fb
KM
29#include <sys/dir.h>
30#include <sys/stat.h>
c0efa4d3 31#include <ufs/fs.h>
3eba0f43 32#include <ufs/dinode.h>
7abf8d65
KB
33#include <stdio.h>
34#include <paths.h>
3f96c1fb
KM
35
36union {
37 struct fs fs;
38 char fsx[SBSIZE];
39} ufs;
40#define sblock ufs.fs
41union {
42 struct cg cg;
43 char cgx[MAXBSIZE];
44} ucg;
45#define acg ucg.cg
46struct fs *fs;
47int fso, fsi;
48int errs;
a66ab591 49long dev_bsize = 1;
3f96c1fb
KM
50
51char buf[MAXBSIZE];
52
c939dd1c
BJ
53
54main(argc, argv)
55 int argc;
3f96c1fb 56 char *argv[];
c939dd1c 57{
3f96c1fb
KM
58 daddr_t number;
59 struct stat stbuf, devstat;
60 register struct direct *dp;
61 DIR *dirp;
62 int fd;
63 char name[BUFSIZ];
c939dd1c 64
3f96c1fb
KM
65 if (argc < 3) {
66 fprintf(stderr, "usage: badsect bbdir blkno [ blkno ]\n");
67 exit(1);
68 }
69 if (chdir(argv[1]) < 0 || stat(".", &stbuf) < 0) {
70 perror(argv[1]);
71 exit(2);
72 }
7abf8d65 73 strcpy(name, _PATH_DEV);
3f96c1fb
KM
74 if ((dirp = opendir(name)) == NULL) {
75 perror(name);
76 exit(3);
77 }
78 while ((dp = readdir(dirp)) != NULL) {
79 strcpy(&name[5], dp->d_name);
80 if (stat(name, &devstat) < 0) {
81 perror(name);
82 exit(4);
83 }
84 if (stbuf.st_dev == devstat.st_rdev &&
85 (devstat.st_mode & IFMT) == IFBLK)
86 break;
c939dd1c 87 }
3f96c1fb
KM
88 closedir(dirp);
89 if (dp == NULL) {
90 printf("Cannot find dev 0%o corresponding to %s\n",
91 stbuf.st_rdev, argv[1]);
92 exit(5);
93 }
94 if ((fsi = open(name, 0)) < 0) {
95 perror(name);
96 exit(6);
97 }
98 fs = &sblock;
a66ab591
KM
99 rdfs(SBOFF, SBSIZE, (char *)fs);
100 dev_bsize = fs->fs_fsize / fsbtodb(fs, 1);
3f96c1fb
KM
101 for (argc -= 2, argv += 2; argc > 0; argc--, argv++) {
102 number = atoi(*argv);
103 if (chkuse(number, 1))
104 continue;
105 if (mknod(*argv, IFMT|0600, dbtofsb(fs, number)) < 0) {
106 perror(*argv);
107 errs++;
108 }
109 }
110 printf("Don't forget to run ``fsck %s''\n", name);
c939dd1c
BJ
111 exit(errs);
112}
3f96c1fb
KM
113
114chkuse(blkno, cnt)
115 daddr_t blkno;
116 int cnt;
117{
118 int cg;
119 daddr_t fsbn, bn;
120
121 fsbn = dbtofsb(fs, blkno);
122 if ((unsigned)(fsbn+cnt) > fs->fs_size) {
123 printf("block %d out of range of file system\n", blkno);
124 return (1);
125 }
126 cg = dtog(fs, fsbn);
127 if (fsbn < cgdmin(fs, cg)) {
128 if (cg == 0 || (fsbn+cnt) > cgsblock(fs, cg)) {
129 printf("block %d in non-data area: cannot attach\n",
130 blkno);
131 return (1);
132 }
133 } else {
134 if ((fsbn+cnt) > cgbase(fs, cg+1)) {
135 printf("block %d in non-data area: cannot attach\n",
136 blkno);
137 return (1);
138 }
139 }
140 rdfs(fsbtodb(fs, cgtod(fs, cg)), (int)sblock.fs_cgsize,
141 (char *)&acg);
89b44b6d 142 if (!cg_chkmagic(&acg)) {
3f96c1fb
KM
143 fprintf(stderr, "cg %d: bad magic number\n", cg);
144 errs++;
75e5614d 145 return (1);
3f96c1fb
KM
146 }
147 bn = dtogd(fs, fsbn);
89b44b6d 148 if (isclr(cg_blksfree(&acg), bn))
3f96c1fb
KM
149 printf("Warning: sector %d is in use\n", blkno);
150 return (0);
151}
152
153/*
154 * read a block from the file system
155 */
156rdfs(bno, size, bf)
157 int bno, size;
158 char *bf;
159{
160 int n;
161
a66ab591 162 if (lseek(fsi, bno * dev_bsize, 0) < 0) {
3f96c1fb
KM
163 printf("seek error: %ld\n", bno);
164 perror("rdfs");
165 exit(1);
166 }
167 n = read(fsi, bf, size);
168 if(n != size) {
169 printf("read error: %ld\n", bno);
170 perror("rdfs");
171 exit(1);
172 }
173}