Mercurial > hg > toybox
comparison toys/pending/blkid.c @ 1084:4f30bf230196 draft
Cleanup blkid
author | Rob Landley <rob@landley.net> |
---|---|
date | Tue, 08 Oct 2013 12:25:02 -0500 |
parents | 8f0a577dcdd3 |
children |
comparison
equal
deleted
inserted
replaced
1083:8f0a577dcdd3 | 1084:4f30bf230196 |
---|---|
16 */ | 16 */ |
17 | 17 |
18 #define FOR_blkid | 18 #define FOR_blkid |
19 #include "toys.h" | 19 #include "toys.h" |
20 | 20 |
21 #define BIT(x) (1<<(x)) | 21 struct fstype { |
22 #define _MATCH(buf,type,offset,match) (((unsigned type *)&buf[offset])[0]==(match)) | 22 char *name; |
23 #define MATCH2(b,a) (_MATCH(b,a##_TYPE,a##_OFFSET,a##_MAGIC2)||MATCH(b,a)) | 23 uint64_t magic; |
24 #define MATCH3(b,a) (_MATCH(b,a##_TYPE,a##_OFFSET,a##_MAGIC3)||MATCH2(b,a)) | 24 int magic_len, magic_offset, uuid_off, label_len, label_off; |
25 #define MATCH(b,a) _MATCH(b,a##_TYPE,a##_OFFSET,a##_MAGIC) | |
26 /* may need to check endianess for C2I */ | |
27 #define C2I(a,b,c,d) (a|(b<<8)|(c<<16)|(d<<24)) | |
28 | |
29 struct fs_info { | |
30 unsigned uuid_off; | |
31 unsigned lab_off; | |
32 short uuid_t; | |
33 short lab_len; | |
34 }; | 25 }; |
35 | 26 |
36 #define SET_FS(t) (struct fs_info)t##_INFO | 27 static const struct fstype fstypes[] = { |
28 // ext3 = buf[1116]&4 ext4 = buf[1120]&64 | |
29 {"ext2", 0xEF53, 2, 1080, 1128, 16, 1144}, | |
30 // label actually 8/16 0x4d80 but horrible: 16 bit wide characters via | |
31 // codepage, something called a uuid that's only 8 bytes long... | |
32 {"ntfs", 0x5346544e, 4, 3, 0x48+(8<<24), 0, 0}, | |
37 | 33 |
38 #define ADFS_MAGIC 0xadf5 | 34 {"adfs", 0xadf5, 2, 0xc00, 0,0,0}, |
39 #define ADFS_TYPE short | 35 {"bfs", 0x1badface, 4, 0, 0,0,0}, |
40 #define ADFS_OFFSET 0xc00 | 36 {"btrfs", 0x4D5F53665248425FULL, 8, 65600, 65803, 256, 65819}, |
41 #define ADFS_INFO {0,0,0,0} /*todo*/ | 37 {"cramfs", 0x28cd3d45, 4, 0, 0, 16, 48}, |
42 | 38 {"f2fs", 0xF2F52010, 4, 1024, 1132, 16, 1110}, |
43 #define BFS_MAGIC 0x1badface | 39 {"jfs", 0x3153464a, 4, 32768, 32920, 16, 32904}, |
44 #define BFS_TYPE long | 40 {"nilfs", 0x3434, 2, 1030, 1176, 80, 1192}, |
45 #define BFS_OFFSET 0 | 41 {"murderfs", 0x724573496552, 6, 8244, 8276, 16, 8292}, |
46 #define BFS_INFO {0,0,0,0} | 42 {"murderfs", 0x724573496552, 6, 65588, 65620, 16, 65536}, |
47 | 43 {"romfs", 0x2d6d6f72, 4, 0, 0,0,0}, |
48 /*won't fit in 1 toybuf*/ | 44 {"squashfs", 0x73717368, 4, 0, 0,0,0}, |
49 #define BTRFS_MAGIC C2I('_','B','H','R') //'RHB_' | 45 {"xiafs", 0x012fd16d, 4, 572, 0,0,0}, |
50 //#define BTRFS_MAGIC2 'M_Sf' /*not currently used*/ | 46 {"xfs", 0x42534658, 4, 0, 32, 12, 108}, |
51 //#define BTRFS_OFFSET2 65604 /*not currently used*/ | 47 {"vfat", 0x3233544146, 5, 82, 67+(4<<24), 11, 71}, // fat32 |
52 #define BTRFS_TYPE long /*change to long long if full magic used?*/ | 48 {"vfat", 0x31544146, 4, 54, 39+(4<<24), 11, 43} // fat1 |
53 #define BTRFS_OFFSET 65600 | 49 }; |
54 #define BTRFS_INFO {65803,65819,16,256} | |
55 | |
56 #define CRAMFS_MAGIC 0x28cd3d45 | |
57 #define CRAMFS_MAGIC2 0x453dcd28 | |
58 #define CRAMFS_TYPE long | |
59 #define CRAMFS_OFFSET 0 | |
60 #define CRAMFS_INFO {0,48,0,16} | |
61 | |
62 #define EXT_MAGIC 0xEF53 | |
63 #define EXT_MAGIC2 0xEF51 | |
64 #define EXT_MAGIC3 0x53EF | |
65 #define EXT_TYPE short | |
66 #define EXT_OFFSET 1080 | |
67 #define EXT3_BYTE 1116 | |
68 #define EXT4_BYTE 1120 | |
69 #define EXT_INFO {1128,1144,16,16} | |
70 | |
71 #define F2FS_MAGIC 0xF2F52010 | |
72 #define F2FS_TYPE long | |
73 #define F2FS_OFFSET 1024 | |
74 #define F2FS_INFO {1132,1110,16,16} | |
75 | |
76 /*won't fit in 1 toybuf*/ | |
77 #define JFS_MAGIC C2I('J','S','F','1') //'1SFJ' | |
78 #define JFS_TYPE long | |
79 #define JFS_OFFSET 32768 | |
80 #define JFS_INFO {32920,32904,16,16} | |
81 | |
82 #define NILFS_MAGIC 0x3434 | |
83 #define NILFS_TYPE short | |
84 #define NILFS_OFFSET 1030 | |
85 #define NILFS_INFO {1176,1192,16,80} | |
86 | |
87 #define NTFS_MAGIC C2I('N','T','F','S') //'SFTN' | |
88 #define NTFS_TYPE long | |
89 #define NTFS_OFFSET 3 | |
90 #define NTFS_INFO {0x48,0X4D80,8,-8} | |
91 | |
92 /*won't fit in 1 toybuf*/ | |
93 #define REISER_MAGIC C2I('R','e','I','s') //'sIeR' | |
94 #define REISER_TYPE long | |
95 #define REISER_OFFSET 8244 | |
96 #define REISER_INFO {8276,8292,16,16} | |
97 | |
98 #define REISERB_MAGIC REISER_MAGIC //'sIeR' | |
99 #define REISERB_TYPE REISER_TYPE | |
100 #define REISERB_OFFSET 65588 | |
101 #define REISERB_INFO {65620,65636,16,16} | |
102 | |
103 #define ROMFS_MAGIC C2I('r','o','m','-') //'-mor' | |
104 #define ROMFS_OFFSET 0 | |
105 #define ROMFS_TYPE long | |
106 #define ROMFS_INFO {0,0,0,0} | |
107 | |
108 #define SQUASHFS_OFFSET 0 | |
109 #define SQUASHFS_TYPE long | |
110 #define SQUASHFS_MAGIC 0x73717368 | |
111 #define SQUASHFS_INFO {0,0,0,0} | |
112 | |
113 #define XIAFS_OFFSET 572 | |
114 #define XIAFS_TYPE long | |
115 #define XIAFS_MAGIC 0x012FD16D | |
116 #define XIAFS_INFO {0,0,0,0} | |
117 | |
118 #define XFS_OFFSET 0 | |
119 #define XFS_TYPE long | |
120 #define XFS_MAGIC C2I('X','F','S','B') | |
121 #define XFS_INFO {32,108,16,12} | |
122 | |
123 /* hack for NTFS utf16 */ | |
124 char *toutf8(unsigned short *ws) | |
125 { | |
126 static char buf[16]; | |
127 int i=0; | |
128 | |
129 while((buf[i++]=*ws++)); | |
130 return buf; | |
131 } | |
132 | 50 |
133 /* TODO if no args use proc/partitions */ | 51 /* TODO if no args use proc/partitions */ |
134 void do_blkid(int fd, char *name) | 52 void do_blkid(int fd, char *name) |
135 { | 53 { |
136 struct fs_info fs; | 54 int off, i, j; |
137 char *fstype; | 55 char *type; |
138 unsigned char buf[66560]; /*toybuf is only 4096, could rework logic*/ | |
139 int sb_read; | |
140 | 56 |
141 sb_read = read(fd, &buf, sizeof(buf)); | 57 off = i = 0; |
142 if (sb_read < 1) return; | |
143 | 58 |
144 if MATCH(buf,ADFS) { | 59 for (;;) { |
145 fstype="adfs"; | 60 int pass = 0, len; |
146 if (CFG_BLKID) fs=SET_FS(ADFS); | |
147 } else if MATCH(buf,BFS) { | |
148 fstype="bfs"; | |
149 if (CFG_BLKID) fs=SET_FS(BFS); | |
150 } else if MATCH(buf,CRAMFS) { | |
151 fstype="cramfs"; | |
152 if (CFG_BLKID) fs=SET_FS(CRAMFS); | |
153 } else if MATCH3(buf,EXT) { | |
154 fstype=(buf[EXT3_BYTE]&BIT(2))?((buf[EXT4_BYTE]&BIT(6))?"ext4":"ext3"):"ext2"; | |
155 if (CFG_BLKID) fs=SET_FS(EXT); | |
156 } else if MATCH(buf,F2FS) { | |
157 fstype="f2fs"; | |
158 if (CFG_BLKID) fs=SET_FS(F2FS); | |
159 } else if MATCH(buf,NILFS) { | |
160 fstype="nilfs"; | |
161 if (CFG_BLKID) fs=SET_FS(NILFS); | |
162 } else if MATCH(buf,NTFS) { | |
163 fstype="ntfs"; | |
164 if (CFG_BLKID) fs=SET_FS(NTFS); | |
165 } else if MATCH(buf,XIAFS) { | |
166 fstype="xiafs"; | |
167 if (CFG_BLKID) fs=SET_FS(XIAFS); | |
168 /*below here would require more than 1 toybuf*/ | |
169 } else if MATCH(buf,REISER) { | |
170 fstype="reiserfs"; | |
171 if (CFG_BLKID) fs=SET_FS(REISER); | |
172 } else if MATCH(buf,JFS) { | |
173 fstype="jfs"; | |
174 if (CFG_BLKID) fs=SET_FS(JFS); | |
175 } else if MATCH(buf,BTRFS) { | |
176 fstype="btrfs"; | |
177 if (CFG_BLKID) fs=SET_FS(BTRFS); | |
178 } else if MATCH(buf,REISERB) { | |
179 fstype="reiserfs"; | |
180 if (CFG_BLKID) fs=SET_FS(REISERB); | |
181 } else return; | |
182 | 61 |
183 if (CFG_BLKID && !strncmp("blkid",toys.which->name,5) ) { | 62 // Read next block of data |
184 printf("%s:",name); | 63 len = readall(fd, toybuf, sizeof(toybuf)); |
185 if (fs.lab_len > 0) | 64 if (len != sizeof(toybuf)) return; |
186 printf(" LABEL=\"%.*s\"", fs.lab_len, (char *)&buf[fs.lab_off]); | 65 |
187 else if (fs.lab_len < 0) | 66 // Iterate through types in range |
188 printf(" LABEL=\"%.*s\"", -fs.lab_len, | 67 for (i=0; i < sizeof(fstypes)/sizeof(struct fstype); i++) { |
189 toutf8((unsigned short *)&buf[fs.lab_off])); | 68 uint64_t test; |
190 if (fs.uuid_off > 0) { | 69 |
191 if (fs.uuid_t == 16) | 70 // Skip tests not in this 4k block |
192 printf(" UUID=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" | 71 if (fstypes[i].magic_offset > off+sizeof(toybuf)) { |
193 "%02x%02x%02x%02x%02x%02x\"", | 72 pass++; |
194 buf[fs.uuid_off], buf[fs.uuid_off+1], | 73 continue; |
195 buf[fs.uuid_off+2], buf[fs.uuid_off+3], | 74 } |
196 buf[fs.uuid_off+4], buf[fs.uuid_off+5], | 75 if (fstypes[i].magic_offset < off) continue; |
197 buf[fs.uuid_off+6], buf[fs.uuid_off+7], | 76 |
198 buf[fs.uuid_off+8], buf[fs.uuid_off+9], | 77 // Populate 64 bit little endian magic value |
199 buf[fs.uuid_off+10], buf[fs.uuid_off+11], | 78 test = 0; |
200 buf[fs.uuid_off+12], buf[fs.uuid_off+13], | 79 for (j = 0; j < fstypes[i].magic_len; j++) |
201 buf[fs.uuid_off+14], buf[fs.uuid_off+15]); | 80 test += ((uint64_t)toybuf[j+fstypes[i].magic_offset-off])<<(8*j); |
202 if (fs.uuid_t == 8) | 81 if (test == fstypes[i].magic) break; |
203 printf(" UUID=\"%02X%02X%02X%02X%02X%02X%02X%02X\"", | |
204 buf[fs.uuid_off+7], buf[fs.uuid_off+6], | |
205 buf[fs.uuid_off+5], buf[fs.uuid_off+4], | |
206 buf[fs.uuid_off+3], buf[fs.uuid_off+2], | |
207 buf[fs.uuid_off+1], buf[fs.uuid_off]); | |
208 } | 82 } |
209 printf(" TYPE=\"%s\"",fstype); | |
210 | 83 |
211 /* avoid printf overhead in fstype */ | 84 if (i == sizeof(fstypes)/sizeof(struct fstype)) { |
212 } else write(1,fstype,strlen(fstype)); | 85 off += len; |
213 putchar('\n'); | 86 if (pass) continue; |
87 return; | |
88 } | |
89 break; | |
90 } | |
91 | |
92 // distinguish ext2/3/4 | |
93 type = fstypes[i].name; | |
94 if (!i) { | |
95 if (toybuf[1116]&4) type = "ext3"; | |
96 if (toybuf[1120]&64) type = "ext4"; | |
97 } | |
98 | |
99 // Could special case NTFS here... | |
100 | |
101 // Output for fstype | |
102 if (*toys.which->name == 'f') { | |
103 puts(type); | |
104 return; | |
105 } | |
106 | |
107 // output for blkid | |
108 printf("%s:",name); | |
109 | |
110 if (fstypes[i].label_len) | |
111 printf(" LABEL=\"%.*s\"", fstypes[i].label_len, | |
112 toybuf+fstypes[i].label_off-off); | |
113 | |
114 if (fstypes[i].uuid_off) { | |
115 int bits = 0x550, size = fstypes[i].uuid_off >> 24, | |
116 uoff = (fstypes[i].uuid_off & ((1<<24)-1))-off; | |
117 | |
118 if (size) bits = 4*(size == 4); | |
119 else size = 16; | |
120 | |
121 printf(" UUID=\""); | |
122 for (j = 0; j < size; j++) printf("-%02x"+!(bits & (1<<j)), toybuf[uoff+j]); | |
123 printf("\""); | |
124 } | |
125 | |
126 printf(" TYPE=\"%s\"\n", fstypes[i].name); | |
214 } | 127 } |
215 | 128 |
216 void blkid_main(void) | 129 void blkid_main(void) |
217 { | 130 { |
218 loopfiles(toys.optargs, do_blkid); | 131 loopfiles(toys.optargs, do_blkid); |