diff options
Diffstat (limited to 'util-linux/volume_id/squashfs.c')
-rw-r--r-- | util-linux/volume_id/squashfs.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/util-linux/volume_id/squashfs.c b/util-linux/volume_id/squashfs.c new file mode 100644 index 000000000..c5b4f9ced --- /dev/null +++ b/util-linux/volume_id/squashfs.c | |||
@@ -0,0 +1,49 @@ | |||
1 | /* | ||
2 | * volume_id - reads filesystem label and uuid | ||
3 | * | ||
4 | * Copyright (C) 2012 S-G Bergh <sgb@systemasis.org> | ||
5 | * | ||
6 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
7 | */ | ||
8 | |||
9 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_SQUASHFS) += squashfs.o | ||
10 | |||
11 | #include "volume_id_internal.h" | ||
12 | |||
13 | struct squashfs_superblock { | ||
14 | uint32_t magic; | ||
15 | /* | ||
16 | uint32_t dummy[6]; | ||
17 | uint16_t major; | ||
18 | uint16_t minor; | ||
19 | */ | ||
20 | } PACKED; | ||
21 | |||
22 | int FAST_FUNC volume_id_probe_squashfs(struct volume_id *id /*,uint64_t off*/) | ||
23 | { | ||
24 | #define off ((uint64_t)0) | ||
25 | struct squashfs_superblock *sb; | ||
26 | |||
27 | dbg("SquashFS: probing at offset 0x%llx", (unsigned long long) off); | ||
28 | sb = volume_id_get_buffer(id, off, 0x200); | ||
29 | if (!sb) | ||
30 | return -1; | ||
31 | |||
32 | // Old SquashFS (pre 4.0) can be both big and little endian, so test for both. | ||
33 | // Likewise, it is commonly used in firwmare with some non-standard signatures. | ||
34 | #define pack(a,b,c,d) ( (uint32_t)((a * 256 + b) * 256 + c) * 256 + d ) | ||
35 | #define SIG1 pack('s','q','s','h') | ||
36 | #define SIG2 pack('h','s','q','s') | ||
37 | #define SIG3 pack('s','h','s','q') | ||
38 | #define SIG4 pack('q','s','h','s') | ||
39 | if (sb->magic == SIG1 | ||
40 | || sb->magic == SIG2 | ||
41 | || sb->magic == SIG3 | ||
42 | || sb->magic == SIG4 | ||
43 | ) { | ||
44 | IF_FEATURE_BLKID_TYPE(id->type = "squashfs";) | ||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | return -1; | ||
49 | } | ||