diff options
author | bde <bde@FreeBSD.org> | 1995-04-02 16:36:39 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1995-04-02 16:36:39 +0000 |
commit | 7caaf6f20052c6406feca4802b6bb8eb5dd59db2 (patch) | |
tree | 819ca4e25504b405c638df6f4cb96b1bd242011d | |
parent | 7d745e5a93e3605f065808ca83cb2a5012af188a (diff) | |
download | FreeBSD-src-7caaf6f20052c6406feca4802b6bb8eb5dd59db2.zip FreeBSD-src-7caaf6f20052c6406feca4802b6bb8eb5dd59db2.tar.gz |
Make this actually work. It always failed in FreeBSD because it attempted
to open the mounted block device containing the directory to put the bad
sector files in, and opening of mounted block devices hasn't been allowed
since Net/2 or before. Attempt to open the raw device instead. Be more
careful about long names.
Use lstat() instead of stat() to search for block devices so that my
symlink to the default floppy doesn't cause problems.
Check for truncation of the block number when it is squeezed through the
mknod() interface. The maximum used to be only 32767, but now it large
enough.
-rw-r--r-- | sbin/badsect/badsect.c | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/sbin/badsect/badsect.c b/sbin/badsect/badsect.c index fa978b1..ce81179 100644 --- a/sbin/badsect/badsect.c +++ b/sbin/badsect/badsect.c @@ -89,11 +89,13 @@ main(argc, argv) int argc; char *argv[]; { + daddr_t diskbn; daddr_t number; struct stat stbuf, devstat; register struct direct *dp; DIR *dirp; - char name[BUFSIZ]; + char name[2 * MAXPATHLEN]; + char *name_dir_end; if (argc < 3) { fprintf(stderr, "usage: badsect bbdir blkno [ blkno ]\n"); @@ -108,9 +110,10 @@ main(argc, argv) perror(name); exit(3); } + name_dir_end = name + strlen(name); while ((dp = readdir(dirp)) != NULL) { - strcpy(&name[5], dp->d_name); - if (stat(name, &devstat) < 0) { + strcpy(name_dir_end, dp->d_name); + if (lstat(name, &devstat) < 0) { perror(name); exit(4); } @@ -124,7 +127,13 @@ main(argc, argv) stbuf.st_rdev, argv[1]); exit(5); } - if ((fsi = open(name, 0)) < 0) { + /* + * Opening of a mounted on device is not allowed. + * Attempt to open the raw device instead. + */ + memcpy(name_dir_end + 1, name_dir_end, strlen(name_dir_end) + 1); + *name_dir_end = 'r'; + if ((fsi = open(name, O_RDONLY)) < 0) { perror(name); exit(6); } @@ -132,10 +141,22 @@ main(argc, argv) 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); + number = atol(*argv); if (chkuse(number, 1)) continue; - if (mknod(*argv, IFMT|0600, dbtofsb(fs, number)) < 0) { + /* + * Print a warning if converting the block number to a dev_t + * will truncate it. badsect was not very useful in versions + * of BSD before 4.4 because dev_t was 16 bits and another + * bit was lost by bogus sign extensions. + */ + diskbn = dbtofsb(fs, number); + if ((dev_t)diskbn != diskbn) { + printf("sector %d cannot be represented as a dev_t\n", + number); + errs++; + } + else if (mknod(*argv, IFMT|0600, (dev_t)diskbn) < 0) { perror(*argv); errs++; } |