1 /* 2 * This program, created 2002-10-03 by Garrett A. Wollman 3 * <wollman@FreeBSD.org>, is in the public domain. Use at your own risk. 4 * 5 * $FreeBSD$ 6 */ 7 8 #ifdef __FreeBSD__ 9 #include <sys/param.h> 10 11 #include <ufs/ufs/dinode.h> 12 #include <ufs/ffs/fs.h> 13 #else 14 #include "mini_ufs.h" 15 #endif 16 17 #include <err.h> 18 #include <fcntl.h> 19 #include <inttypes.h> 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <string.h> 23 #include <unistd.h> 24 25 static union { 26 char buf[SBLOCKSIZE]; 27 struct fs sblock; 28 } u; 29 30 int 31 main(int argc, char **argv) 32 { 33 off_t end, last1, last2; 34 size_t len; 35 ssize_t justread; 36 int fd; 37 char *ch; 38 char c; 39 intmax_t offset; 40 41 offset = 0; 42 while ((c = getopt(argc, argv, "o:")) != -1) { 43 switch (c) { 44 case 'o': 45 if (optarg[0] == '\0') 46 errx(1, "usage"); 47 offset = strtoimax(optarg, &ch, 10); 48 if (*ch != '\0' || offset < 0) 49 errx(1, "usage"); 50 offset -= offset % DEV_BSIZE; 51 break; 52 53 default: 54 errx(1, "usage"); 55 } 56 } 57 argc -= optind; 58 argv += optind; 59 60 if (argc != 1) 61 errx(1, "usage"); 62 63 fd = open(argv[0], O_RDONLY, 0); 64 if (fd < 0) 65 err(1, "%s", argv[0]); 66 67 if (offset != 0) { 68 end = lseek(fd, offset, SEEK_SET); 69 if (end == -1) 70 err(1, "%s", argv[0]); 71 } else { 72 end = 0; 73 } 74 len = 0; 75 last1 = last2 = -1; 76 77 while (1) { 78 justread = read(fd, &u.buf[len], DEV_BSIZE); 79 if (justread != DEV_BSIZE) { 80 if (justread == 0) { 81 printf("reached end-of-file at %jd\n", 82 (intmax_t)end); 83 exit (0); 84 } 85 if (justread < 0) 86 err(1, "read"); 87 errx(1, "short read %jd (wanted %d) at %jd", 88 (intmax_t)justread, DEV_BSIZE, (intmax_t)end); 89 } 90 len += DEV_BSIZE; 91 end += DEV_BSIZE; 92 if (len >= sizeof(struct fs)) { 93 offset = end - len; 94 95 if (u.sblock.fs_magic == FS_UFS1_MAGIC) { 96 intmax_t fsbegin = offset - SBLOCK_UFS1; 97 printf("Found UFS1 superblock at offset %jd, " 98 "block %jd\n", offset, 99 offset / DEV_BSIZE); 100 printf("Filesystem might begin at offset %jd, " 101 "block %jd\n", fsbegin, 102 fsbegin / DEV_BSIZE); 103 if (last1 >= 0) { 104 printf("%jd blocks from last guess\n", 105 fsbegin / DEV_BSIZE - last1); 106 } 107 last1 = fsbegin / DEV_BSIZE; 108 len -= DEV_BSIZE; 109 memmove(u.buf, &u.buf[DEV_BSIZE], len); 110 } else if (u.sblock.fs_magic == FS_UFS2_MAGIC) { 111 intmax_t fsbegin = offset - SBLOCK_UFS2; 112 printf("Found UFS2 superblock at offset %jd, " 113 "block %jd\n", offset, 114 offset / DEV_BSIZE); 115 printf("Filesystem might begin at offset %jd, " 116 "block %jd\n", fsbegin, 117 fsbegin / DEV_BSIZE); 118 if (last2 >= 0) { 119 printf("%jd blocks from last guess\n", 120 fsbegin / DEV_BSIZE - last2); 121 } 122 last2 = fsbegin / DEV_BSIZE; 123 len -= DEV_BSIZE; 124 memmove(u.buf, &u.buf[DEV_BSIZE], len); 125 } 126 } 127 if (len >= SBLOCKSIZE) { 128 memmove(u.buf, &u.buf[DEV_BSIZE], 129 SBLOCKSIZE - DEV_BSIZE); 130 len -= DEV_BSIZE; 131 } 132 } 133 } 134