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