comparison toys/pending/blkid.c @ 1081:7cd565f5adb5 draft

Add blkid.c I finally figured out the NTFS labels after reading a rant on how UTF-8 rocks and how MS switched to UTF16 or UCS1 or whatever. The reason I couldn't grep for the label (mine was "myntfs") was that it is stored as "m\0y\0n\0t\0f\0s\0\0" - found another good use for hexdump :) Notes: I only have x86 to test on, so there are a couple of places that may need bswap_{16,32} for endianness. I used a 65k buf instead of toybuf (4k) for simplicity, but tried to organize it for toybuf if wanted. I have info on more fs types, to patch with after review. blkid does output for all devices if 0 args -> read /proc/partitions?
author Brad Conroy <bconroy@uis.edu>
date Mon, 07 Oct 2013 14:12:35 -0500
parents
children b895518fdc40
comparison
equal deleted inserted replaced
1080:12246ab3fd9c 1081:7cd565f5adb5
1 /* blkid.c - Prints type, label and UUID of filesystem(s).
2 *
3 * Copyright 2013 Brad Conroy <bconroy@uis.edu>
4 *
5 * See ftp://ftp.kernel.org/pub/linux/utils/util-linux/v2.24/libblkid-docs/api-index-full.html
6
7 USE_BLKID(NEWTOY(blkid, NULL, TOYFLAG_BIN))
8
9 config BLKID
10 bool "blkid"
11 default n
12 help
13 usage: blkid [block device...]
14 Prints type, label and UUID of filesystem.
15
16 */
17 #define FOR_blkid
18 #include "toys.h"
19
20 #define BIT(x) (1<<(x))
21 #define _MATCH(buf,type,offset,match) (((unsigned type *)&buf[offset])[0]==(match))
22 #define MATCH2(b,a) (_MATCH(b,a##_TYPE,a##_OFFSET,a##_MAGIC2)||MATCH(b,a))
23 #define MATCH3(b,a) (_MATCH(b,a##_TYPE,a##_OFFSET,a##_MAGIC3)||MATCH2(b,a))
24 #define MATCH(b,a) _MATCH(b,a##_TYPE,a##_OFFSET,a##_MAGIC)
25 /* may need to check endianess for C2I */
26 #define C2I(a,b,c,d) (a|(b<<8)|(c<<16)|(d<<24))
27
28 typedef struct fs_info{
29 unsigned uuid_off;
30 unsigned lab_off;
31 short uuid_t;
32 short lab_len;
33 }fs_info_t;
34
35 //#define SET_FS(t) (fs_info_t){t##_UUID,t##_LABEL,t##_UUID_T,t##_LABEL_SZ}
36 #define SET_FS(t) (fs_info_t)t##_INFO
37
38 #define ADFS_MAGIC 0xadf5
39 #define ADFS_TYPE short
40 #define ADFS_OFFSET 0xc00
41 #define ADFS_INFO {0,0,0,0} /*todo*/
42
43 #define BFS_MAGIC 0x1badface
44 #define BFS_TYPE long
45 #define BFS_OFFSET 0
46 #define BFS_INFO {0,0,0,0}
47
48 /*won't fit in 1 toybuf*/
49 #define BTRFS_MAGIC C2I('_','B','H','R') //'RHB_'
50 //#define BTRFS_MAGIC2 'M_Sf' /*not currently used*/
51 //#define BTRFS_OFFSET2 65604 /*not currently used*/
52 #define BTRFS_TYPE long /*change to long long if full magic used?*/
53 #define BTRFS_OFFSET 65600
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 #if (CFG_BLKID)
124 char *toutf8(unsigned short * ws){ /* hack for NTFS utf16 */
125 static char buf[16];
126 int i=0;
127 while((buf[i++]=*ws++));
128 return buf;
129 }
130 #endif
131
132 /* TODO if no args use proc/partitions */
133 void do_blkid(int fd, char *name){
134 fs_info_t fs;
135 char *fstype;
136 unsigned char buf[66560]; /*toybuf is only 4096, could rework logic*/
137 int sb_read;
138
139 sb_read = read(fd, &buf, sizeof(buf));
140 if (sb_read < 1) return;
141
142 if MATCH(buf,ADFS){
143 fstype="adfs";
144 if (CFG_BLKID) fs=SET_FS(ADFS);
145 }else if MATCH(buf,BFS){
146 fstype="bfs";
147 if (CFG_BLKID) fs=SET_FS(BFS);
148 }else if MATCH(buf,CRAMFS){
149 fstype="cramfs";
150 if (CFG_BLKID) fs=SET_FS(CRAMFS);
151 }else if MATCH3(buf,EXT){
152 fstype=(buf[EXT3_BYTE]&BIT(2))?((buf[EXT4_BYTE]&BIT(6))?"ext4":"ext3"):"ext2";
153 if (CFG_BLKID) fs=SET_FS(EXT);
154 }else if MATCH(buf,F2FS){
155 fstype="f2fs";
156 if (CFG_BLKID) fs=SET_FS(F2FS);
157 }else if MATCH(buf,NILFS){
158 fstype="nilfs";
159 if (CFG_BLKID) fs=SET_FS(NILFS);
160 }else if MATCH(buf,NTFS){
161 fstype="ntfs";
162 if (CFG_BLKID) fs=SET_FS(NTFS);
163 }else if MATCH(buf,XIAFS){
164 fstype="xiafs";
165 if (CFG_BLKID) fs=SET_FS(XIAFS);
166 /*below here would require more than 1 toybuf*/
167 }else if MATCH(buf,REISER){
168 fstype="reiserfs";
169 if (CFG_BLKID) fs=SET_FS(REISER);
170 }else if MATCH(buf,JFS){
171 fstype="jfs";
172 if (CFG_BLKID) fs=SET_FS(JFS);
173 }else if MATCH(buf,BTRFS){
174 fstype="btrfs";
175 if (CFG_BLKID) fs=SET_FS(BTRFS);
176 }else if MATCH(buf,REISERB){
177 fstype="reiserfs";
178 if (CFG_BLKID) fs=SET_FS(REISERB);
179 }else return;
180
181 if (CFG_BLKID && !strncmp("blkid",toys.which->name,5) ){
182 printf("%s:",name);
183 if ( fs.lab_len > 0 )
184 printf(" LABEL=\"%.*s\"", fs.lab_len, (char *)&buf[fs.lab_off]);
185 else if ( fs.lab_len < 0 )
186 printf(" LABEL=\"%.*s\"", -fs.lab_len,
187 toutf8((unsigned short *)&buf[fs.lab_off]));
188 if ( fs.uuid_off > 0 ){
189 if ( fs.uuid_t == 16 )
190 printf(" UUID=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
191 "%02x%02x%02x%02x%02x%02x\"",
192 buf[fs.uuid_off], buf[fs.uuid_off+1],
193 buf[fs.uuid_off+2], buf[fs.uuid_off+3],
194 buf[fs.uuid_off+4], buf[fs.uuid_off+5],
195 buf[fs.uuid_off+6], buf[fs.uuid_off+7],
196 buf[fs.uuid_off+8], buf[fs.uuid_off+9],
197 buf[fs.uuid_off+10], buf[fs.uuid_off+11],
198 buf[fs.uuid_off+12], buf[fs.uuid_off+13],
199 buf[fs.uuid_off+14], buf[fs.uuid_off+15]);
200 if ( fs.uuid_t == 8 )
201 printf(" UUID=\"%02X%02X%02X%02X%02X%02X%02X%02X\"",
202 buf[fs.uuid_off+7], buf[fs.uuid_off+6],
203 buf[fs.uuid_off+5], buf[fs.uuid_off+4],
204 buf[fs.uuid_off+3], buf[fs.uuid_off+2],
205 buf[fs.uuid_off+1], buf[fs.uuid_off]);
206 }
207 printf(" TYPE=\"%s\"",fstype);
208 }else /* fstype */
209 write(1,fstype,strlen(fstype)); /* avoid printf overhead in fstype */
210 putchar('\n');
211 }
212
213 #if (CFG_BLKID)
214 void blkid_main(void)
215 {
216 loopfiles(toys.optargs, do_blkid);
217 }
218 #endif
219
220
221 /* fstype.c - Prints type of filesystem(s).
222 *
223 * Copyright 2013 Brad Conroy <bconroy@uis.edu>
224
225 USE_FSTYPE(NEWTOY(fstype, NULL, TOYFLAG_BIN))
226
227 config FSTYPE
228 bool "fstype"
229 default n
230 help
231 usage: fstype [block device...]
232 Prints type of filesystem.
233 */
234 #define FOR_fstype
235 #include "toys.h"
236 void do_blkid(int fd, char *name);
237 void fstype_main(void)
238 {
239 loopfiles(toys.optargs, do_blkid);
240 }