]>
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 | |
5 | * Copyright (c) 2004-2006 by Michael Holzt, kju -at- fqdn.org | |
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> | |
20 | #include "cramfs_common.h" | |
21 | #include "../include/bitops.h" | |
22 | ||
23 | u32 u32_toggle_endianness(int big_endian, u32 what) | |
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); | |
38 | super->fsid.files = swab32(super->fsid.files); | |
39 | } | |
40 | } | |
41 | ||
42 | void inode_toggle_endianness(int input_big_endian, int output_big_endian, struct cramfs_inode *inode_in, struct cramfs_inode *inode_out) | |
43 | { | |
44 | if (input_big_endian == output_big_endian) { | |
45 | memmove(inode_out, inode_in, sizeof(*inode_out)); | |
46 | } | |
47 | else { | |
48 | unsigned char inode_out_buf[sizeof(*inode_in)]; | |
49 | unsigned char *inode_in_buf = (unsigned char*)inode_in; | |
50 | ||
51 | inode_out_buf[0] = inode_in_buf[1]; /* 16 bit: mode */ | |
52 | inode_out_buf[1] = inode_in_buf[0]; | |
53 | ||
54 | inode_out_buf[2] = inode_in_buf[3]; /* 16 bit: uid */ | |
55 | inode_out_buf[3] = inode_in_buf[2]; | |
56 | ||
57 | inode_out_buf[4] = inode_in_buf[6]; /* 24 bit: size */ | |
58 | inode_out_buf[5] = inode_in_buf[5]; | |
59 | inode_out_buf[6] = inode_in_buf[4]; | |
60 | ||
61 | inode_out_buf[7] = inode_in_buf[7]; /* 8 bit: gid width */ | |
62 | ||
63 | /* Stop the madness! Outlaw C bitfields! They are unportable and nasty! | |
64 | See for yourself what a mess this is: */ | |
65 | ||
66 | if (output_big_endian) { | |
67 | inode_out_buf[ 8] = ( (inode_in_buf[ 8]&0x3F) << 2 ) | | |
68 | ( (inode_in_buf[11]&0xC0) >> 6 ); | |
69 | ||
70 | inode_out_buf[ 9] = ( (inode_in_buf[11]&0x3F) << 2 ) | | |
71 | ( (inode_in_buf[10]&0xC0) >> 6 ); | |
72 | ||
73 | inode_out_buf[10] = ( (inode_in_buf[10]&0x3F) << 2 ) | | |
74 | ( (inode_in_buf[ 9]&0xC0) >> 6 ); | |
75 | ||
76 | inode_out_buf[11] = ( (inode_in_buf[ 9]&0x3F) << 2 ) | | |
77 | ( (inode_in_buf[ 8]&0xC0) >> 6 ); | |
78 | } | |
79 | else { | |
80 | inode_out_buf[ 8] = ( (inode_in_buf[ 8]&0xFD) >> 2 ) | | |
81 | ( (inode_in_buf[11]&0x03) << 6 ); | |
82 | ||
83 | inode_out_buf[ 9] = ( (inode_in_buf[11]&0xFD) >> 2 ) | | |
84 | ( (inode_in_buf[10]&0x03) << 6 ); | |
85 | ||
86 | inode_out_buf[10] = ( (inode_in_buf[10]&0xFD) >> 2 ) | | |
87 | ( (inode_in_buf[ 9]&0x03) << 6 ); | |
88 | ||
89 | inode_out_buf[11] = ( (inode_in_buf[ 9]&0xFD) >> 2 ) | | |
90 | ( (inode_in_buf[ 8]&0x03) << 6 ); | |
91 | } | |
92 | ||
93 | memmove(inode_out, inode_out_buf, sizeof(*inode_out)); | |
94 | } | |
95 | } | |
96 | ||
97 | void inode_to_host(int from_big_endian, struct cramfs_inode *inode_in, struct cramfs_inode *inode_out) | |
98 | { | |
99 | inode_toggle_endianness(from_big_endian, HOST_IS_BIG_ENDIAN, inode_in, inode_out); | |
100 | } | |
101 | ||
102 | void inode_from_host(int to_big_endian, struct cramfs_inode *inode_in, struct cramfs_inode *inode_out) | |
103 | { | |
104 | inode_toggle_endianness(HOST_IS_BIG_ENDIAN, to_big_endian, inode_in, inode_out); | |
105 | } |