Whamcloud - gitweb
806b12d40c37694744c159e84a92fa6227d7d796
[tools/e2fsprogs.git] / misc / findsuper.c
1 /*
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
11  * 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  * 
23  *
24  * Well, here's my linux version of findsuper.
25  * 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
57  * 
58  */
59
60 /*
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
89 #include <stdio.h>
90 #include <stdlib.h>
91 #include <time.h>
92
93 #include <linux/ext2_fs.h>
94 #include "nls-enable.h"
95
96
97 main(int argc, char *argv[])
98 {
99         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;
105
106         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 */
109
110 #ifdef ENABLE_NLS
111         setlocale(LC_MESSAGES, "");
112         bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
113         textdomain(NLS_CAT_NAME);
114 #endif
115         if (argc<2) {
116                 fprintf(stderr,
117                         _("Usage:  findsuper device [skiprate [start]]\n"));
118                 exit(1);
119         }
120         if (argc>2)
121                 skiprate=atoi(argv[2]);
122         if (skiprate<512) {
123                 fprintf(stderr,
124                         _("Do you really want to skip less than a sector??\n"));
125                 exit(2);
126         }
127         if (argc>3)
128                 sk=atol(argv[3]);
129         if (sk<0) {
130                 fprintf(stderr,_("Have to start at 0 or greater,not %ld\n"),sk);
131                 exit(1);
132         }
133         f=fopen(argv[1],"r");
134         if (!f) {
135                 perror(argv[1]);
136                 exit(1);
137         }
138  
139         /* Now, go looking for the superblock ! */
140         printf("  thisoff     block fs_blk_sz  blksz grp last_mount\n");
141         for (;!feof(f) &&  (i=fseek(f,sk,SEEK_SET))!= -1; sk+=skiprate){
142                 if (i=fread(&ext2,sizeof(ext2),1, f)!=1) {
143                         perror(_("read failed"));
144                 }
145                 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);
155         }
156         printf(_("Failed on %d at %ld\n"), i, sk);
157         fclose(f);
158 }