1 /* 2 * CDDL HEADER START 3 * 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. 8 * 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. 13 * 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] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1994, by Sun Microsytems, Inc. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include "libtnf.h" 29 30 /* 31 * File header operations 32 */ 33 34 tnf_datum_t 35 tnf_get_file_header(TNF *tnf) 36 { 37 return (DATUM(tnf->file_header_info, (caddr_t)tnf->file_header)); 38 } 39 40 /* 41 * Block access operations 42 */ 43 44 unsigned 45 tnf_get_block_count(TNF *tnf) 46 { 47 return (tnf->block_count); 48 } 49 50 tnf_datum_t 51 tnf_get_block_absolute(TNF *tnf, unsigned index) 52 { 53 if (index >= tnf->block_count) 54 /* 55 * access to non-existent block: 56 * no error as per spec 57 */ 58 return (TNF_DATUM_NULL); 59 else 60 /* 61 * XXX Require a single block header tag 62 */ 63 /* LINTED pointer cast may result in improper alignment */ 64 return (DATUM(tnf->block_header_info, 65 (caddr_t)_GET_INDEX_BLOCK(tnf, index))); 66 } 67 68 tnf_datum_t 69 tnf_get_block_relative(tnf_datum_t datum, int adjust) 70 { 71 TNF *tnf; 72 tnf_ref32_t *bhdr; 73 unsigned index; 74 75 CHECK_DATUM(datum); 76 77 tnf = DATUM_TNF(datum); 78 bhdr = _GET_BLOCK(tnf, DATUM_VAL(datum)); 79 index = _GET_BLOCK_INDEX(tnf, bhdr); 80 81 return (tnf_get_block_absolute(tnf, index + adjust)); 82 } 83 84 int 85 tnf_is_block_header(tnf_datum_t datum) 86 { 87 struct taginfo *info; 88 caddr_t val; 89 tnf_ref32_t *bhdr; 90 91 CHECK_DATUM(datum); 92 93 info = DATUM_INFO(datum); 94 val = DATUM_VAL(datum); 95 bhdr = _GET_BLOCK(info->tnf, val); 96 97 return (((caddr_t)bhdr == val) && 98 (info == info->tnf->block_header_info)); 99 } 100 101 tnf_datum_t 102 tnf_get_block_header(tnf_datum_t datum) 103 { 104 TNF *tnf; 105 caddr_t val; 106 107 CHECK_DATUM(datum); 108 109 tnf = DATUM_TNF(datum); 110 val = DATUM_VAL(datum); 111 /* 112 * XXX Require a single block header tag 113 */ 114 return (DATUM(tnf->block_header_info, (caddr_t)_GET_BLOCK(tnf, val))); 115 } 116 117 /* 118 * Sequential record access 119 */ 120 121 tnf_datum_t 122 tnf_get_next_record(tnf_datum_t datum) 123 { 124 TNF *tnf; 125 tnf_ref32_t *bhdr, *cell, ref32; 126 caddr_t val, nval, bval, blim; 127 size_t size, bytes; 128 129 CHECK_RECORD(datum); 130 131 tnf = DATUM_TNF(datum); 132 val = DATUM_VAL(datum); 133 134 size = tnf_get_size(datum); 135 nval = val + size; 136 137 /* Check file bounds */ 138 if (nval < tnf->data_start) 139 return (tnf_get_block_absolute(tnf, 0)); 140 else if (nval >= tnf->file_end) 141 return (TNF_DATUM_NULL); 142 143 /* 144 * OK, nval is in data area, start looking in block 145 */ 146 bhdr = _GET_BLOCK(tnf, nval); 147 /* LINTED pointer cast may result in improper alignment */ 148 bytes = _GET_BLOCK_BYTES_VALID(tnf, bhdr); 149 bval = (caddr_t)bhdr; 150 blim = bval + bytes; 151 152 /* sequentially examine valid cells in block from nval onwards */ 153 while (nval < blim) { 154 /* LINTED pointer cast may result in improper alignment */ 155 cell = (tnf_ref32_t *)nval; 156 ref32 = _GET_INT32(tnf, cell); 157 158 switch (TNF_REF32_TYPE(ref32)) { 159 case TNF_REF32_T_FWD: /* skip forwarding cells */ 160 nval += sizeof (tnf_ref32_t); 161 break; 162 case TNF_REF32_T_RSVD: /* catch bogus cells */ 163 _tnf_error(tnf, TNF_ERR_BADTNF); 164 return (TNF_DATUM_NULL); 165 default: /* PAIR or TAG: record header */ 166 return (RECORD_DATUM(tnf, cell)); 167 } 168 } 169 170 /* 171 * Couldn't find it: return next non-zero block header 172 */ 173 while ((bval += tnf->block_size) < tnf->file_end) 174 /* Gotta check that there is a real bhdr here */ 175 /* LINTED pointer cast may result in improper alignment */ 176 if (*(tnf_ref32_t *)bval != TNF_NULL) 177 /* LINTED pointer cast may result in improper alignment */ 178 return (RECORD_DATUM(tnf, (tnf_ref32_t *)bval)); 179 180 /* 181 * default: we're off the end of the file 182 */ 183 return (TNF_DATUM_NULL); 184 } 185