6198 Let's EOL cachefs
[illumos-gate.git] / usr / src / lib / libtnf / reader.c
blobc7d3d8fe746a58f6e2e23a051f51aff7029311a0
1 /*
2 * CDDL HEADER START
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
7 * with the License.
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]
20 * CDDL HEADER END
23 * Copyright (c) 1994, by Sun Microsytems, Inc.
26 #pragma ident "%Z%%M% %I% %E% SMI"
28 #include "libtnf.h"
31 * Initiate a reader session
34 tnf_errcode_t
35 tnf_reader_begin(caddr_t base, size_t size, TNF **tnfret)
37 tnf_uint32_t magic;
38 int native;
39 TNF *tnf;
40 tnf_ref32_t *fhdr, *bhdr;
41 size_t tmpsz;
42 caddr_t p, genp, bvp;
43 tnf_errcode_t err;
46 * Check magic number
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 */
54 else
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;
71 * Examine file header
74 /* LINTED pointer cast may result in improper alignment */
75 fhdr = (tnf_ref32_t *)(base + sizeof (magic)); /* second word */
76 tnf->file_header = fhdr;
78 /* Block size */
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);
83 /* Directory size */
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);
88 /* Block count */
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;
104 if (tmpsz != size) {
105 if (tmpsz > size)
106 /* missing data? */
107 return (TNF_ERR_BADTNF);
108 else {
109 tnf->file_size = tmpsz;
110 tnf->file_end = base + tmpsz;
114 /* Calculate block shift */
115 tmpsz = 1;
116 while (tmpsz != tnf->block_size) {
117 tmpsz <<= 1;
118 tnf->block_shift++;
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)
161 return (err);
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
170 *tnfret = tnf;
171 return (TNF_ERR_NONE);
175 * Terminate a reader session
178 tnf_errcode_t
179 tnf_reader_end(TNF *tnf)
181 tnf_errcode_t err;
183 /* Deallocate all taginfo */
184 if ((err = _tnf_fini_tags(tnf)) != TNF_ERR_NONE)
185 return (err);
187 /* Deallocate TNF */
188 free(tnf);
190 return (TNF_ERR_NONE);