/* * Copyright (c) 1999 Niall Smart. 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 Niall Smart, niall@pobox.com. * * THIS SOFTWARE IS PROVIDED BY NIALL SMART ``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 NIALL SMART 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 #include #include #include #include #include #include #include #include int main(int argc, char** argv) { int fd; int ret; off_t offset; u_quad_t skip; char* ptr; char buf[SBSIZE]; struct fs* fs = (struct fs*)buf; if (argc != 3) { fprintf(stderr, "usage: %s device skip\n", argv[0]); exit(1); } if ( (fd = open(argv[1], O_RDONLY)) < 0) { perror("open"); exit(1); } if ( (skip = strtouq(argv[2], &ptr, 0)) == QUAD_MAX || *ptr != '\0') { fprintf(stderr, "bad seek value: %s\n", argv[2]); exit(1); } if ( (skip % SBOFF) != 0) fprintf(stderr, "warning: %qu is not a multiple of SBOFF (%d)\n", skip, (int)SBOFF);; if (skip > 0) { fprintf(stderr, "skipping %qu bytes\n", skip); lseek(fd, skip, SEEK_SET); } while (1) { ret = read(fd, buf, sizeof(buf)); if (ret < 0) { perror("read"); exit(1); } /* * based on checks in /sys/ufs/ffs/ffs_vfsops.c, line 478 */ if (fs->fs_magic == FS_MAGIC && fs->fs_bsize <= MAXBSIZE && fs->fs_bsize >= (int32_t)sizeof(struct fs)) { offset = lseek(fd, 0, SEEK_CUR); printf("found superblock: offset=%qd, fs_size=%d, fs_fsmnt=%.*s\n", offset, fs->fs_size, MAXMNTLEN, fs->fs_fsmnt); printf("suggested disklabel entry:\n\n"); printf(" size offset fstype\n"); printf("%8d %8qd 4.2BSD\n\n", fs->fs_size * 2, (offset - 16384) / 512); } } printf("%d:%d\n", sizeof(struct fs), offsetof(struct fs, fs_magic)); return 0; }