find-sb.c revision 158297
1178676Ssam/*
2254204Sadrian * This program, created 2002-10-03 by Garrett A. Wollman
3254204Sadrian * <wollman@FreeBSD.org>, is in the public domain.  Use at your own risk.
4198429Srpaulo *
5178676Ssam * $FreeBSD: head/tools/tools/find-sb/find-sb.c 158297 2006-05-05 00:19:24Z sobomax $
6178676Ssam */
7178676Ssam
8178676Ssam#ifdef __FreeBSD__
9178676Ssam#include <sys/param.h>
10178676Ssam
11178676Ssam#include <ufs/ufs/dinode.h>
12178676Ssam#include <ufs/ffs/fs.h>
13178676Ssam#else
14178676Ssam#include "mini_ufs.h"
15178676Ssam#endif
16178676Ssam
17178676Ssam#include <err.h>
18178676Ssam#include <fcntl.h>
19178676Ssam#include <inttypes.h>
20178676Ssam#include <stdio.h>
21178676Ssam#include <stdlib.h>
22178676Ssam#include <string.h>
23178676Ssam#include <unistd.h>
24201209Srpaulo
25201209Srpaulostatic union {
26178676Ssam	char buf[SBLOCKSIZE];
27178676Ssam	struct fs sblock;
28178676Ssam} u;
29178676Ssam
30178676Ssamint
31243692Sadrianmain(int argc, char **argv)
32253868Sadrian{
33243692Sadrian	off_t end, last;
34178676Ssam	size_t len;
35178676Ssam	ssize_t justread;
36178676Ssam	int fd;
37178676Ssam
38178676Ssam	if (argv[1] == NULL)
39178676Ssam		errx(1, "usage");
40178676Ssam
41178676Ssam	fd = open(argv[1], O_RDONLY, 0);
42178676Ssam	if (fd < 0)
43178676Ssam		err(1, "%s", argv[1]);
44178676Ssam
45178676Ssam	end = len = 0;
46178676Ssam	last = -1;
47178676Ssam	while (1) {
48178676Ssam		justread = read(fd, &u.buf[len], DEV_BSIZE);
49178676Ssam		if (justread != DEV_BSIZE) {
50178676Ssam			if (justread == 0) {
51178676Ssam				printf("reached end-of-file at %jd\n",
52178676Ssam				       (intmax_t)end);
53178676Ssam				exit (0);
54178676Ssam			}
55178676Ssam			if (justread < 0)
56178676Ssam				err(1, "read");
57178676Ssam			errx(1, "short read %jd (wanted %d) at %jd",
58178676Ssam			     (intmax_t)justread, DEV_BSIZE, (intmax_t)end);
59178676Ssam		}
60178676Ssam		len += DEV_BSIZE;
61178676Ssam		end += DEV_BSIZE;
62178676Ssam		if (len >= sizeof(struct fs)) {
63178676Ssam			intmax_t offset = end - len;
64178676Ssam
65178676Ssam			if (u.sblock.fs_magic == FS_UFS1_MAGIC) {
66178676Ssam				intmax_t fsbegin = offset - SBLOCK_UFS1;
67178676Ssam				printf("Found UFS1 superblock at offset %jd, "
68178676Ssam				       "block %jd\n", offset,
69178676Ssam				       offset / DEV_BSIZE);
70178676Ssam				printf("Filesystem might begin at offset %jd, "
71178676Ssam				       "block %jd\n", fsbegin,
72178676Ssam				       fsbegin / DEV_BSIZE);
73178676Ssam				if (last >= 0) {
74178676Ssam					printf("%jd blocks from last guess\n",
75206358Srpaulo					       fsbegin / DEV_BSIZE - last);
76178676Ssam				}
77178676Ssam				last = fsbegin / DEV_BSIZE;
78178676Ssam			} else if (u.sblock.fs_magic == FS_UFS2_MAGIC) {
79253897Sadrian				intmax_t fsbegin = offset - SBLOCK_UFS2;
80178676Ssam				printf("Found UFS2 superblock at offset %jd, "
81220723Sbschmidt				       "block %jd\n", offset,
82220723Sbschmidt				       offset / DEV_BSIZE);
83220723Sbschmidt				printf("Filesystem might begin at offset %jd, "
84220723Sbschmidt				       "block %jd\n", fsbegin,
85220723Sbschmidt				       fsbegin / DEV_BSIZE);
86220723Sbschmidt				if (last >= 0) {
87220895Sbschmidt					printf("%jd blocks from last guess\n",
88253897Sadrian					       fsbegin / DEV_BSIZE - last);
89253897Sadrian				}
90253897Sadrian				last = fsbegin / DEV_BSIZE;
91253897Sadrian			}
92253897Sadrian		}
93253897Sadrian		if (len >= SBLOCKSIZE) {
94253897Sadrian			memmove(u.buf, &u.buf[DEV_BSIZE],
95253897Sadrian				SBLOCKSIZE - DEV_BSIZE);
96253897Sadrian			len -= DEV_BSIZE;
97253897Sadrian		}
98253897Sadrian	}
99253897Sadrian}
100253897Sadrian