findsuper.c revision 74a74d22d8ed60587afd55c798f08531115f4920
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 it may not be included in the Debian 12 * distribution. (Yes, this violates the Debian Free Software 13 * Guidelines. That's the point. I don't want this program being 14 * distributed in Debian, because I don't care to support it, and the 15 * maintainer, Yann Dirson, doesn't seem to pay attention to my wishes 16 * on this matter. So I'm delibiately adding this clause so it 17 * violates the Debian Free Software Guidelines to force him to take 18 * it out. If this doesn't work, I'll have to remove it from the 19 * upstream source distribution on the next release. So there. :-) 20 * 21 * Well, here's my linux version of findsuper. 22 * I'm sure you coulda done it faster. :) 23 * IMHO there isn't as much interesting data to print in the 24 * linux superblock as there is in the SunOS superblock--disk geometry is 25 * not there...and linux seems to update the dates in all the superblocks. 26 * SunOS doesn't ever touch the backup superblocks after the fs is created, 27 * as far as I can tell, so the date is more interesting IMHO and certainly 28 * marks which superblocks are backup ones. 29 * 30 * This still doesn't handle disks >2G. 31 * 32 * I wanted to add msdos support, but I couldn't make heads or tails 33 * of the kernel include files to find anything I could look for in msdos. 34 * 35 * Reading every block of a Sun partition is fairly quick. Doing the 36 * same under linux (slower hardware I suppose) just isn't the same. 37 * It might be more useful to default to reading the first (second?) block 38 * on each cyl; however, if the disk geometry is wrong, this is useless. 39 * But ya could still get the cyl size to print the numbers as cyls instead 40 * of blocks... 41 * 42 * run this as (for example) 43 * findsuper /dev/hda 44 * findsuper /dev/hda 437760 1024 (my disk has cyls of 855*512) 45 * 46 * I suppose the next step is to figgure out a way to determine if 47 * the block found is the first superblock somehow, and if so, build 48 * a partition table from the superblocks found... but this is still 49 * useful as is. 50 * 51 * Steve 52 * ssd@nevets.oau.org 53 * ssd@mae.engr.ucf.edu 54 * 55 */ 56 57/* 58 * Documentation addendum added by Andreas dwguest@win.tue.nl/aeb@cwi.nl 59 * 60 * The program findsuper is a utility that scans a disk and finds 61 * copies of ext2 superblocks (by checking for the ext2 signature; it 62 * will occasionally find other blocks that by coincidence have this 63 * signature - often these can be recognised by their ridiculous 64 * dates). 65 * 66 * For each superblock found, it prints the offset in bytes, the 67 * offset in 1024-byte blocks, the size of ext2 partition in 1024-byte 68 * blocks, the filesystem blocksize (given as log(blocksize)-10, so 69 * that 0 means 1024), the block group number (0 for older ext2 70 * systems), and a timestamp (s_mtime). 71 * 72 * This program can be used to retrieve partitions that have been 73 * lost. The superblock for block group 0 is found 1 block (2 74 * sectors) after the partition start. 75 * 76 * For new systems that have a block group number in the superblock it 77 * is immediately clear which superblock is the first of a partition. 78 * For old systems where no group numbers are given, the first 79 * superblock can be recognised by the timestamp: all superblock 80 * copies have the creation time in s_mtime, except the first, which 81 * has the last time e2fsck or tune2fs wrote to the filesystem. 82 * 83 */ 84 85 86#include <stdio.h> 87#include <stdlib.h> 88#include <time.h> 89 90#include <linux/ext2_fs.h> 91#include "nls-enable.h" 92 93 94main(int argc, char *argv[]) 95{ 96 int i; 97 int skiprate=512; /* one sector */ 98 long sk=0; /* limited to 2G filesystems!! */ 99 FILE *f; 100 char *s; 101 time_t tm; 102 103 struct ext2_super_block ext2; 104 /* interesting fields: EXT2_SUPER_MAGIC 105 * s_blocks_count s_log_block_size s_mtime s_magic s_lastcheck */ 106 107#ifdef ENABLE_NLS 108 setlocale(LC_MESSAGES, ""); 109 bindtextdomain(NLS_CAT_NAME, LOCALEDIR); 110 textdomain(NLS_CAT_NAME); 111#endif 112 if (argc<2) { 113 fprintf(stderr, 114 _("Usage: findsuper device [skiprate [start]]\n")); 115 exit(1); 116 } 117 if (argc>2) 118 skiprate=atoi(argv[2]); 119 if (skiprate<512) { 120 fprintf(stderr, 121 _("Do you really want to skip less than a sector??\n")); 122 exit(2); 123 } 124 if (argc>3) 125 sk=atol(argv[3]); 126 if (sk<0) { 127 fprintf(stderr,_("Have to start at 0 or greater,not %ld\n"),sk); 128 exit(1); 129 } 130 f=fopen(argv[1],"r"); 131 if (!f) { 132 perror(argv[1]); 133 exit(1); 134 } 135 136 /* Now, go looking for the superblock ! */ 137 printf(" thisoff block fs_blk_sz blksz grp last_mount\n"); 138 for (;!feof(f) && (i=fseek(f,sk,SEEK_SET))!= -1; sk+=skiprate){ 139 if (i=fread(&ext2,sizeof(ext2),1, f)!=1) { 140 perror(_("read failed")); 141 } 142 if (ext2.s_magic != EXT2_SUPER_MAGIC) 143 continue; 144 145 tm = ext2.s_mtime; 146 s=ctime(&tm); 147 s[24]=0; 148 printf("%9ld %9ld %9ld %5ld %4d %s\n", sk, 149 sk/1024, ext2.s_blocks_count, 150 ext2.s_log_block_size, 151 ext2.s_block_group_nr, s); 152 } 153 printf(_("Failed on %d at %ld\n"), i, sk); 154 fclose(f); 155} 156