Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Feb 2003 22:20:12 +0100
From:      Michael Ranner <mranner@inode.at>
To:        freebsd-fs@freebsd.org
Cc:        freebsd-hackers@freebsd.org
Subject:   scan_ffs for UFS2
Message-ID:  <200302192220.12731.mranner@inode.at>

next in thread | raw e-mail | index | archive | help

--Boundary-00=_MU/U+5seNB+VrtY
Content-Type: text/plain;
  charset="us-ascii"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline


Hello!

I am trying to learn scan_ffs (original from OpenBSD, ported to FreeBSD
by Robert Watson) about UFS2 on 5-CURRENT, but it will not find the
Superblock and I dont understand exactly both for loops, especially
that 512 byte increment.

Scan_ffs is a system tool from OpenBSD to recover erased disklabels
from your hard drive.

Thanks for your input.

-- 
/\/\ichael Ranner

mranner@jawa.at - mranner@bitonline.cc - webmaster@mariazell.at
----------------------------------------------------------------------
JAWA Management Software GmbH - http://www.jawa.at/
  Liebenauer Hauptstrasse 2oo - A-8041 Graz
        Tel +43 316 403274 21 - Fax +43 316 403274 10
----------------------------------------------------------------------
             Mariazell Online - http://www.mariazell.at/
----------------------------------------------------------------------

-----BEGIN GEEK CODE BLOCK-----
GIT/CS/AT dx(-) s+:(++:) a- C++ UBLVS++++$ P++>+++$ L-(+)$ E---
W+++$ N+(++) o-- K- w--()$ O-(--) M@ V-(--) PS+>++ PE(-) Y+ PGP(-)
t+ 5+ X+++(++++) R* tv++ b+(++) DI++ D-(--) G- e h--(*) r++ y?
------END GEEK CODE BLOCK------

--Boundary-00=_MU/U+5seNB+VrtY
Content-Type: text/x-csrc;
  charset="us-ascii";
  name="scan_ffs.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="scan_ffs.c"

/*	$OpenBSD: scan_ffs.c,v 1.8 2002/07/03 22:32:33 deraadt Exp $	*/

/*
 * Copyright (c) 1998 Niklas Hallqvist, Tobias Weingartner
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    This product includes software developed by Tobias Weingartner.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/types.h>
#include <sys/param.h>
#include <sys/fcntl.h>
#ifdef __FreeBSD__
#include <ufs/ufs/dinode.h>
#endif
#include <ufs/ffs/fs.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <err.h>
#if 0
#include <util.h>
#endif

#ifdef __FreeBSD__
#define SBSIZE SBLOCKSIZE
#endif
#define SBCOUNT 64		/* XXX - Should be configurable */

/* Flags to control ourselves... */
#define FLAG_VERBOSE		1
#define FLAG_SMART		2
#define FLAG_LABELS		4

int
ufsscan(int fd, daddr_t beg, daddr_t end, int flags)
{
	static char lastmount[MAXMNTLEN];
	static u_int8_t buf[SBSIZE * SBCOUNT];
	struct fs *sb;
	daddr_t blk, lastblk;
	int n;

	lastblk = -1;
	memset(lastmount, 0, MAXMNTLEN);

	for (blk = beg; blk <= ((end<0)?blk:end); blk += (SBCOUNT*SBSIZE/512)){
		memset(buf, 0, SBSIZE * SBCOUNT);
		if (lseek(fd, (off_t)blk * 512, SEEK_SET) < 0)
		    err(1, "lseek");
		if (read(fd, buf, SBSIZE * SBCOUNT) < 0)
			err(1, "read");

		for (n = 0; n < (SBSIZE * SBCOUNT); n += 512){
			sb = (struct fs*)(&buf[n]);
			if ((sb->fs_magic == FS_UFS1_MAGIC) ||
			    (sb->fs_magic == FS_UFS2_MAGIC)) {
				if (flags & FLAG_VERBOSE)
					printf("block %d id %x,%x size %d\n",
					    blk + (n/512), sb->fs_id[0],
					    sb->fs_id[1], sb->fs_size);

				if (((blk+(n/512)) - lastblk) == (SBSIZE/512)) {
					if (flags & FLAG_LABELS ) {
#ifdef __FreeBSD__
						printf("X: %lld %lld 4.2BSD %ld %ld %ld # %s\n",
#else
						printf("X: %d %d 4.2BSD %d %d %d # %s\n",
#endif
						    (daddr_t)((off_t)sb->fs_size *
						    sb->fs_fsize / 512),
						    blk+(n/512)-(2*SBSIZE/512),
						    sb->fs_fsize, sb->fs_bsize,
						    sb->fs_old_cpg, lastmount);
					} else {
#ifdef __FreeBSD__
						printf("ufs1 at %lld size %lld mount %s time %s\n",
#else
						printf("ffs1 at %d size %lld mount %s time %s\n",
#endif
		  				    blk+(n/512)-(2*SBSIZE/512),
	    				    (long long)(off_t)sb->fs_size *
							    sb->fs_fsize,
						    lastmount, ctime((time_t *)&sb->fs_time));
					}

					if (flags & FLAG_SMART) {
						off_t size = (off_t)sb->fs_size *
						    sb->fs_fsize;

						if ((n + size) < (SBSIZE * SBCOUNT))
							n += size;
						else {
							blk += (size/512 -
							    (SBCOUNT*SBCOUNT));
							break;
						}
					}
				}

				/* Update last potential FS SBs seen */
				lastblk = blk + (n/512);
				memcpy(lastmount, sb->fs_fsmnt, MAXMNTLEN);
			}
		}
	}
	return(0);
}


void
usage(int code)
{
	extern char *__progname;

	fprintf(stderr, "usage: %s [-lsv] [-b begin] [-e end] device\n",
	    __progname);
	exit(code);
}


int
main(int argc, char *argv[])
{
#ifdef __FreeBSD__
	char *name;
#endif
	int ch, fd, flags = 0;
	daddr_t beg = 0, end = -1;

	while ((ch = getopt(argc, argv, "lsvb:e:")) != -1)
		switch(ch) {
		case 'b':
			beg = atoi(optarg);
			break;
		case 'e':
			end = atoi(optarg);
			break;
		case 'v':
			flags |= FLAG_VERBOSE;
			break;
		case 's':
			flags |= FLAG_SMART;
			break;
		case 'l':
			flags |= FLAG_LABELS;
			break;
		default:
			usage(1);
			/* NOTREACHED */
	}
	argc -= optind;
	argv += optind;

	if (argc != 1)
		usage(1);

#ifdef __FreeBSD__
	if (argv[0][0] != '/') {
		if (asprintf(&name, "/dev/%s", argv[0]) == -1)
			err(1, "%s", argv[1]);
	} else
		name = argv[0];
	fd = open(name, O_RDONLY);
#else
	fd = opendev(argv[0], O_RDONLY, OPENDEV_PART, NULL);
#endif
	if (fd < 0)
		err(1, "%s", argv[1]);
#ifdef __FreeBSD__
	if (name != argv[0])
		free(name);
#endif

	return (ufsscan(fd, beg, end, flags));
}

--Boundary-00=_MU/U+5seNB+VrtY--


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-fs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200302192220.12731.mranner>