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);