blob: 35bf9b960e33e4b369c97d8d2d92401aec9f9d3d [file] [log] [blame]
Theodore Ts'o74a74d22000-12-09 14:33:29 +00001/*
2 * findsuper --- quick hacked up program to find ext2 superblocks.
3 *
4 * This is a hack, and really shouldn't be installed anywhere. If you
5 * need a program which does this sort of functionality, please try
6 * using gpart program.
7 *
8 * Portions Copyright 1998-2000, Theodore Ts'o.
9 *
10 * This program may be used under the provisions of the GNU Public
Theodore Ts'o26900ae2000-12-09 21:46:59 +000011 * License, *EXCEPT* that a binary copy of the executable may not be
12 * packaged as a part of binary package which is distributed as part
13 * of a Linux distribution. (Yes, this violates the Debian Free
14 * Software Guidelines in terms of restricting its field of use.
15 * That's the point. I don't want this program being distributed in
16 * Debian, because I don't care to support it, and the maintainer,
17 * Yann Dirson, doesn't seem to pay attention to my wishes on this
18 * matter. So I'm delibiately adding this clause so it violates the
19 * Debian Free Software Guidelines to force him to take it out. If
20 * this doesn't work, I'll have to remove it from the upstream source
21 * distribution at the next release. End of Rant. :-)
22 *
Theodore Ts'o74a74d22000-12-09 14:33:29 +000023 *
24 * Well, here's my linux version of findsuper.
Theodore Ts'o7f88b041997-04-26 14:48:50 +000025 * I'm sure you coulda done it faster. :)
26 * IMHO there isn't as much interesting data to print in the
27 * linux superblock as there is in the SunOS superblock--disk geometry is
28 * not there...and linux seems to update the dates in all the superblocks.
29 * SunOS doesn't ever touch the backup superblocks after the fs is created,
30 * as far as I can tell, so the date is more interesting IMHO and certainly
31 * marks which superblocks are backup ones.
32 *
33 * This still doesn't handle disks >2G.
34 *
35 * I wanted to add msdos support, but I couldn't make heads or tails
36 * of the kernel include files to find anything I could look for in msdos.
37 *
38 * Reading every block of a Sun partition is fairly quick. Doing the
39 * same under linux (slower hardware I suppose) just isn't the same.
40 * It might be more useful to default to reading the first (second?) block
41 * on each cyl; however, if the disk geometry is wrong, this is useless.
42 * But ya could still get the cyl size to print the numbers as cyls instead
43 * of blocks...
44 *
45 * run this as (for example)
46 * findsuper /dev/hda
47 * findsuper /dev/hda 437760 1024 (my disk has cyls of 855*512)
48 *
49 * I suppose the next step is to figgure out a way to determine if
50 * the block found is the first superblock somehow, and if so, build
51 * a partition table from the superblocks found... but this is still
52 * useful as is.
53 *
54 * Steve
55 * ssd@nevets.oau.org
56 * ssd@mae.engr.ucf.edu
Theodore Ts'oe2423cc1999-06-18 00:51:31 +000057 *
Theodore Ts'o7f88b041997-04-26 14:48:50 +000058 */
59
Theodore Ts'oe2423cc1999-06-18 00:51:31 +000060/*
61 * Documentation addendum added by Andreas dwguest@win.tue.nl/aeb@cwi.nl
62 *
63 * The program findsuper is a utility that scans a disk and finds
64 * copies of ext2 superblocks (by checking for the ext2 signature; it
65 * will occasionally find other blocks that by coincidence have this
66 * signature - often these can be recognised by their ridiculous
67 * dates).
68 *
69 * For each superblock found, it prints the offset in bytes, the
70 * offset in 1024-byte blocks, the size of ext2 partition in 1024-byte
71 * blocks, the filesystem blocksize (given as log(blocksize)-10, so
72 * that 0 means 1024), the block group number (0 for older ext2
73 * systems), and a timestamp (s_mtime).
74 *
75 * This program can be used to retrieve partitions that have been
76 * lost. The superblock for block group 0 is found 1 block (2
77 * sectors) after the partition start.
78 *
79 * For new systems that have a block group number in the superblock it
80 * is immediately clear which superblock is the first of a partition.
81 * For old systems where no group numbers are given, the first
82 * superblock can be recognised by the timestamp: all superblock
83 * copies have the creation time in s_mtime, except the first, which
84 * has the last time e2fsck or tune2fs wrote to the filesystem.
85 *
86 */
87
88
Theodore Ts'o7f88b041997-04-26 14:48:50 +000089#include <stdio.h>
90#include <stdlib.h>
91#include <time.h>
92
Theodore Ts'o54c637d2001-05-14 11:45:38 +000093#include "ext2fs/ext2_fs.h"
Theodore Ts'od9c56d32000-02-08 00:47:55 +000094#include "nls-enable.h"
Theodore Ts'o7f88b041997-04-26 14:48:50 +000095
96
97main(int argc, char *argv[])
98{
Theodore Ts'o19c78dc1997-04-29 16:17:09 +000099 int i;
100 int skiprate=512; /* one sector */
101 long sk=0; /* limited to 2G filesystems!! */
102 FILE *f;
103 char *s;
104 time_t tm;
Theodore Ts'o7f88b041997-04-26 14:48:50 +0000105
Theodore Ts'o19c78dc1997-04-29 16:17:09 +0000106 struct ext2_super_block ext2;
107 /* interesting fields: EXT2_SUPER_MAGIC
108 * s_blocks_count s_log_block_size s_mtime s_magic s_lastcheck */
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000109
110#ifdef ENABLE_NLS
111 setlocale(LC_MESSAGES, "");
112 bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
113 textdomain(NLS_CAT_NAME);
114#endif
Theodore Ts'o19c78dc1997-04-29 16:17:09 +0000115 if (argc<2) {
116 fprintf(stderr,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000117 _("Usage: findsuper device [skiprate [start]]\n"));
Theodore Ts'o19c78dc1997-04-29 16:17:09 +0000118 exit(1);
119 }
120 if (argc>2)
121 skiprate=atoi(argv[2]);
122 if (skiprate<512) {
123 fprintf(stderr,
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000124 _("Do you really want to skip less than a sector??\n"));
Theodore Ts'o19c78dc1997-04-29 16:17:09 +0000125 exit(2);
126 }
127 if (argc>3)
128 sk=atol(argv[3]);
129 if (sk<0) {
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000130 fprintf(stderr,_("Have to start at 0 or greater,not %ld\n"),sk);
Theodore Ts'o19c78dc1997-04-29 16:17:09 +0000131 exit(1);
132 }
133 f=fopen(argv[1],"r");
134 if (!f) {
135 perror(argv[1]);
136 exit(1);
137 }
Theodore Ts'o7f88b041997-04-26 14:48:50 +0000138
Theodore Ts'o19c78dc1997-04-29 16:17:09 +0000139 /* Now, go looking for the superblock ! */
Theodore Ts'oeb5ab741998-07-04 17:47:52 +0000140 printf(" thisoff block fs_blk_sz blksz grp last_mount\n");
Theodore Ts'o19c78dc1997-04-29 16:17:09 +0000141 for (;!feof(f) && (i=fseek(f,sk,SEEK_SET))!= -1; sk+=skiprate){
142 if (i=fread(&ext2,sizeof(ext2),1, f)!=1) {
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000143 perror(_("read failed"));
Theodore Ts'o19c78dc1997-04-29 16:17:09 +0000144 }
Theodore Ts'oe2423cc1999-06-18 00:51:31 +0000145 if (ext2.s_magic != EXT2_SUPER_MAGIC)
146 continue;
147
148 tm = ext2.s_mtime;
149 s=ctime(&tm);
150 s[24]=0;
151 printf("%9ld %9ld %9ld %5ld %4d %s\n", sk,
152 sk/1024, ext2.s_blocks_count,
153 ext2.s_log_block_size,
154 ext2.s_block_group_nr, s);
Theodore Ts'o19c78dc1997-04-29 16:17:09 +0000155 }
Theodore Ts'od9c56d32000-02-08 00:47:55 +0000156 printf(_("Failed on %d at %ld\n"), i, sk);
Theodore Ts'o19c78dc1997-04-29 16:17:09 +0000157 fclose(f);
Theodore Ts'o7f88b041997-04-26 14:48:50 +0000158}