1104442Swollman/* 2104442Swollman * This program, created 2002-10-03 by Garrett A. Wollman 3104442Swollman * <wollman@FreeBSD.org>, is in the public domain. Use at your own risk. 4104442Swollman * 5104442Swollman * $FreeBSD$ 6104442Swollman */ 7104442Swollman 8158297Ssobomax#ifdef __FreeBSD__ 9104442Swollman#include <sys/param.h> 10104442Swollman 11104442Swollman#include <ufs/ufs/dinode.h> 12104442Swollman#include <ufs/ffs/fs.h> 13158297Ssobomax#else 14158297Ssobomax#include "mini_ufs.h" 15158297Ssobomax#endif 16104442Swollman 17104442Swollman#include <err.h> 18104442Swollman#include <fcntl.h> 19104442Swollman#include <inttypes.h> 20104442Swollman#include <stdio.h> 21104442Swollman#include <stdlib.h> 22104442Swollman#include <string.h> 23104442Swollman#include <unistd.h> 24104442Swollman 25104442Swollmanstatic union { 26104442Swollman char buf[SBLOCKSIZE]; 27104442Swollman struct fs sblock; 28104442Swollman} u; 29104442Swollman 30104442Swollmanint 31104442Swollmanmain(int argc, char **argv) 32104442Swollman{ 33158526Ssobomax off_t end, last1, last2; 34104442Swollman size_t len; 35104442Swollman ssize_t justread; 36104442Swollman int fd; 37158526Ssobomax char *ch; 38158526Ssobomax char c; 39158526Ssobomax intmax_t offset; 40104442Swollman 41162720Sru offset = 0; 42158526Ssobomax while ((c = getopt(argc, argv, "o:")) != -1) { 43158526Ssobomax switch (c) { 44158526Ssobomax case 'o': 45158526Ssobomax if (optarg[0] == '\0') 46158526Ssobomax errx(1, "usage"); 47158526Ssobomax offset = strtoimax(optarg, &ch, 10); 48158526Ssobomax if (*ch != '\0' || offset < 0) 49158526Ssobomax errx(1, "usage"); 50158526Ssobomax offset -= offset % DEV_BSIZE; 51158526Ssobomax break; 52158526Ssobomax 53158526Ssobomax default: 54158526Ssobomax errx(1, "usage"); 55158526Ssobomax } 56158526Ssobomax } 57158526Ssobomax argc -= optind; 58158526Ssobomax argv += optind; 59158526Ssobomax 60158526Ssobomax if (argc != 1) 61104442Swollman errx(1, "usage"); 62104442Swollman 63158526Ssobomax fd = open(argv[0], O_RDONLY, 0); 64104442Swollman if (fd < 0) 65158526Ssobomax err(1, "%s", argv[0]); 66104442Swollman 67158526Ssobomax if (offset != 0) { 68158526Ssobomax end = lseek(fd, offset, SEEK_SET); 69158526Ssobomax if (end == -1) 70158526Ssobomax err(1, "%s", argv[0]); 71158526Ssobomax } else { 72158526Ssobomax end = 0; 73158526Ssobomax } 74158526Ssobomax len = 0; 75158526Ssobomax last1 = last2 = -1; 76158526Ssobomax 77104442Swollman while (1) { 78104442Swollman justread = read(fd, &u.buf[len], DEV_BSIZE); 79104442Swollman if (justread != DEV_BSIZE) { 80104442Swollman if (justread == 0) { 81104442Swollman printf("reached end-of-file at %jd\n", 82104442Swollman (intmax_t)end); 83104442Swollman exit (0); 84104442Swollman } 85104442Swollman if (justread < 0) 86104442Swollman err(1, "read"); 87104442Swollman errx(1, "short read %jd (wanted %d) at %jd", 88104442Swollman (intmax_t)justread, DEV_BSIZE, (intmax_t)end); 89104442Swollman } 90104442Swollman len += DEV_BSIZE; 91104442Swollman end += DEV_BSIZE; 92104442Swollman if (len >= sizeof(struct fs)) { 93158526Ssobomax offset = end - len; 94104442Swollman 95104442Swollman if (u.sblock.fs_magic == FS_UFS1_MAGIC) { 96104442Swollman intmax_t fsbegin = offset - SBLOCK_UFS1; 97104442Swollman printf("Found UFS1 superblock at offset %jd, " 98104442Swollman "block %jd\n", offset, 99104442Swollman offset / DEV_BSIZE); 100104442Swollman printf("Filesystem might begin at offset %jd, " 101104442Swollman "block %jd\n", fsbegin, 102104442Swollman fsbegin / DEV_BSIZE); 103158526Ssobomax if (last1 >= 0) { 104104442Swollman printf("%jd blocks from last guess\n", 105158526Ssobomax fsbegin / DEV_BSIZE - last1); 106104442Swollman } 107158526Ssobomax last1 = fsbegin / DEV_BSIZE; 108158526Ssobomax len -= DEV_BSIZE; 109158526Ssobomax memmove(u.buf, &u.buf[DEV_BSIZE], len); 110104442Swollman } else if (u.sblock.fs_magic == FS_UFS2_MAGIC) { 111158297Ssobomax intmax_t fsbegin = offset - SBLOCK_UFS2; 112104442Swollman printf("Found UFS2 superblock at offset %jd, " 113104442Swollman "block %jd\n", offset, 114104442Swollman offset / DEV_BSIZE); 115104442Swollman printf("Filesystem might begin at offset %jd, " 116104442Swollman "block %jd\n", fsbegin, 117104442Swollman fsbegin / DEV_BSIZE); 118158526Ssobomax if (last2 >= 0) { 119104442Swollman printf("%jd blocks from last guess\n", 120158526Ssobomax fsbegin / DEV_BSIZE - last2); 121104442Swollman } 122158526Ssobomax last2 = fsbegin / DEV_BSIZE; 123158526Ssobomax len -= DEV_BSIZE; 124158526Ssobomax memmove(u.buf, &u.buf[DEV_BSIZE], len); 125104442Swollman } 126104442Swollman } 127104442Swollman if (len >= SBLOCKSIZE) { 128104442Swollman memmove(u.buf, &u.buf[DEV_BSIZE], 129104442Swollman SBLOCKSIZE - DEV_BSIZE); 130104442Swollman len -= DEV_BSIZE; 131104442Swollman } 132104442Swollman } 133104442Swollman} 134