1*22486Sdist /* 2*22486Sdist * Copyright (c) 1983 Regents of the University of California. 3*22486Sdist * All rights reserved. The Berkeley software License Agreement 4*22486Sdist * specifies the terms and conditions for redistribution. 5*22486Sdist */ 63724Sroot 7*22486Sdist #ifndef lint 8*22486Sdist char copyright[] = 9*22486Sdist "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 10*22486Sdist All rights reserved.\n"; 11*22486Sdist #endif not lint 12*22486Sdist 13*22486Sdist #ifndef lint 14*22486Sdist static char sccsid[] = "@(#)badsect.c 5.1 (Berkeley) 06/06/85"; 15*22486Sdist #endif not lint 16*22486Sdist 173724Sroot /* 183724Sroot * badsect 193724Sroot * 203724Sroot * Badsect takes a list of file-system relative sector numbers 213724Sroot * and makes files containing the blocks of which these sectors are a part. 223724Sroot * It can be used to contain sectors which have problems if these sectors 233724Sroot * are not part of the bad file for the pack (see bad144). For instance, 243724Sroot * this program can be used if the driver for the file system in question 253724Sroot * does not support bad block forwarding. 263724Sroot */ 2711272Smckusick #include <stdio.h> 283724Sroot #include <sys/param.h> 2911272Smckusick #include <sys/fs.h> 3011272Smckusick #include <sys/dir.h> 3111272Smckusick #include <sys/stat.h> 3211272Smckusick #include <sys/inode.h> 333724Sroot 3411272Smckusick union { 3511272Smckusick struct fs fs; 3611272Smckusick char fsx[SBSIZE]; 3711272Smckusick } ufs; 3811272Smckusick #define sblock ufs.fs 3911272Smckusick union { 4011272Smckusick struct cg cg; 4111272Smckusick char cgx[MAXBSIZE]; 4211272Smckusick } ucg; 4311272Smckusick #define acg ucg.cg 4411272Smckusick struct fs *fs; 4511272Smckusick int fso, fsi; 4611272Smckusick int errs; 4711272Smckusick 4811272Smckusick char buf[MAXBSIZE]; 4911272Smckusick 5011272Smckusick 513724Sroot main(argc, argv) 523724Sroot int argc; 5311272Smckusick char *argv[]; 543724Sroot { 5511272Smckusick daddr_t number; 5611272Smckusick struct stat stbuf, devstat; 5711272Smckusick register struct direct *dp; 5811272Smckusick DIR *dirp; 5911272Smckusick int fd; 6011272Smckusick char name[BUFSIZ]; 613724Sroot 6211272Smckusick if (argc < 3) { 6311272Smckusick fprintf(stderr, "usage: badsect bbdir blkno [ blkno ]\n"); 6411272Smckusick exit(1); 653724Sroot } 6611272Smckusick if (chdir(argv[1]) < 0 || stat(".", &stbuf) < 0) { 6711272Smckusick perror(argv[1]); 6811272Smckusick exit(2); 6911272Smckusick } 7011272Smckusick strcpy(name, "/dev/"); 7111272Smckusick if ((dirp = opendir(name)) == NULL) { 7211272Smckusick perror(name); 7311272Smckusick exit(3); 7411272Smckusick } 7511272Smckusick while ((dp = readdir(dirp)) != NULL) { 7611272Smckusick strcpy(&name[5], dp->d_name); 7711272Smckusick if (stat(name, &devstat) < 0) { 7811272Smckusick perror(name); 7911272Smckusick exit(4); 8011272Smckusick } 8111272Smckusick if (stbuf.st_dev == devstat.st_rdev && 8211272Smckusick (devstat.st_mode & IFMT) == IFBLK) 8311272Smckusick break; 8411272Smckusick } 8511272Smckusick closedir(dirp); 8611272Smckusick if (dp == NULL) { 8711272Smckusick printf("Cannot find dev 0%o corresponding to %s\n", 8811272Smckusick stbuf.st_rdev, argv[1]); 8911272Smckusick exit(5); 9011272Smckusick } 9111272Smckusick if ((fsi = open(name, 0)) < 0) { 9211272Smckusick perror(name); 9311272Smckusick exit(6); 9411272Smckusick } 9511272Smckusick fs = &sblock; 9611272Smckusick rdfs(SBLOCK, SBSIZE, (char *)fs); 9711272Smckusick for (argc -= 2, argv += 2; argc > 0; argc--, argv++) { 9811272Smckusick number = atoi(*argv); 9911272Smckusick if (chkuse(number, 1)) 10011272Smckusick continue; 10111272Smckusick if (mknod(*argv, IFMT|0600, dbtofsb(fs, number)) < 0) { 10211272Smckusick perror(*argv); 10311272Smckusick errs++; 10411272Smckusick } 10511272Smckusick } 10611272Smckusick printf("Don't forget to run ``fsck %s''\n", name); 1073724Sroot exit(errs); 1083724Sroot } 10911272Smckusick 11011272Smckusick chkuse(blkno, cnt) 11111272Smckusick daddr_t blkno; 11211272Smckusick int cnt; 11311272Smckusick { 11411272Smckusick int cg; 11511272Smckusick daddr_t fsbn, bn; 11611272Smckusick 11711272Smckusick fsbn = dbtofsb(fs, blkno); 11811272Smckusick if ((unsigned)(fsbn+cnt) > fs->fs_size) { 11911272Smckusick printf("block %d out of range of file system\n", blkno); 12011272Smckusick return (1); 12111272Smckusick } 12211272Smckusick cg = dtog(fs, fsbn); 12311272Smckusick if (fsbn < cgdmin(fs, cg)) { 12411272Smckusick if (cg == 0 || (fsbn+cnt) > cgsblock(fs, cg)) { 12511272Smckusick printf("block %d in non-data area: cannot attach\n", 12611272Smckusick blkno); 12711272Smckusick return (1); 12811272Smckusick } 12911272Smckusick } else { 13011272Smckusick if ((fsbn+cnt) > cgbase(fs, cg+1)) { 13111272Smckusick printf("block %d in non-data area: cannot attach\n", 13211272Smckusick blkno); 13311272Smckusick return (1); 13411272Smckusick } 13511272Smckusick } 13611272Smckusick rdfs(fsbtodb(fs, cgtod(fs, cg)), (int)sblock.fs_cgsize, 13711272Smckusick (char *)&acg); 13811272Smckusick if (acg.cg_magic != CG_MAGIC) { 13911272Smckusick fprintf(stderr, "cg %d: bad magic number\n", cg); 14011272Smckusick errs++; 14111272Smckusick return; 14211272Smckusick } 14311272Smckusick bn = dtogd(fs, fsbn); 14411272Smckusick if (isclr(acg.cg_free, bn)) 14511272Smckusick printf("Warning: sector %d is in use\n", blkno); 14611272Smckusick return (0); 14711272Smckusick } 14811272Smckusick 14911272Smckusick /* 15011272Smckusick * read a block from the file system 15111272Smckusick */ 15211272Smckusick rdfs(bno, size, bf) 15311272Smckusick int bno, size; 15411272Smckusick char *bf; 15511272Smckusick { 15611272Smckusick int n; 15711272Smckusick 15811272Smckusick if (lseek(fsi, bno * DEV_BSIZE, 0) < 0) { 15911272Smckusick printf("seek error: %ld\n", bno); 16011272Smckusick perror("rdfs"); 16111272Smckusick exit(1); 16211272Smckusick } 16311272Smckusick n = read(fsi, bf, size); 16411272Smckusick if(n != size) { 16511272Smckusick printf("read error: %ld\n", bno); 16611272Smckusick perror("rdfs"); 16711272Smckusick exit(1); 16811272Smckusick } 16911272Smckusick } 170