X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/c939dd1cd48c826e48a74e3f80deee203de1a9ab..4b18aea43817016255ffe89871607f817eb8700f:/usr/src/sbin/badsect/badsect.c diff --git a/usr/src/sbin/badsect/badsect.c b/usr/src/sbin/badsect/badsect.c index 2617c70074..50d2d2dd92 100644 --- a/usr/src/sbin/badsect/badsect.c +++ b/usr/src/sbin/badsect/badsect.c @@ -1,4 +1,18 @@ -static char *sccsid = "@(#)badsect.c 4.1 (Berkeley) 81/05/10"; +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + */ + +#ifndef lint +char copyright[] = +"@(#) Copyright (c) 1983 Regents of the University of California.\n\ + All rights reserved.\n"; +#endif not lint + +#ifndef lint +static char sccsid[] = "@(#)badsect.c 5.4 (Berkeley) %G%"; +#endif not lint /* * badsect @@ -10,20 +24,148 @@ static char *sccsid = "@(#)badsect.c 4.1 (Berkeley) 81/05/10"; * this program can be used if the driver for the file system in question * does not support bad block forwarding. */ +#include #include +#include +#include +#include +#include + +union { + struct fs fs; + char fsx[SBSIZE]; +} ufs; +#define sblock ufs.fs +union { + struct cg cg; + char cgx[MAXBSIZE]; +} ucg; +#define acg ucg.cg +struct fs *fs; +int fso, fsi; +int errs; +long dev_bsize = 1; + +char buf[MAXBSIZE]; + main(argc, argv) int argc; - char **argv; + char *argv[]; { - char nambuf[32]; - int errs = 0; + daddr_t number; + struct stat stbuf, devstat; + register struct direct *dp; + DIR *dirp; + int fd; + char name[BUFSIZ]; - --argc, argv++; - while (argc > 0) { - if (mknod(*argv, 0, atoi(*argv) / CLSIZE)) - perror("mknod"), errs++; - argc--, argv++; + if (argc < 3) { + fprintf(stderr, "usage: badsect bbdir blkno [ blkno ]\n"); + exit(1); } + if (chdir(argv[1]) < 0 || stat(".", &stbuf) < 0) { + perror(argv[1]); + exit(2); + } + strcpy(name, "/dev/"); + if ((dirp = opendir(name)) == NULL) { + perror(name); + exit(3); + } + while ((dp = readdir(dirp)) != NULL) { + strcpy(&name[5], dp->d_name); + if (stat(name, &devstat) < 0) { + perror(name); + exit(4); + } + if (stbuf.st_dev == devstat.st_rdev && + (devstat.st_mode & IFMT) == IFBLK) + break; + } + closedir(dirp); + if (dp == NULL) { + printf("Cannot find dev 0%o corresponding to %s\n", + stbuf.st_rdev, argv[1]); + exit(5); + } + if ((fsi = open(name, 0)) < 0) { + perror(name); + exit(6); + } + fs = &sblock; + rdfs(SBOFF, SBSIZE, (char *)fs); + dev_bsize = fs->fs_fsize / fsbtodb(fs, 1); + for (argc -= 2, argv += 2; argc > 0; argc--, argv++) { + number = atoi(*argv); + if (chkuse(number, 1)) + continue; + if (mknod(*argv, IFMT|0600, dbtofsb(fs, number)) < 0) { + perror(*argv); + errs++; + } + } + printf("Don't forget to run ``fsck %s''\n", name); exit(errs); } + +chkuse(blkno, cnt) + daddr_t blkno; + int cnt; +{ + int cg; + daddr_t fsbn, bn; + + fsbn = dbtofsb(fs, blkno); + if ((unsigned)(fsbn+cnt) > fs->fs_size) { + printf("block %d out of range of file system\n", blkno); + return (1); + } + cg = dtog(fs, fsbn); + if (fsbn < cgdmin(fs, cg)) { + if (cg == 0 || (fsbn+cnt) > cgsblock(fs, cg)) { + printf("block %d in non-data area: cannot attach\n", + blkno); + return (1); + } + } else { + if ((fsbn+cnt) > cgbase(fs, cg+1)) { + printf("block %d in non-data area: cannot attach\n", + blkno); + return (1); + } + } + rdfs(fsbtodb(fs, cgtod(fs, cg)), (int)sblock.fs_cgsize, + (char *)&acg); + if (!cg_chkmagic(&acg)) { + fprintf(stderr, "cg %d: bad magic number\n", cg); + errs++; + return (1); + } + bn = dtogd(fs, fsbn); + if (isclr(cg_blksfree(&acg), bn)) + printf("Warning: sector %d is in use\n", blkno); + return (0); +} + +/* + * read a block from the file system + */ +rdfs(bno, size, bf) + int bno, size; + char *bf; +{ + int n; + + if (lseek(fsi, bno * dev_bsize, 0) < 0) { + printf("seek error: %ld\n", bno); + perror("rdfs"); + exit(1); + } + n = read(fsi, bf, size); + if(n != size) { + printf("read error: %ld\n", bno); + perror("rdfs"); + exit(1); + } +}