]>
Commit | Line | Data |
---|---|---|
fbaec83b SRP |
1 | /* |
2 | * cramfs_common - cramfs common code | |
3 | * | |
4 | * Copyright (c) 2008 Roy Peled, the.roy.peled -at- gmail.com | |
cd42d02f | 5 | * Copyright (c) 2004-2006 by Juliane Holzt, kju -at- fqdn.org |
fbaec83b SRP |
6 | * |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | */ | |
18 | ||
19 | #include <string.h> | |
06f25585 | 20 | #include "cramfs.h" |
fbaec83b SRP |
21 | #include "../include/bitops.h" |
22 | ||
d51f37a3 | 23 | uint32_t u32_toggle_endianness(int big_endian, uint32_t what) |
fbaec83b SRP |
24 | { |
25 | return big_endian == HOST_IS_BIG_ENDIAN ? what : swab32(what); | |
26 | } | |
27 | ||
28 | void super_toggle_endianness(int big_endian, struct cramfs_super *super) | |
29 | { | |
30 | if (big_endian != HOST_IS_BIG_ENDIAN) { | |
31 | super->magic = swab32(super->magic); | |
32 | super->size = swab32(super->size); | |
33 | super->flags = swab32(super->flags); | |
34 | super->future = swab32(super->future); | |
35 | super->fsid.crc = swab32(super->fsid.crc); | |
36 | super->fsid.edition = swab32(super->fsid.edition); | |
37 | super->fsid.blocks = swab32(super->fsid.blocks); | |
fc2798c5 | 38 | super->fsid.files = swab32(super->fsid.files); |
fbaec83b SRP |
39 | } |
40 | } | |
41 | ||
cc924cc0 | 42 | static void inode_toggle_endianness(int input_big_endian, int output_big_endian, |
fc2798c5 SK |
43 | struct cramfs_inode *inode_in, |
44 | struct cramfs_inode *inode_out) | |
fbaec83b SRP |
45 | { |
46 | if (input_big_endian == output_big_endian) { | |
47 | memmove(inode_out, inode_in, sizeof(*inode_out)); | |
fc2798c5 | 48 | } else { |
fbaec83b SRP |
49 | unsigned char inode_out_buf[sizeof(*inode_in)]; |
50 | unsigned char *inode_in_buf = (unsigned char*)inode_in; | |
51 | ||
52 | inode_out_buf[0] = inode_in_buf[1]; /* 16 bit: mode */ | |
53 | inode_out_buf[1] = inode_in_buf[0]; | |
54 | ||
55 | inode_out_buf[2] = inode_in_buf[3]; /* 16 bit: uid */ | |
fc2798c5 | 56 | inode_out_buf[3] = inode_in_buf[2]; |
fbaec83b SRP |
57 | |
58 | inode_out_buf[4] = inode_in_buf[6]; /* 24 bit: size */ | |
59 | inode_out_buf[5] = inode_in_buf[5]; | |
60 | inode_out_buf[6] = inode_in_buf[4]; | |
61 | ||
62 | inode_out_buf[7] = inode_in_buf[7]; /* 8 bit: gid width */ | |
63 | ||
fc2798c5 SK |
64 | /* |
65 | * Stop the madness! Outlaw C bitfields! They are unportable | |
66 | * and nasty! See for yourself what a mess this is: | |
67 | */ | |
fbaec83b | 68 | if (output_big_endian) { |
fc2798c5 | 69 | inode_out_buf[ 8] = ( (inode_in_buf[ 8]&0x3F) << 2 ) | |
fbaec83b SRP |
70 | ( (inode_in_buf[11]&0xC0) >> 6 ); |
71 | ||
72 | inode_out_buf[ 9] = ( (inode_in_buf[11]&0x3F) << 2 ) | | |
73 | ( (inode_in_buf[10]&0xC0) >> 6 ); | |
74 | ||
75 | inode_out_buf[10] = ( (inode_in_buf[10]&0x3F) << 2 ) | | |
76 | ( (inode_in_buf[ 9]&0xC0) >> 6 ); | |
77 | ||
78 | inode_out_buf[11] = ( (inode_in_buf[ 9]&0x3F) << 2 ) | | |
79 | ( (inode_in_buf[ 8]&0xC0) >> 6 ); | |
fc2798c5 SK |
80 | } else { |
81 | inode_out_buf[ 8] = ( (inode_in_buf[ 8]&0xFD) >> 2 ) | | |
fbaec83b SRP |
82 | ( (inode_in_buf[11]&0x03) << 6 ); |
83 | ||
fc2798c5 | 84 | inode_out_buf[ 9] = ( (inode_in_buf[11]&0xFD) >> 2 ) | |
fbaec83b SRP |
85 | ( (inode_in_buf[10]&0x03) << 6 ); |
86 | ||
fc2798c5 | 87 | inode_out_buf[10] = ( (inode_in_buf[10]&0xFD) >> 2 ) | |
fbaec83b SRP |
88 | ( (inode_in_buf[ 9]&0x03) << 6 ); |
89 | ||
fc2798c5 | 90 | inode_out_buf[11] = ( (inode_in_buf[ 9]&0xFD) >> 2 ) | |
fbaec83b SRP |
91 | ( (inode_in_buf[ 8]&0x03) << 6 ); |
92 | } | |
fbaec83b SRP |
93 | memmove(inode_out, inode_out_buf, sizeof(*inode_out)); |
94 | } | |
95 | } | |
96 | ||
fc2798c5 SK |
97 | void inode_to_host(int from_big_endian, struct cramfs_inode *inode_in, |
98 | struct cramfs_inode *inode_out) | |
fbaec83b | 99 | { |
fc2798c5 SK |
100 | inode_toggle_endianness(from_big_endian, HOST_IS_BIG_ENDIAN, inode_in, |
101 | inode_out); | |
fbaec83b SRP |
102 | } |
103 | ||
fc2798c5 SK |
104 | void inode_from_host(int to_big_endian, struct cramfs_inode *inode_in, |
105 | struct cramfs_inode *inode_out) | |
fbaec83b | 106 | { |
fc2798c5 SK |
107 | inode_toggle_endianness(HOST_IS_BIG_ENDIAN, to_big_endian, inode_in, |
108 | inode_out); | |
fbaec83b | 109 | } |