4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1994, by Sun Microsytems, Inc.
26 #pragma ident "%Z%%M% %I% %E% SMI"
31 * Initiate a reader session
35 tnf_reader_begin(caddr_t base
, size_t size
, TNF
**tnfret
)
40 tnf_ref32_t
*fhdr
, *bhdr
;
49 /* LINTED pointer cast may result in improper alignment */
50 if ((magic
= *(tnf_uint32_t
*)base
) == TNF_MAGIC
)
51 native
= 1; /* same endian */
52 else if (magic
== TNF_MAGIC_1
)
53 native
= 0; /* other endian */
55 return (TNF_ERR_NOTTNF
);
58 * Allocate TNF struct, initialize members
61 if ((tnf
= (TNF
*)calloc(1, sizeof (*tnf
))) == (TNF
*)NULL
)
62 return (TNF_ERR_ALLOCFAIL
);
64 tnf
->file_magic
= magic
;
65 tnf
->file_native
= native
;
66 tnf
->file_start
= base
;
67 tnf
->file_size
= size
;
68 tnf
->file_end
= base
+ size
;
74 /* LINTED pointer cast may result in improper alignment */
75 fhdr
= (tnf_ref32_t
*)(base
+ sizeof (magic
)); /* second word */
76 tnf
->file_header
= fhdr
;
79 p
= _tnf_get_slot_named(tnf
, fhdr
, TNF_N_BLOCK_SIZE
);
80 /* LINTED pointer cast may result in improper alignment */
81 tnf
->block_size
= _GET_UINT32(tnf
, (tnf_uint32_t
*)p
);
84 p
= _tnf_get_slot_named(tnf
, fhdr
, TNF_N_DIRECTORY_SIZE
);
85 /* LINTED pointer cast may result in improper alignment */
86 tnf
->directory_size
= _GET_UINT32(tnf
, (tnf_uint32_t
*)p
);
89 p
= _tnf_get_slot_named(tnf
, fhdr
, TNF_N_BLOCK_COUNT
);
90 /* LINTED pointer cast may result in improper alignment */
91 tnf
->block_count
= _GET_UINT32(tnf
, (tnf_uint32_t
*)p
);
93 * This member tracks data block count, not total block count
94 * (unlike the TNF file header). Discount directory blocks.
96 tnf
->block_count
-= tnf
->directory_size
/ tnf
->block_size
;
99 * 1196886: Clients may supply file_size information obtained
100 * by fstat() which is incorrect. Check it now and revise
101 * downwards if we have to.
103 tmpsz
= tnf
->directory_size
+ tnf
->block_count
* tnf
->block_size
;
107 return (TNF_ERR_BADTNF
);
109 tnf
->file_size
= tmpsz
;
110 tnf
->file_end
= base
+ tmpsz
;
114 /* Calculate block shift */
116 while (tmpsz
!= tnf
->block_size
) {
121 /* Calculate block mask */
122 tnf
->block_mask
= ~(tnf
->block_size
- 1);
124 /* Generation shift */
125 p
= _tnf_get_slot_named(tnf
, fhdr
, TNF_N_FILE_LOGICAL_SIZE
);
126 /* LINTED pointer cast may result in improper alignment */
127 tnf
->generation_shift
= _GET_UINT32(tnf
, (tnf_uint32_t
*)p
);
129 /* Calculate the address mask */
131 * Following lint complaint is unwarranted, probably an
132 * uninitialized variable in lint or something ...
134 /* LINTED constant truncated by assignment */
135 tnf
->address_mask
= 0xffffffff;
136 tnf
->address_mask
<<= tnf
->generation_shift
;
137 tnf
->address_mask
= ~(tnf
->address_mask
);
141 * Examine first block header in data area
144 tnf
->data_start
= tnf
->file_start
+ tnf
->directory_size
;
145 /* LINTED pointer cast may result in improper alignment */
146 bhdr
= (tnf_ref32_t
*)tnf
->data_start
;
148 /* Block generation offset */
149 genp
= _tnf_get_slot_named(tnf
, bhdr
, TNF_N_GENERATION
);
150 tnf
->block_generation_offset
= genp
- (caddr_t
)bhdr
;
152 /* Block bytes valid offset */
153 bvp
= _tnf_get_slot_named(tnf
, bhdr
, TNF_N_BYTES_VALID
);
154 tnf
->block_bytes_valid_offset
= bvp
- (caddr_t
)bhdr
;
157 * Bootstrap taginfo system and cache important taginfo
160 if ((err
= _tnf_init_tags(tnf
)) != TNF_ERR_NONE
)
163 tnf
->file_header_info
= _tnf_get_info(tnf
, _tnf_get_tag(tnf
, fhdr
));
164 tnf
->block_header_info
= _tnf_get_info(tnf
, _tnf_get_tag(tnf
, bhdr
));
167 * Return TNF handle and error status
171 return (TNF_ERR_NONE
);
175 * Terminate a reader session
179 tnf_reader_end(TNF
*tnf
)
183 /* Deallocate all taginfo */
184 if ((err
= _tnf_fini_tags(tnf
)) != TNF_ERR_NONE
)
190 return (TNF_ERR_NONE
);