2 * Copyright 1996, 1998, 2002-2003 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
7 /* All Rights Reserved */
10 * Copyright (c) 1983 Regents of the University of California.
11 * All rights reserved. The Berkeley software License Agreement
12 * specifies the terms and conditions for redistribution.
15 #pragma ident "%Z%%M% %I% %E% SMI"
18 #include <sys/types.h>
20 #include <sys/vnode.h>
23 #include <sys/fs/ufs_inode.h>
24 #include <sys/fs/ufs_fsdir.h>
25 #include <sys/fs/ufs_acl.h>
26 #include <byteorder.h>
28 struct byteorder_ctx
*
29 byteorder_create(void)
31 struct byteorder_ctx
*rc
;
33 /* LINTED: assignment value is used */
34 if ((rc
= (struct byteorder_ctx
*)calloc(1, sizeof (*rc
))) == NULL
)
40 byteorder_destroy(struct byteorder_ctx
*ctx
)
43 (void) free((char *)ctx
);
47 byteorder_banner(struct byteorder_ctx
*ctx
, FILE *filep
)
49 if ((! ctx
->initialized
) || (filep
== NULL
))
53 (void) fprintf(filep
, gettext("Note: doing byte swapping\n"));
57 * Control string (cp) is a sequence of optional numeric repeat counts
58 * and format specifiers. s/w/h indicate a 16-bit quantity is to be
59 * byte-swapped, l indicates a 32-bit quantity. A repeat count is
60 * identical in effect to having the following format character appear
61 * N times (e.g., "3h" is equivalent to "hhh").
63 * The byte-swapping is performed in-place, in the buffer sp.
66 swabst(char *cp
, uchar_t
*sp
)
73 case '0': case '1': case '2': case '3': case '4':
74 case '5': case '6': case '7': case '8': case '9':
75 n
= (n
* 10) + (*cp
++ - '0');
78 case 's': case 'w': case 'h':
79 /* LINTED: type punning ok here */
80 c
= sp
[0]; sp
[0] = sp
[1]; sp
[1] = c
;
85 c
= sp
[0]; sp
[0] = sp
[3]; sp
[3] = c
;
86 c
= sp
[2]; sp
[2] = sp
[1]; sp
[1] = c
;
89 /* Any other character, like 'b' counts as byte. */
103 swabst("l", (uchar_t
*)&l
);
104 /* LINTED: type punning ok here */
109 checksum(struct byteorder_ctx
*ctx
, int *b
, int size
)
113 if (! ctx
->initialized
)
117 * We should only be called on to checksum u_spcl's, so make
118 * sure that's what we got.
120 if ((unsigned)size
< tp_bsize
)
123 j
= tp_bsize
/ sizeof (int);
131 * What happens if we want to read restore tapes
132 * for a 16bit int machine???
139 return (i
!= CHECKSUM
);
143 * normspcl() checks that a spclrec is valid. it does byte/quad
144 * swapping if necessary, and checks the checksum. it does NOT convert
145 * from the old filesystem format; gethead() in tape.c does that.
147 * ctx is the context for this package
148 * sp is a pointer to a current-format spclrec, that may need to be
150 * cs is a pointer to the thing we want to checksum. if we're
151 * converting from the old filesystem format, it might be different
153 * css is the size of the thing we want to checksum.
154 * magic is the magic number we compare against.
158 normspcl(struct byteorder_ctx
*ctx
, struct s_spcl
*sp
, int *cs
,
163 if ((! ctx
->initialized
) && (sp
->c_magic
!= magic
)) {
164 if (swabl(sp
->c_magic
) != (uint32_t)magic
)
168 ctx
->initialized
= 1;
170 if (checksum(ctx
, cs
, css
))
174 * Unless our caller is actively trying to break us, a
175 * successful checksum() means that *sp is at least as
176 * big as what we think it should be as far as byte
177 * swapping goes. Therefore, we don't need to do any
178 * more size checks here.
181 /* handle byte swapping */
185 * c_type, c_date, c_ddate, c_volume, c_tapea, c_inumber,
186 * c_magic, c_checksum,
187 * all of c_dinode, and c_count.
190 swabst("8l4s31l", (uchar_t
*)sp
);
194 * c_flags, c_firstrec, and c_spare.
197 swabst("34l", (uchar_t
*)&(sp
->c_flags
));
199 /* byteswap the inodes if necessary. */
201 #ifndef lint /* lint won't shut up about sprintf below */
202 if (sp
->c_flags
& DR_INODEINFO
) {
204 /* Can't overflow, max len is %d format (20)+`l'+\0 */
205 /* LINTED lint can't tell diff between %ld and %dl */
206 (void) sprintf(buffy
, "%dl", TP_NINOS
);
207 swabst(buffy
, (uchar_t
*)sp
->c_data
.s_inos
);
211 /* if no metadata, byteswap the level */
213 if (! (sp
->c_flags
& DR_HASMETA
))
214 swabst("1l", (uchar_t
*)&(sp
->c_level
));
217 /* handle quad swapping (note -- we no longer perform this check */
218 /* we now do quad swapping iff we're doing byte swapping.) */
221 * the following code is being changed during the large file
222 * project. This code needed to be changed because ic_size
223 * is no longer a quad, it has been changed to ic_lsize, which is
224 * an offset_t, and the field "val" doesn't exist anymore.
228 * This is the old code. (before large file project.)
230 * sv = sp->c_dinode.di_ic.ic_size.val;
241 /* swap the upper 32 bits of ic_lsize with the lower 32 bits */
244 sv
= sp
->c_dinode
.di_ic
.ic_lsize
;
245 sv
= (sv
<< 32) | (sv
>> 32);
246 sp
->c_dinode
.di_ic
.ic_lsize
= sv
;
249 if (sp
->c_magic
!= magic
)
256 struct byteorder_ctx
*ctx
;
259 assert(ctx
->initialized
);
262 swabst("l2s", (uchar_t
*)d
);
266 normacls(struct byteorder_ctx
*ctx
, ufs_acl_t
*acl
, int n
)
268 static int complained
= 0;
272 assert(ctx
->initialized
);
277 for (i
= 0; i
< n
; i
++) {
278 swabst("1s", (uchar_t
*)&(acl
[i
].acl_tag
)); /* u_short */
279 swabst("1s", (uchar_t
*)&(acl
[i
].acl_perm
)); /* o_mode_t */
281 /* LINTED explicitly checking for truncation below */
282 uid
= (uid32_t
)(acl
[i
].acl_who
);
283 if (!complained
&& ((uid_t
)uid
) != acl
[i
].acl_who
) {
285 * The problem is that acl_who is a uid_t,
286 * and we know that the on-tape version is
287 * definitely 32 bits. To avoid getting
288 * burned if/when uid_t becomes bigger
289 * than that, we need to do the explicit
290 * conversion and check.
292 (void) fprintf(stderr
,
293 "Some ACL uids have been truncated\n");
296 swabst("1l", (uchar_t
*)&(uid
)); /* uid32_t */