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