xref: /onnv-gate/usr/src/cmd/fs.d/udfs/fstyp/ud_lib.c (revision 2212:4d4fd25d9b6e)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*2212Sartem  * Common Development and Distribution License (the "License").
6*2212Sartem  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*2212Sartem  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23*2212Sartem  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate #include <stdio.h>
290Sstevel@tonic-gate #include <stdlib.h>
300Sstevel@tonic-gate #include <malloc.h>
310Sstevel@tonic-gate #include <unistd.h>
320Sstevel@tonic-gate #include <strings.h>
330Sstevel@tonic-gate #include <errno.h>
340Sstevel@tonic-gate #include <libintl.h>
350Sstevel@tonic-gate #include <libgen.h>
360Sstevel@tonic-gate #include <fcntl.h>
370Sstevel@tonic-gate #include <sys/types.h>
380Sstevel@tonic-gate #include <sys/int_types.h>
390Sstevel@tonic-gate #include <sys/dkio.h>
400Sstevel@tonic-gate #include <sys/cdio.h>
410Sstevel@tonic-gate #include <sys/vtoc.h>
420Sstevel@tonic-gate #include <sys/stat.h>
430Sstevel@tonic-gate #include <sys/param.h>
440Sstevel@tonic-gate #include <sys/fs/udf_volume.h>
450Sstevel@tonic-gate #include "ud_lib.h"
460Sstevel@tonic-gate 
470Sstevel@tonic-gate extern char *getfullrawname(char *);
480Sstevel@tonic-gate 
49*2212Sartem static int32_t ud_get_ecma_ver(ud_handle_t, uint32_t);
50*2212Sartem static int32_t ud_get_fs_bsize(ud_handle_t, uint32_t, uint32_t *);
51*2212Sartem static int32_t ud_parse_fill_vds(ud_handle_t, struct vds *, uint32_t, uint32_t);
52*2212Sartem static int32_t	ud_read_and_translate_lvd(ud_handle_t, uint32_t, uint32_t);
53*2212Sartem static int32_t ud_get_latest_lvid(ud_handle_t, uint32_t, uint32_t);
54*2212Sartem static int32_t	ud_get_latest_fsd(ud_handle_t, uint16_t, uint32_t, uint32_t);
55*2212Sartem 
56*2212Sartem static uint16_t ud_crc(uint8_t *, int32_t);
57*2212Sartem static int32_t UdfTxName(uint16_t *, int32_t);
58*2212Sartem static int32_t UncompressUnicode(int32_t, uint8_t *, uint16_t *);
59*2212Sartem static int32_t ud_compressunicode(int32_t, int32_t, uint16_t *, uint8_t *);
60*2212Sartem static int32_t ud_convert2utf8(uint8_t *, uint8_t *, int32_t);
61*2212Sartem static int32_t ud_convert2utf16(uint8_t *, uint8_t *, int32_t);
620Sstevel@tonic-gate 
630Sstevel@tonic-gate 
64*2212Sartem int
ud_init(int fd,ud_handle_t * hp)65*2212Sartem ud_init(int fd, ud_handle_t *hp)
66*2212Sartem {
67*2212Sartem 	struct ud_handle *h;
680Sstevel@tonic-gate 
69*2212Sartem 	if ((h = calloc(1, sizeof (struct ud_handle))) == NULL) {
70*2212Sartem 		return (ENOMEM);
71*2212Sartem 	}
72*2212Sartem 	h->fd = fd;
73*2212Sartem 	*hp = h;
74*2212Sartem 	return (0);
75*2212Sartem }
760Sstevel@tonic-gate 
77*2212Sartem void
ud_fini(ud_handle_t h)78*2212Sartem ud_fini(ud_handle_t h)
79*2212Sartem {
80*2212Sartem 	free(h);
81*2212Sartem }
820Sstevel@tonic-gate 
83*2212Sartem /* ARGSUSED */
840Sstevel@tonic-gate int32_t
ud_open_dev(ud_handle_t h,char * special,uint32_t flags)85*2212Sartem ud_open_dev(ud_handle_t h, char *special, uint32_t flags)
860Sstevel@tonic-gate {
870Sstevel@tonic-gate 	char *temp;
880Sstevel@tonic-gate 	struct stat i_stat, r_stat;
890Sstevel@tonic-gate 
900Sstevel@tonic-gate 	(void) bzero(&i_stat, sizeof (struct stat));
910Sstevel@tonic-gate 	(void) bzero(&r_stat, sizeof (struct stat));
920Sstevel@tonic-gate 
930Sstevel@tonic-gate 	/*
940Sstevel@tonic-gate 	 * Get the stat structure
950Sstevel@tonic-gate 	 */
960Sstevel@tonic-gate 	if (stat(special, &i_stat) < 0) {
970Sstevel@tonic-gate 		temp = special;
980Sstevel@tonic-gate 	} else {
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate 		if ((i_stat.st_mode & S_IFMT) == S_IFCHR) {
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate 			/*
1030Sstevel@tonic-gate 			 * If Raw deivce is given use it as it is
1040Sstevel@tonic-gate 			 */
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate 			temp = special;
1070Sstevel@tonic-gate 		} else if ((i_stat.st_mode & S_IFMT) == S_IFBLK) {
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate 			/*
1100Sstevel@tonic-gate 			 * Block device try to convert to raw device
1110Sstevel@tonic-gate 			 */
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate 			temp = getfullrawname(special);
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate 			/*
1160Sstevel@tonic-gate 			 * Stat the converted device name and verify
1170Sstevel@tonic-gate 			 * both the raw and block device belong to
1180Sstevel@tonic-gate 			 * the same device
1190Sstevel@tonic-gate 			 */
1200Sstevel@tonic-gate 			if (stat(temp, &r_stat) < 0) {
1210Sstevel@tonic-gate 				temp = special;
1220Sstevel@tonic-gate 			} else {
1230Sstevel@tonic-gate 				if (((r_stat.st_mode & S_IFMT) == S_IFBLK) ||
1240Sstevel@tonic-gate 					(r_stat.st_rdev != i_stat.st_rdev)) {
1250Sstevel@tonic-gate 					temp = special;
1260Sstevel@tonic-gate 				}
1270Sstevel@tonic-gate 			}
1280Sstevel@tonic-gate 		}
1290Sstevel@tonic-gate 	}
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate 	/*
1320Sstevel@tonic-gate 	 * Now finally open the device
1330Sstevel@tonic-gate 	 */
134*2212Sartem 	h->fd = open(temp, flags);
1350Sstevel@tonic-gate 
136*2212Sartem 	return (h->fd);
1370Sstevel@tonic-gate }
1380Sstevel@tonic-gate 
139*2212Sartem /* ARGSUSED */
1400Sstevel@tonic-gate void
ud_close_dev(ud_handle_t h)141*2212Sartem ud_close_dev(ud_handle_t h)
1420Sstevel@tonic-gate {
1430Sstevel@tonic-gate 	/*
1440Sstevel@tonic-gate 	 * Too simple Just close it
1450Sstevel@tonic-gate 	 */
146*2212Sartem 	(void) close(h->fd);
1470Sstevel@tonic-gate }
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate int32_t
ud_read_dev(ud_handle_t h,uint64_t offset,uint8_t * buf,uint32_t count)150*2212Sartem ud_read_dev(ud_handle_t h, uint64_t offset, uint8_t *buf, uint32_t count)
1510Sstevel@tonic-gate {
1520Sstevel@tonic-gate 	/*
1530Sstevel@tonic-gate 	 * Seek to the given offset
1540Sstevel@tonic-gate 	 */
155*2212Sartem 	if (lseek(h->fd, offset, SEEK_SET) == -1) {
1560Sstevel@tonic-gate 		return (1);
1570Sstevel@tonic-gate 	}
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate 	/*
1600Sstevel@tonic-gate 	 * Read the required number of bytes
1610Sstevel@tonic-gate 	 */
162*2212Sartem 	if (read(h->fd, buf, count) != count) {
1630Sstevel@tonic-gate 		return (1);
1640Sstevel@tonic-gate 	}
1650Sstevel@tonic-gate 	return (0);
1660Sstevel@tonic-gate }
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate int32_t
ud_write_dev(ud_handle_t h,uint64_t offset,uint8_t * buf,uint32_t count)169*2212Sartem ud_write_dev(ud_handle_t h, uint64_t offset, uint8_t *buf, uint32_t count)
1700Sstevel@tonic-gate {
1710Sstevel@tonic-gate 	/*
1720Sstevel@tonic-gate 	 * Seek to the given offset
1730Sstevel@tonic-gate 	 */
174*2212Sartem 	if (lseek(h->fd, offset, SEEK_SET) == -1) {
1750Sstevel@tonic-gate 		return (1);
1760Sstevel@tonic-gate 	}
1770Sstevel@tonic-gate 
1780Sstevel@tonic-gate 	/*
1790Sstevel@tonic-gate 	 * Read the appropriate number of bytes
1800Sstevel@tonic-gate 	 */
181*2212Sartem 	if (write(h->fd, buf, count) != count) {
1820Sstevel@tonic-gate 		return (1);
1830Sstevel@tonic-gate 	}
1840Sstevel@tonic-gate 	return (0);
1850Sstevel@tonic-gate }
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate /* ----- BEGIN Read and translate the on disk VDS to IN CORE format -------- */
1880Sstevel@tonic-gate 
1890Sstevel@tonic-gate int32_t
ud_fill_udfs_info(ud_handle_t h)190*2212Sartem ud_fill_udfs_info(ud_handle_t h)
1910Sstevel@tonic-gate {
1920Sstevel@tonic-gate 	struct	anch_vol_desc_ptr	*avdp = NULL;
1930Sstevel@tonic-gate 	uint32_t			offset = 0;
1940Sstevel@tonic-gate 
195*2212Sartem 	if (ioctl(h->fd, CDROMREADOFFSET, &offset) == -1) {
1960Sstevel@tonic-gate 		offset = 0;
1970Sstevel@tonic-gate 	}
1980Sstevel@tonic-gate 
199*2212Sartem 	h->udfs.flags = INVALID_UDFS;
2000Sstevel@tonic-gate 
201*2212Sartem 	h->udfs.ecma_version = ud_get_ecma_ver(h, offset);
202*2212Sartem 	if (h->udfs.ecma_version == UD_ECMA_UNKN) {
2030Sstevel@tonic-gate 		return (1);
2040Sstevel@tonic-gate 	}
2050Sstevel@tonic-gate 
206*2212Sartem 	h->udfs.lbsize = ud_get_fs_bsize(h, offset, &h->udfs.avdp_loc);
207*2212Sartem 	if (h->udfs.lbsize == 0) {
2080Sstevel@tonic-gate 		return (2);
2090Sstevel@tonic-gate 	}
2100Sstevel@tonic-gate 
211*2212Sartem 	h->udfs.avdp_len = lb_roundup(512, h->udfs.lbsize);
2120Sstevel@tonic-gate 
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate 	if ((avdp = (struct anch_vol_desc_ptr *)
215*2212Sartem 			malloc(h->udfs.lbsize)) == NULL) {
2160Sstevel@tonic-gate 		return (3);
2170Sstevel@tonic-gate 	}
218*2212Sartem 	if (ud_read_dev(h, h->udfs.avdp_loc * h->udfs.lbsize,
219*2212Sartem 			(uint8_t *)avdp, h->udfs.lbsize) != 0) {
2200Sstevel@tonic-gate 		free(avdp);
2210Sstevel@tonic-gate 		return (4);
2220Sstevel@tonic-gate 	}
223*2212Sartem 	if (ud_verify_tag(h, &avdp->avd_tag, UD_ANCH_VOL_DESC,
224*2212Sartem 			h->udfs.avdp_loc, 1, 0) != 0) {
2250Sstevel@tonic-gate 		free(avdp);
2260Sstevel@tonic-gate 		return (5);
2270Sstevel@tonic-gate 	}
2280Sstevel@tonic-gate 
229*2212Sartem 	h->udfs.mvds_loc = SWAP_32(avdp->avd_main_vdse.ext_loc);
230*2212Sartem 	h->udfs.mvds_len = SWAP_32(avdp->avd_main_vdse.ext_len);
2310Sstevel@tonic-gate 
232*2212Sartem 	h->udfs.rvds_loc = SWAP_32(avdp->avd_res_vdse.ext_loc);
233*2212Sartem 	h->udfs.rvds_len = SWAP_32(avdp->avd_res_vdse.ext_len);
2340Sstevel@tonic-gate 
2350Sstevel@tonic-gate 	free(avdp);
2360Sstevel@tonic-gate 
2370Sstevel@tonic-gate 	/*
2380Sstevel@tonic-gate 	 * get information from mvds and rvds
2390Sstevel@tonic-gate 	 */
240*2212Sartem 	if (ud_parse_fill_vds(h, &h->udfs.mvds,
241*2212Sartem 			h->udfs.mvds_loc, h->udfs.mvds_len) == 0) {
242*2212Sartem 		h->udfs.flags |= VALID_MVDS;
2430Sstevel@tonic-gate 	}
244*2212Sartem 	if (ud_parse_fill_vds(h, &h->udfs.rvds,
245*2212Sartem 			h->udfs.rvds_loc, h->udfs.rvds_len) == 0) {
246*2212Sartem 		h->udfs.flags |= VALID_RVDS;
2470Sstevel@tonic-gate 	}
2480Sstevel@tonic-gate 
249*2212Sartem 	if ((h->udfs.flags & (VALID_MVDS | VALID_RVDS)) == 0) {
2500Sstevel@tonic-gate 		return (6);
2510Sstevel@tonic-gate 	}
2520Sstevel@tonic-gate 
2530Sstevel@tonic-gate 	/*
2540Sstevel@tonic-gate 	 * If we are here we have
2550Sstevel@tonic-gate 	 * a valid Volume Descriptor Seqence
2560Sstevel@tonic-gate 	 * Read and understand lvd
2570Sstevel@tonic-gate 	 */
258*2212Sartem 	if (h->udfs.flags & VALID_MVDS) {
259*2212Sartem 		if (ud_read_and_translate_lvd(h, h->udfs.mvds.lvd_loc,
260*2212Sartem 				h->udfs.mvds.lvd_len) != 0) {
2610Sstevel@tonic-gate 			return (7);
2620Sstevel@tonic-gate 		}
2630Sstevel@tonic-gate 	} else {
264*2212Sartem 		if (ud_read_and_translate_lvd(h, h->udfs.rvds.lvd_loc,
265*2212Sartem 				h->udfs.rvds.lvd_len) != 0) {
2660Sstevel@tonic-gate 			return (8);
2670Sstevel@tonic-gate 		}
2680Sstevel@tonic-gate 	}
2690Sstevel@tonic-gate 
270*2212Sartem 	h->udfs.flags |= VALID_UDFS;
2710Sstevel@tonic-gate 
2720Sstevel@tonic-gate 	return (0);
2730Sstevel@tonic-gate }
2740Sstevel@tonic-gate 
275*2212Sartem static int32_t
ud_get_ecma_ver(ud_handle_t h,uint32_t offset)276*2212Sartem ud_get_ecma_ver(ud_handle_t h, uint32_t offset)
2770Sstevel@tonic-gate {
2780Sstevel@tonic-gate 	uint8_t *buf;
2790Sstevel@tonic-gate 	uint64_t off;
2800Sstevel@tonic-gate 	uint64_t end_off;
2810Sstevel@tonic-gate 	struct nsr_desc *ndsc;
2820Sstevel@tonic-gate 	uint32_t ecma_ver = UD_ECMA_UNKN;
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate 	/*
2850Sstevel@tonic-gate 	 * Allocate a buffer of size UD_VOL_REC_BSZ
2860Sstevel@tonic-gate 	 */
2870Sstevel@tonic-gate 	if ((buf = (uint8_t *)malloc(UD_VOL_REC_BSZ)) == NULL) {
2880Sstevel@tonic-gate 
2890Sstevel@tonic-gate 		/*
2900Sstevel@tonic-gate 		 * Uh could not even allocate this much
2910Sstevel@tonic-gate 		 */
2920Sstevel@tonic-gate 		goto end;
2930Sstevel@tonic-gate 	}
2940Sstevel@tonic-gate 
2950Sstevel@tonic-gate 	/*
2960Sstevel@tonic-gate 	 * Start from 32k and keep reading 2k blocks we
2970Sstevel@tonic-gate 	 * should be able to find NSR if we have one by 256 * 2k bytes
2980Sstevel@tonic-gate 	 */
2990Sstevel@tonic-gate 	off = offset * 2048 + UD_VOL_REC_START;
3000Sstevel@tonic-gate 	end_off = offset * 2048 + UD_VOL_REC_END;
3010Sstevel@tonic-gate 	for (; off < end_off; off += UD_VOL_REC_BSZ) {
3020Sstevel@tonic-gate 
303*2212Sartem 		if (ud_read_dev(h, off, buf, UD_VOL_REC_BSZ) == 0) {
3040Sstevel@tonic-gate 
3050Sstevel@tonic-gate 			ndsc = (struct nsr_desc *)buf;
3060Sstevel@tonic-gate 			/*
3070Sstevel@tonic-gate 			 * Is this either NSR02 or NSR03
3080Sstevel@tonic-gate 			 */
3090Sstevel@tonic-gate 			if ((ndsc->nsr_str_type == 0) &&
3100Sstevel@tonic-gate 				(ndsc->nsr_ver == 1) &&
3110Sstevel@tonic-gate 				(ndsc->nsr_id[0] == 'N') &&
3120Sstevel@tonic-gate 				(ndsc->nsr_id[1] == 'S') &&
3130Sstevel@tonic-gate 				(ndsc->nsr_id[2] == 'R') &&
3140Sstevel@tonic-gate 				(ndsc->nsr_id[3] == '0') &&
3150Sstevel@tonic-gate 					((ndsc->nsr_id[4] == '2') ||
3160Sstevel@tonic-gate 					(ndsc->nsr_id[4] == '3'))) {
3170Sstevel@tonic-gate 
318*2212Sartem 				(void) strncpy((char *)h->udfs.ecma_id,
3190Sstevel@tonic-gate 					(char *)ndsc->nsr_id, 5);
3200Sstevel@tonic-gate 
3210Sstevel@tonic-gate 				switch (ndsc->nsr_id[4]) {
3220Sstevel@tonic-gate 				case '2' :
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate 					/*
3250Sstevel@tonic-gate 					 * ECMA 167/2
3260Sstevel@tonic-gate 					 */
3270Sstevel@tonic-gate 					ecma_ver = UD_ECMA_VER2;
3280Sstevel@tonic-gate 					goto end;
3290Sstevel@tonic-gate 				case '3' :
3300Sstevel@tonic-gate 
3310Sstevel@tonic-gate 					/*
3320Sstevel@tonic-gate 					 * ECMA 167/3
3330Sstevel@tonic-gate 					 */
3340Sstevel@tonic-gate 					ecma_ver = UD_ECMA_VER3;
3350Sstevel@tonic-gate 					goto end;
3360Sstevel@tonic-gate 				}
3370Sstevel@tonic-gate 			}
3380Sstevel@tonic-gate 		}
3390Sstevel@tonic-gate 	}
3400Sstevel@tonic-gate 
3410Sstevel@tonic-gate end:
3420Sstevel@tonic-gate 	/*
3430Sstevel@tonic-gate 	 * Cleanup
3440Sstevel@tonic-gate 	 */
3450Sstevel@tonic-gate 	free(buf);
3460Sstevel@tonic-gate 	return (ecma_ver);
3470Sstevel@tonic-gate }
3480Sstevel@tonic-gate 
349*2212Sartem static uint32_t last_block_index[] = {0, 0, 256, 2, 2 + 256,
3500Sstevel@tonic-gate 		150, 150 + 256, 152, 152 + 256};
3510Sstevel@tonic-gate 
352*2212Sartem static int32_t
ud_get_fs_bsize(ud_handle_t h,uint32_t offset,uint32_t * avd_loc)353*2212Sartem ud_get_fs_bsize(ud_handle_t h, uint32_t offset, uint32_t *avd_loc)
3540Sstevel@tonic-gate {
3550Sstevel@tonic-gate 	uint64_t off;
3560Sstevel@tonic-gate 	int32_t index, bsize, shift, end_index;
3570Sstevel@tonic-gate 	uint32_t num_blocks, sub_blk;
3580Sstevel@tonic-gate 	uint8_t *buf = NULL;
3590Sstevel@tonic-gate 	struct anch_vol_desc_ptr *avdp;
3600Sstevel@tonic-gate 
3610Sstevel@tonic-gate 	if ((buf = (uint8_t *)malloc(MAXBSIZE)) == NULL) {
3620Sstevel@tonic-gate 		return (0);
3630Sstevel@tonic-gate 	}
3640Sstevel@tonic-gate 
3650Sstevel@tonic-gate 	/*
3660Sstevel@tonic-gate 	 * If we could figure out the last block
3670Sstevel@tonic-gate 	 * search at 256, N, N - 256 blocks
3680Sstevel@tonic-gate 	 * otherwise just check at 256
3690Sstevel@tonic-gate 	 */
370*2212Sartem 	if (ud_get_num_blks(h, &num_blocks) != 0) {
3710Sstevel@tonic-gate 		end_index = 1;
3720Sstevel@tonic-gate 		num_blocks = 0;
3730Sstevel@tonic-gate 	} else {
3740Sstevel@tonic-gate 		end_index = sizeof (last_block_index) / 4;
3750Sstevel@tonic-gate 	}
3760Sstevel@tonic-gate 
3770Sstevel@tonic-gate 	for (index = 0; index < end_index; index++) {
3780Sstevel@tonic-gate 		sub_blk = last_block_index[index];
3790Sstevel@tonic-gate 
3800Sstevel@tonic-gate 		/*
3810Sstevel@tonic-gate 		 * Start guessing from DEV_BSIZE to MAXBSIZE
3820Sstevel@tonic-gate 		 */
3830Sstevel@tonic-gate 		for (bsize = DEV_BSIZE, shift = 0;
3840Sstevel@tonic-gate 			bsize <= MAXBSIZE; bsize <<= 1, shift++) {
3850Sstevel@tonic-gate 
3860Sstevel@tonic-gate 			if (index == 0) {
3870Sstevel@tonic-gate 
3880Sstevel@tonic-gate 				/*
3890Sstevel@tonic-gate 				 * Check if we atleast have 256 of bsize
3900Sstevel@tonic-gate 				 * blocks on the device
3910Sstevel@tonic-gate 				 */
3920Sstevel@tonic-gate 				if ((end_index == 0) ||
3930Sstevel@tonic-gate 					(num_blocks > (256 << shift))) {
3940Sstevel@tonic-gate 					*avd_loc = 256;
3950Sstevel@tonic-gate 					if (bsize <= 2048) {
3960Sstevel@tonic-gate 						*avd_loc +=
3970Sstevel@tonic-gate 							offset * 2048 / bsize;
3980Sstevel@tonic-gate 					} else {
3990Sstevel@tonic-gate 						*avd_loc +=
4000Sstevel@tonic-gate 							offset / (bsize / 2048);
4010Sstevel@tonic-gate 					}
4020Sstevel@tonic-gate 				} else {
4030Sstevel@tonic-gate 					continue;
4040Sstevel@tonic-gate 				}
4050Sstevel@tonic-gate 			} else {
4060Sstevel@tonic-gate 				/*
407*2212Sartem 				 * Calculate the bsize avd block
4080Sstevel@tonic-gate 				 */
4090Sstevel@tonic-gate 				if ((num_blocks) &&
4100Sstevel@tonic-gate 					(num_blocks > (sub_blk << shift))) {
4110Sstevel@tonic-gate 					*avd_loc = (num_blocks >> shift) -
4120Sstevel@tonic-gate 						sub_blk;
4130Sstevel@tonic-gate 				} else {
4140Sstevel@tonic-gate 					continue;
4150Sstevel@tonic-gate 				}
4160Sstevel@tonic-gate 			}
4170Sstevel@tonic-gate 
4180Sstevel@tonic-gate 			off = (uint64_t)*avd_loc * bsize;
4190Sstevel@tonic-gate 
4200Sstevel@tonic-gate 			/*
4210Sstevel@tonic-gate 			 * Read bsize bytes at off
4220Sstevel@tonic-gate 			 */
423*2212Sartem 			if (ud_read_dev(h, off, buf, bsize) != 0) {
4240Sstevel@tonic-gate 				continue;
4250Sstevel@tonic-gate 			}
4260Sstevel@tonic-gate 
4270Sstevel@tonic-gate 			/*
4280Sstevel@tonic-gate 			 * Check if we have a Anchor Volume Descriptor here
4290Sstevel@tonic-gate 			 */
4300Sstevel@tonic-gate 
4310Sstevel@tonic-gate 			/* LINTED */
4320Sstevel@tonic-gate 			avdp = (struct anch_vol_desc_ptr *)buf;
433*2212Sartem 			if (ud_verify_tag(h, &avdp->avd_tag,
4340Sstevel@tonic-gate 				UD_ANCH_VOL_DESC, *avd_loc, 1, 0) != 0) {
4350Sstevel@tonic-gate 				continue;
4360Sstevel@tonic-gate 			}
4370Sstevel@tonic-gate 			goto end;
4380Sstevel@tonic-gate 		}
4390Sstevel@tonic-gate 	}
4400Sstevel@tonic-gate 
4410Sstevel@tonic-gate end:
4420Sstevel@tonic-gate 	if (bsize > MAXBSIZE) {
4430Sstevel@tonic-gate 		bsize = 0;
4440Sstevel@tonic-gate 		*avd_loc = 0;
4450Sstevel@tonic-gate 	}
4460Sstevel@tonic-gate 	free(buf);
4470Sstevel@tonic-gate 	return (bsize);
4480Sstevel@tonic-gate }
4490Sstevel@tonic-gate 
450*2212Sartem static int32_t
ud_parse_fill_vds(ud_handle_t h,struct vds * v,uint32_t vds_loc,uint32_t vds_len)451*2212Sartem ud_parse_fill_vds(ud_handle_t h, struct vds *v,
4520Sstevel@tonic-gate 	uint32_t vds_loc, uint32_t vds_len)
4530Sstevel@tonic-gate {
4540Sstevel@tonic-gate 	uint8_t *addr, *taddr, *eaddr;
4550Sstevel@tonic-gate 	uint16_t id;
4560Sstevel@tonic-gate 	int32_t i;
4570Sstevel@tonic-gate 	uint64_t off;
4580Sstevel@tonic-gate 	struct tag *tag;
4590Sstevel@tonic-gate 	struct pri_vol_desc *pvd;
4600Sstevel@tonic-gate 	struct log_vol_desc *lvd;
4610Sstevel@tonic-gate 	struct vol_desc_ptr *vds;
4620Sstevel@tonic-gate 	struct unall_spc_desc *usd;
4630Sstevel@tonic-gate 
4640Sstevel@tonic-gate begin:
4650Sstevel@tonic-gate 	if ((addr = (uint8_t *)malloc(vds_len)) == NULL) {
4660Sstevel@tonic-gate 		return (1);
4670Sstevel@tonic-gate 	}
4680Sstevel@tonic-gate 
469*2212Sartem 	off = vds_loc * h->udfs.lbsize;
470*2212Sartem 	if (ud_read_dev(h, off, addr, vds_len) != 0) {
4710Sstevel@tonic-gate 		goto end;
4720Sstevel@tonic-gate 	}
4730Sstevel@tonic-gate 
474*2212Sartem 	for (taddr = addr, eaddr = addr + h->udfs.mvds_len; taddr < eaddr;
475*2212Sartem 			taddr += h->udfs.lbsize, vds_loc ++) {
4760Sstevel@tonic-gate 
4770Sstevel@tonic-gate 		/* LINTED */
4780Sstevel@tonic-gate 		tag = (struct tag *)taddr;
4790Sstevel@tonic-gate 		id = SWAP_16(tag->tag_id);
4800Sstevel@tonic-gate 		/*
4810Sstevel@tonic-gate 		 * If you cannot verify the tag just skip it
4820Sstevel@tonic-gate 		 * This is not a fatal error
4830Sstevel@tonic-gate 		 */
484*2212Sartem 		if (ud_verify_tag(h, tag, id, vds_loc, 1, 0) != 0) {
4850Sstevel@tonic-gate 			continue;
4860Sstevel@tonic-gate 		}
4870Sstevel@tonic-gate 		switch (id) {
4880Sstevel@tonic-gate 		case UD_PRI_VOL_DESC :
4890Sstevel@tonic-gate 
4900Sstevel@tonic-gate 			/*
4910Sstevel@tonic-gate 			 * Primary Volume Descriptor
4920Sstevel@tonic-gate 			 */
4930Sstevel@tonic-gate 			/* LINTED */
4940Sstevel@tonic-gate 			pvd = (struct pri_vol_desc *)taddr;
4950Sstevel@tonic-gate 			if ((v->pvd_len == 0) ||
4960Sstevel@tonic-gate 				(SWAP_32(pvd->pvd_vdsn) > v->pvd_vdsn)) {
4970Sstevel@tonic-gate 				v->pvd_vdsn = SWAP_32(pvd->pvd_vdsn);
4980Sstevel@tonic-gate 				v->pvd_loc = vds_loc;
499*2212Sartem 				v->pvd_len = h->udfs.lbsize;
5000Sstevel@tonic-gate 			}
5010Sstevel@tonic-gate 			break;
5020Sstevel@tonic-gate 		case UD_VOL_DESC_PTR :
5030Sstevel@tonic-gate 
5040Sstevel@tonic-gate 			/*
5050Sstevel@tonic-gate 			 * Curent sequence is continued from
5060Sstevel@tonic-gate 			 * the location pointed by vdp
5070Sstevel@tonic-gate 			 */
5080Sstevel@tonic-gate 			/* LINTED */
5090Sstevel@tonic-gate 			vds = (struct vol_desc_ptr *)taddr;
5100Sstevel@tonic-gate 
5110Sstevel@tonic-gate 			if (SWAP_32(vds->vdp_nvdse.ext_len) != 0) {
5120Sstevel@tonic-gate 				vds_loc = SWAP_32(vds->vdp_nvdse.ext_loc);
5130Sstevel@tonic-gate 				vds_len = SWAP_32(vds->vdp_nvdse.ext_len);
5140Sstevel@tonic-gate 				free(addr);
5150Sstevel@tonic-gate 				goto begin;
5160Sstevel@tonic-gate 			}
5170Sstevel@tonic-gate 			break;
5180Sstevel@tonic-gate 		case UD_IMPL_USE_DESC :
5190Sstevel@tonic-gate 
5200Sstevel@tonic-gate 			/*
5210Sstevel@tonic-gate 			 * Implementation Use Volume Descriptor
5220Sstevel@tonic-gate 			 */
5230Sstevel@tonic-gate 			v->iud_loc = vds_loc;
524*2212Sartem 			v->iud_len = lb_roundup(512, h->udfs.lbsize);
5250Sstevel@tonic-gate 			break;
5260Sstevel@tonic-gate 		case UD_PART_DESC :
5270Sstevel@tonic-gate 			{
5280Sstevel@tonic-gate 				struct ud_part *p;
529*2212Sartem 				struct phdr_desc *ph;
5300Sstevel@tonic-gate 				struct part_desc *pd;
5310Sstevel@tonic-gate 
5320Sstevel@tonic-gate 				/*
5330Sstevel@tonic-gate 				 * Partition Descriptor
5340Sstevel@tonic-gate 				 */
5350Sstevel@tonic-gate 				/* LINTED */
5360Sstevel@tonic-gate 				pd = (struct part_desc *)taddr;
5370Sstevel@tonic-gate 
538*2212Sartem 				for (i = 0; i < h->n_parts; i++) {
539*2212Sartem 					p = &h->part[i];
5400Sstevel@tonic-gate 
5410Sstevel@tonic-gate 					if ((SWAP_16(pd->pd_pnum) ==
5420Sstevel@tonic-gate 							p->udp_number) &&
5430Sstevel@tonic-gate 						(SWAP_32(pd->pd_vdsn) >
5440Sstevel@tonic-gate 							p->udp_seqno)) {
5450Sstevel@tonic-gate 						break;
5460Sstevel@tonic-gate 					}
5470Sstevel@tonic-gate 				}
5480Sstevel@tonic-gate 
5490Sstevel@tonic-gate 				v->part_loc[i] = vds_loc;
5500Sstevel@tonic-gate 				v->part_len[i] =
551*2212Sartem 					lb_roundup(512, h->udfs.lbsize);
5520Sstevel@tonic-gate 
553*2212Sartem 				p = &h->part[i];
5540Sstevel@tonic-gate 				p->udp_number = SWAP_16(pd->pd_pnum);
5550Sstevel@tonic-gate 				p->udp_seqno = SWAP_32(pd->pd_vdsn);
5560Sstevel@tonic-gate 				p->udp_access = SWAP_32(pd->pd_acc_type);
5570Sstevel@tonic-gate 				p->udp_start = SWAP_32(pd->pd_part_start);
5580Sstevel@tonic-gate 				p->udp_length = SWAP_32(pd->pd_part_length);
5590Sstevel@tonic-gate 
5600Sstevel@tonic-gate 				/* LINTED */
561*2212Sartem 				ph = (struct phdr_desc *)pd->pd_pc_use;
562*2212Sartem 				if (ph->phdr_ust.sad_ext_len) {
5630Sstevel@tonic-gate 			p->udp_flags = UDP_SPACETBLS;
564*2212Sartem 			p->udp_unall_loc = SWAP_32(ph->phdr_ust.sad_ext_loc);
565*2212Sartem 			p->udp_unall_len = SWAP_32(ph->phdr_ust.sad_ext_len);
566*2212Sartem 			p->udp_freed_loc = SWAP_32(ph->phdr_fst.sad_ext_loc);
567*2212Sartem 			p->udp_freed_len = SWAP_32(ph->phdr_fst.sad_ext_len);
5680Sstevel@tonic-gate 				} else {
5690Sstevel@tonic-gate 			p->udp_flags = UDP_BITMAPS;
570*2212Sartem 			p->udp_unall_loc = SWAP_32(ph->phdr_usb.sad_ext_loc);
571*2212Sartem 			p->udp_unall_len = SWAP_32(ph->phdr_usb.sad_ext_len);
572*2212Sartem 			p->udp_freed_loc = SWAP_32(ph->phdr_fsb.sad_ext_loc);
573*2212Sartem 			p->udp_freed_len = SWAP_32(ph->phdr_fsb.sad_ext_len);
5740Sstevel@tonic-gate 				}
5750Sstevel@tonic-gate 
576*2212Sartem 				if (i == h->n_parts) {
577*2212Sartem 					h->n_parts ++;
5780Sstevel@tonic-gate 				}
5790Sstevel@tonic-gate 			}
5800Sstevel@tonic-gate 			break;
5810Sstevel@tonic-gate 		case UD_LOG_VOL_DESC :
5820Sstevel@tonic-gate 
5830Sstevel@tonic-gate 			/*
5840Sstevel@tonic-gate 			 * Logical Volume Descriptor
5850Sstevel@tonic-gate 			 */
5860Sstevel@tonic-gate 			/* LINTED */
5870Sstevel@tonic-gate 			lvd = (struct log_vol_desc *)taddr;
5880Sstevel@tonic-gate 			if ((v->lvd_len == 0) ||
5890Sstevel@tonic-gate 				(SWAP_32(lvd->lvd_vdsn) > v->lvd_vdsn)) {
5900Sstevel@tonic-gate 				v->lvd_vdsn = SWAP_32(lvd->lvd_vdsn);
5910Sstevel@tonic-gate 				v->lvd_loc = vds_loc;
5920Sstevel@tonic-gate 				v->lvd_len = ((uint32_t)
5930Sstevel@tonic-gate 					&((struct log_vol_desc *)0)->lvd_pmaps);
5940Sstevel@tonic-gate 				v->lvd_len =
595*2212Sartem 					lb_roundup(v->lvd_len, h->udfs.lbsize);
5960Sstevel@tonic-gate 			}
5970Sstevel@tonic-gate 			break;
5980Sstevel@tonic-gate 		case UD_UNALL_SPA_DESC :
5990Sstevel@tonic-gate 
6000Sstevel@tonic-gate 			/*
6010Sstevel@tonic-gate 			 * Unallocated Space Descriptor
6020Sstevel@tonic-gate 			 */
6030Sstevel@tonic-gate 			/* LINTED */
6040Sstevel@tonic-gate 			usd = (struct unall_spc_desc *)taddr;
6050Sstevel@tonic-gate 			v->usd_loc = vds_loc;
6060Sstevel@tonic-gate 			v->usd_len = ((uint32_t)
6070Sstevel@tonic-gate 			&((unall_spc_desc_t *)0)->ua_al_dsc) +
6080Sstevel@tonic-gate 				SWAP_32(usd->ua_nad) *
6090Sstevel@tonic-gate 				sizeof (struct extent_ad);
610*2212Sartem 			v->usd_len = lb_roundup(v->usd_len, h->udfs.lbsize);
6110Sstevel@tonic-gate 			break;
6120Sstevel@tonic-gate 		case UD_TERM_DESC :
6130Sstevel@tonic-gate 			/*
6140Sstevel@tonic-gate 			 * Success fully completed
6150Sstevel@tonic-gate 			 */
6160Sstevel@tonic-gate 			goto end;
6170Sstevel@tonic-gate 		default :
6180Sstevel@tonic-gate 			/*
6190Sstevel@tonic-gate 			 * If you donot undetstand any tag just skip
6200Sstevel@tonic-gate 			 * it. This is not a fatal error
6210Sstevel@tonic-gate 			 */
6220Sstevel@tonic-gate 			break;
6230Sstevel@tonic-gate 		}
6240Sstevel@tonic-gate 	}
6250Sstevel@tonic-gate 
6260Sstevel@tonic-gate end:
6270Sstevel@tonic-gate 	free(addr);
6280Sstevel@tonic-gate 	if ((v->pvd_len == 0) ||
6290Sstevel@tonic-gate 		(v->part_len[0] == 0) ||
6300Sstevel@tonic-gate 		(v->lvd_len == 0)) {
6310Sstevel@tonic-gate 		return (1);
6320Sstevel@tonic-gate 	}
6330Sstevel@tonic-gate 
6340Sstevel@tonic-gate 	return (0);
6350Sstevel@tonic-gate }
6360Sstevel@tonic-gate 
637*2212Sartem static int32_t
ud_read_and_translate_lvd(ud_handle_t h,uint32_t lvd_loc,uint32_t lvd_len)638*2212Sartem ud_read_and_translate_lvd(ud_handle_t h, uint32_t lvd_loc, uint32_t lvd_len)
6390Sstevel@tonic-gate {
6400Sstevel@tonic-gate 	caddr_t addr;
6410Sstevel@tonic-gate 	uint16_t fsd_prn;
6420Sstevel@tonic-gate 	uint32_t fsd_loc, fsd_len;
6430Sstevel@tonic-gate 	uint32_t lvds_loc, lvds_len;
6440Sstevel@tonic-gate 	uint64_t off;
6450Sstevel@tonic-gate 	struct log_vol_desc *lvd = NULL;
6460Sstevel@tonic-gate 
6470Sstevel@tonic-gate 	int32_t max_maps, i, mp_sz, index;
6480Sstevel@tonic-gate 	struct ud_map *m;
649*2212Sartem 	struct pmap_hdr *ph;
6500Sstevel@tonic-gate 	struct pmap_typ1 *typ1;
6510Sstevel@tonic-gate 	struct pmap_typ2 *typ2;
6520Sstevel@tonic-gate 
6530Sstevel@tonic-gate 	if (lvd_len == 0) {
6540Sstevel@tonic-gate 		return (1);
6550Sstevel@tonic-gate 	}
6560Sstevel@tonic-gate 
6570Sstevel@tonic-gate 	if ((lvd = (struct log_vol_desc *)
6580Sstevel@tonic-gate 			malloc(lvd_len)) == NULL) {
6590Sstevel@tonic-gate 		return (1);
6600Sstevel@tonic-gate 	}
6610Sstevel@tonic-gate 
662*2212Sartem 	off = lvd_loc * h->udfs.lbsize;
663*2212Sartem 	if (ud_read_dev(h, off, (uint8_t *)lvd, lvd_len) != 0) {
6640Sstevel@tonic-gate 		free(lvd);
6650Sstevel@tonic-gate 		return (1);
6660Sstevel@tonic-gate 	}
6670Sstevel@tonic-gate 
668*2212Sartem 	if (ud_verify_tag(h, &lvd->lvd_tag, UD_LOG_VOL_DESC,
6690Sstevel@tonic-gate 			lvd_loc, 1, 0) != 0) {
6700Sstevel@tonic-gate 		free(lvd);
6710Sstevel@tonic-gate 		return (1);
6720Sstevel@tonic-gate 	}
6730Sstevel@tonic-gate 
6740Sstevel@tonic-gate 	/*
6750Sstevel@tonic-gate 	 * Take care of maps
6760Sstevel@tonic-gate 	 */
6770Sstevel@tonic-gate 	max_maps = SWAP_32(lvd->lvd_num_pmaps);
678*2212Sartem 	ph = (struct pmap_hdr *)lvd->lvd_pmaps;
679*2212Sartem 	for (h->n_maps = index = 0; index < max_maps; index++) {
680*2212Sartem 		m = &h->maps[h->n_maps];
681*2212Sartem 		switch (ph->maph_type) {
6820Sstevel@tonic-gate 		case MAP_TYPE1 :
6830Sstevel@tonic-gate 
6840Sstevel@tonic-gate 			/* LINTED */
685*2212Sartem 			typ1 = (struct pmap_typ1 *)ph;
6860Sstevel@tonic-gate 
6870Sstevel@tonic-gate 			m->udm_flags = UDM_MAP_NORM;
6880Sstevel@tonic-gate 			m->udm_vsn = SWAP_16(typ1->map1_vsn);
6890Sstevel@tonic-gate 			m->udm_pn = SWAP_16(typ1->map1_pn);
690*2212Sartem 			h->n_maps++;
6910Sstevel@tonic-gate 			break;
6920Sstevel@tonic-gate 
6930Sstevel@tonic-gate 		case MAP_TYPE2 :
6940Sstevel@tonic-gate 
6950Sstevel@tonic-gate 			/* LINTED */
696*2212Sartem 			typ2 = (struct pmap_typ2 *)ph;
6970Sstevel@tonic-gate 
6980Sstevel@tonic-gate 			if (strncmp(typ2->map2_pti.reg_id,
6990Sstevel@tonic-gate 					UDF_VIRT_PART, 23) == 0) {
7000Sstevel@tonic-gate 
7010Sstevel@tonic-gate 				m->udm_flags = UDM_MAP_VPM;
7020Sstevel@tonic-gate 				m->udm_vsn = SWAP_16(typ2->map2_vsn);
7030Sstevel@tonic-gate 				m->udm_pn = SWAP_16(typ2->map2_pn);
7040Sstevel@tonic-gate 			} else if (strncmp(typ2->map2_pti.reg_id,
7050Sstevel@tonic-gate 					UDF_SPAR_PART, 23) == 0) {
7060Sstevel@tonic-gate 
7070Sstevel@tonic-gate 				if ((SWAP_16(typ2->map2_pl) != 32) ||
7080Sstevel@tonic-gate 						(typ2->map2_nst < 1) ||
7090Sstevel@tonic-gate 						(typ2->map2_nst > 4)) {
7100Sstevel@tonic-gate 					break;
7110Sstevel@tonic-gate 				}
7120Sstevel@tonic-gate 				m->udm_flags = UDM_MAP_SPM;
7130Sstevel@tonic-gate 				m->udm_vsn = SWAP_16(typ2->map2_vsn);
7140Sstevel@tonic-gate 				m->udm_pn = SWAP_16(typ2->map2_pn);
7150Sstevel@tonic-gate 
7160Sstevel@tonic-gate 				m->udm_plen = SWAP_16(typ2->map2_pl);
7170Sstevel@tonic-gate 				m->udm_nspm = typ2->map2_nst;
7180Sstevel@tonic-gate 				m->udm_spsz = SWAP_32(typ2->map2_sest);
7190Sstevel@tonic-gate 
720*2212Sartem 				mp_sz = lb_roundup(m->udm_spsz, h->udfs.lbsize);
7210Sstevel@tonic-gate 
7220Sstevel@tonic-gate 				if ((addr = malloc(mp_sz * m->udm_nspm)) ==
7230Sstevel@tonic-gate 						NULL) {
7240Sstevel@tonic-gate 					break;
7250Sstevel@tonic-gate 				}
7260Sstevel@tonic-gate 
7270Sstevel@tonic-gate 				for (i = 0; i < m->udm_nspm; i++) {
7280Sstevel@tonic-gate 					m->udm_loc[i] =
7290Sstevel@tonic-gate 						SWAP_32(typ2->map2_st[index]);
7300Sstevel@tonic-gate 					m->udm_spaddr[i] = addr + i * mp_sz;
7310Sstevel@tonic-gate 
732*2212Sartem 					off = m->udm_loc[i] * h->udfs.lbsize;
733*2212Sartem 					if (ud_read_dev(h, off,
7340Sstevel@tonic-gate 						(uint8_t *)m->udm_spaddr[i],
7350Sstevel@tonic-gate 							mp_sz) != 0) {
7360Sstevel@tonic-gate 						m->udm_spaddr[i] = NULL;
7370Sstevel@tonic-gate 						continue;
7380Sstevel@tonic-gate 					}
7390Sstevel@tonic-gate 				}
7400Sstevel@tonic-gate 			}
741*2212Sartem 			h->n_maps++;
7420Sstevel@tonic-gate 		default :
7430Sstevel@tonic-gate 			break;
7440Sstevel@tonic-gate 		}
745*2212Sartem 		ph = (struct pmap_hdr *)(((uint8_t *)h) + ph->maph_length);
7460Sstevel@tonic-gate 	}
7470Sstevel@tonic-gate 
7480Sstevel@tonic-gate 	lvds_loc = SWAP_32(lvd->lvd_int_seq_ext.ext_loc);
7490Sstevel@tonic-gate 	lvds_len = SWAP_32(lvd->lvd_int_seq_ext.ext_len);
7500Sstevel@tonic-gate 
7510Sstevel@tonic-gate 	fsd_prn = SWAP_16(lvd->lvd_lvcu.lad_ext_prn);
7520Sstevel@tonic-gate 	fsd_loc = SWAP_32(lvd->lvd_lvcu.lad_ext_loc);
7530Sstevel@tonic-gate 	fsd_len = SWAP_32(lvd->lvd_lvcu.lad_ext_len);
7540Sstevel@tonic-gate 
7550Sstevel@tonic-gate 	free(lvd);
7560Sstevel@tonic-gate 
7570Sstevel@tonic-gate 	/*
7580Sstevel@tonic-gate 	 * Get the latest LVID
7590Sstevel@tonic-gate 	 */
760*2212Sartem 	if (ud_get_latest_lvid(h, lvds_loc, lvds_len) != 0) {
7610Sstevel@tonic-gate 		return (1);
7620Sstevel@tonic-gate 	}
7630Sstevel@tonic-gate 
764*2212Sartem 	if (ud_get_latest_fsd(h, fsd_prn, fsd_loc, fsd_len) != 0) {
7650Sstevel@tonic-gate 		return (1);
7660Sstevel@tonic-gate 	}
7670Sstevel@tonic-gate 
7680Sstevel@tonic-gate 	return (0);
7690Sstevel@tonic-gate }
7700Sstevel@tonic-gate 
771*2212Sartem static int32_t
ud_get_latest_lvid(ud_handle_t h,uint32_t lvds_loc,uint32_t lvds_len)772*2212Sartem ud_get_latest_lvid(ud_handle_t h, uint32_t lvds_loc, uint32_t lvds_len)
7730Sstevel@tonic-gate {
7740Sstevel@tonic-gate 	uint8_t *addr, *taddr, *eaddr;
7750Sstevel@tonic-gate 	uint16_t id;
7760Sstevel@tonic-gate 	uint64_t off;
7770Sstevel@tonic-gate 	struct tag *tag;
7780Sstevel@tonic-gate 	struct log_vol_int_desc *lvid;
7790Sstevel@tonic-gate 
7800Sstevel@tonic-gate begin:
7810Sstevel@tonic-gate 	if ((addr = (uint8_t *)malloc(lvds_len)) == NULL) {
7820Sstevel@tonic-gate 		return (1);
7830Sstevel@tonic-gate 	}
7840Sstevel@tonic-gate 
785*2212Sartem 	off = lvds_loc * h->udfs.lbsize;
786*2212Sartem 	if (ud_read_dev(h, off, addr, lvds_len) != 0) {
7870Sstevel@tonic-gate 		goto end;
7880Sstevel@tonic-gate 	}
7890Sstevel@tonic-gate 
790*2212Sartem 	for (taddr = addr, eaddr = addr + h->udfs.mvds_len; taddr < eaddr;
791*2212Sartem 			taddr += h->udfs.lbsize, lvds_loc ++) {
7920Sstevel@tonic-gate 
7930Sstevel@tonic-gate 		/* LINTED */
7940Sstevel@tonic-gate 		tag = (struct tag *)taddr;
7950Sstevel@tonic-gate 		id = SWAP_16(tag->tag_id);
7960Sstevel@tonic-gate 		/*
7970Sstevel@tonic-gate 		 * If you cannot verify the tag just skip it
7980Sstevel@tonic-gate 		 * This is not a fatal error
7990Sstevel@tonic-gate 		 */
800*2212Sartem 		if (ud_verify_tag(h, tag, id, lvds_loc, 1, 0) != 0) {
8010Sstevel@tonic-gate 			continue;
8020Sstevel@tonic-gate 		}
8030Sstevel@tonic-gate 		switch (id) {
8040Sstevel@tonic-gate 		case UD_LOG_VOL_INT :
8050Sstevel@tonic-gate 
8060Sstevel@tonic-gate 			/*
8070Sstevel@tonic-gate 			 * Logical Volume Integrity Descriptor
8080Sstevel@tonic-gate 			 */
8090Sstevel@tonic-gate 			/* LINTED */
8100Sstevel@tonic-gate 			lvid = (struct log_vol_int_desc *)taddr;
811*2212Sartem 			h->udfs.lvid_loc = lvds_loc;
812*2212Sartem 			h->udfs.lvid_len = ((uint32_t)
8130Sstevel@tonic-gate 			&((struct log_vol_int_desc *)0)->lvid_fst) +
8140Sstevel@tonic-gate 				SWAP_32(lvid->lvid_npart) * 8 +
8150Sstevel@tonic-gate 				SWAP_32(lvid->lvid_liu);
816*2212Sartem 			h->udfs.lvid_len = lb_roundup(h->udfs.lvid_len,
817*2212Sartem 				h->udfs.lbsize);
8180Sstevel@tonic-gate 
8190Sstevel@tonic-gate 			/*
8200Sstevel@tonic-gate 			 * It seems we have a next integrity
8210Sstevel@tonic-gate 			 * sequence
8220Sstevel@tonic-gate 			 */
8230Sstevel@tonic-gate 			if (SWAP_32(lvid->lvid_nie.ext_len) != 0) {
8240Sstevel@tonic-gate 				free(addr);
8250Sstevel@tonic-gate 				lvds_loc = SWAP_32(lvid->lvid_nie.ext_loc);
8260Sstevel@tonic-gate 				lvds_len = SWAP_32(lvid->lvid_nie.ext_len);
8270Sstevel@tonic-gate 				goto begin;
8280Sstevel@tonic-gate 			}
8290Sstevel@tonic-gate 			goto end;
8300Sstevel@tonic-gate 		case UD_TERM_DESC :
8310Sstevel@tonic-gate 
8320Sstevel@tonic-gate 			/*
8330Sstevel@tonic-gate 			 * Success fully completed
8340Sstevel@tonic-gate 			 */
8350Sstevel@tonic-gate 				goto end;
8360Sstevel@tonic-gate 		default :
8370Sstevel@tonic-gate 			/*
8380Sstevel@tonic-gate 			 * If you donot undetstand any tag just skip
8390Sstevel@tonic-gate 			 * it. This is not a fatal error
8400Sstevel@tonic-gate 			 */
8410Sstevel@tonic-gate 			break;
8420Sstevel@tonic-gate 		}
8430Sstevel@tonic-gate 	}
8440Sstevel@tonic-gate end:
8450Sstevel@tonic-gate 	free(addr);
846*2212Sartem 	if (h->udfs.lvid_len == 0) {
8470Sstevel@tonic-gate 		return (1);
8480Sstevel@tonic-gate 	}
8490Sstevel@tonic-gate 	return (0);
8500Sstevel@tonic-gate }
8510Sstevel@tonic-gate 
852*2212Sartem static int32_t
ud_get_latest_fsd(ud_handle_t h,uint16_t fsd_prn,uint32_t fsd_loc,uint32_t fsd_len)853*2212Sartem ud_get_latest_fsd(ud_handle_t h, uint16_t fsd_prn,
8540Sstevel@tonic-gate 	uint32_t fsd_loc, uint32_t fsd_len)
8550Sstevel@tonic-gate {
8560Sstevel@tonic-gate 	uint8_t *addr, *taddr, *eaddr;
8570Sstevel@tonic-gate 	uint16_t id;
8580Sstevel@tonic-gate 	uint64_t off;
8590Sstevel@tonic-gate 	uint32_t fsds_loc, fsds_len;
8600Sstevel@tonic-gate 	struct tag *tag;
8610Sstevel@tonic-gate 	struct file_set_desc *fsd;
8620Sstevel@tonic-gate 	uint32_t old_fsn = 0;
8630Sstevel@tonic-gate 
8640Sstevel@tonic-gate begin:
865*2212Sartem 	h->udfs.fsds_prn = fsd_prn;
866*2212Sartem 	h->udfs.fsds_loc = fsd_loc;
867*2212Sartem 	h->udfs.fsds_len = fsd_len;
8680Sstevel@tonic-gate 
869*2212Sartem 	fsds_loc = ud_xlate_to_daddr(h, fsd_prn, fsd_loc);
870*2212Sartem 	fsds_len = lb_roundup(fsd_len, h->udfs.lbsize);
8710Sstevel@tonic-gate 
8720Sstevel@tonic-gate 	if ((addr = (uint8_t *)malloc(fsds_len)) == NULL) {
8730Sstevel@tonic-gate 		return (1);
8740Sstevel@tonic-gate 	}
8750Sstevel@tonic-gate 
876*2212Sartem 	off = fsds_loc * h->udfs.lbsize;
877*2212Sartem 	if (ud_read_dev(h, off, addr, fsds_len) != 0) {
8780Sstevel@tonic-gate 		goto end;
8790Sstevel@tonic-gate 	}
8800Sstevel@tonic-gate 
881*2212Sartem 	for (taddr = addr, eaddr = addr + h->udfs.mvds_len; taddr < eaddr;
882*2212Sartem 			taddr += h->udfs.lbsize, fsds_loc ++) {
8830Sstevel@tonic-gate 
8840Sstevel@tonic-gate 		/* LINTED */
8850Sstevel@tonic-gate 		tag = (struct tag *)taddr;
8860Sstevel@tonic-gate 		id = SWAP_16(tag->tag_id);
8870Sstevel@tonic-gate 		/*
8880Sstevel@tonic-gate 		 * If you cannot verify the tag just skip it
8890Sstevel@tonic-gate 		 * This is not a fatal error
8900Sstevel@tonic-gate 		 */
891*2212Sartem 		if (ud_verify_tag(h, tag, id, fsds_loc, 1, 0) != 0) {
8920Sstevel@tonic-gate 			continue;
8930Sstevel@tonic-gate 		}
8940Sstevel@tonic-gate 		switch (id) {
8950Sstevel@tonic-gate 		case UD_FILE_SET_DESC :
8960Sstevel@tonic-gate 			/* LINTED */
8970Sstevel@tonic-gate 			fsd = (struct file_set_desc *)taddr;
898*2212Sartem 			if ((h->udfs.fsd_len == 0) ||
8990Sstevel@tonic-gate 				(SWAP_32(fsd->fsd_fs_no) > old_fsn)) {
9000Sstevel@tonic-gate 				old_fsn = SWAP_32(fsd->fsd_fs_no);
901*2212Sartem 				h->udfs.fsd_loc = fsds_loc;
902*2212Sartem 				h->udfs.fsd_len = lb_roundup(512,
903*2212Sartem 					h->udfs.lbsize);
904*2212Sartem 				h->udfs.ricb_prn =
9050Sstevel@tonic-gate 					SWAP_16(fsd->fsd_root_icb.lad_ext_prn);
906*2212Sartem 				h->udfs.ricb_loc =
9070Sstevel@tonic-gate 					SWAP_32(fsd->fsd_root_icb.lad_ext_loc);
908*2212Sartem 				h->udfs.ricb_len =
9090Sstevel@tonic-gate 					SWAP_32(fsd->fsd_root_icb.lad_ext_len);
9100Sstevel@tonic-gate 			}
9110Sstevel@tonic-gate 			if (SWAP_32(fsd->fsd_next.lad_ext_len) != 0) {
9120Sstevel@tonic-gate 				fsd_prn = SWAP_16(fsd->fsd_next.lad_ext_prn);
9130Sstevel@tonic-gate 				fsd_loc = SWAP_32(fsd->fsd_next.lad_ext_loc);
9140Sstevel@tonic-gate 				fsd_len = SWAP_32(fsd->fsd_next.lad_ext_len);
9150Sstevel@tonic-gate 				goto begin;
9160Sstevel@tonic-gate 			}
9170Sstevel@tonic-gate 			break;
9180Sstevel@tonic-gate 		case UD_TERM_DESC :
9190Sstevel@tonic-gate 
9200Sstevel@tonic-gate 			/*
9210Sstevel@tonic-gate 			 * Success fully completed
9220Sstevel@tonic-gate 			 */
9230Sstevel@tonic-gate 			goto end;
9240Sstevel@tonic-gate 		default :
9250Sstevel@tonic-gate 			/*
9260Sstevel@tonic-gate 			 * If you donot undetstand any tag just skip
9270Sstevel@tonic-gate 			 * it. This is not a fatal error
9280Sstevel@tonic-gate 			 */
9290Sstevel@tonic-gate 			break;
9300Sstevel@tonic-gate 		}
9310Sstevel@tonic-gate 	}
9320Sstevel@tonic-gate 
9330Sstevel@tonic-gate end:
9340Sstevel@tonic-gate 	free(addr);
935*2212Sartem 	if (h->udfs.fsd_len == 0) {
9360Sstevel@tonic-gate 		return (1);
9370Sstevel@tonic-gate 	}
9380Sstevel@tonic-gate 	return (0);
9390Sstevel@tonic-gate }
9400Sstevel@tonic-gate 
9410Sstevel@tonic-gate int32_t
ud_get_num_blks(ud_handle_t h,uint32_t * blkno)942*2212Sartem ud_get_num_blks(ud_handle_t h, uint32_t *blkno)
9430Sstevel@tonic-gate {
9440Sstevel@tonic-gate 	struct vtoc vtoc;
9450Sstevel@tonic-gate 	struct dk_cinfo dki_info;
9460Sstevel@tonic-gate 	int32_t error;
9470Sstevel@tonic-gate 
9480Sstevel@tonic-gate 	/*
9490Sstevel@tonic-gate 	 * Get VTOC from driver
9500Sstevel@tonic-gate 	 */
951*2212Sartem 	if ((error = ioctl(h->fd, DKIOCGVTOC, (intptr_t)&vtoc)) != 0) {
9520Sstevel@tonic-gate 		return (error);
9530Sstevel@tonic-gate 	}
9540Sstevel@tonic-gate 
9550Sstevel@tonic-gate 	/*
9560Sstevel@tonic-gate 	 * Verify if is proper
9570Sstevel@tonic-gate 	 */
9580Sstevel@tonic-gate 	if (vtoc.v_sanity != VTOC_SANE) {
9590Sstevel@tonic-gate 		return (EINVAL);
9600Sstevel@tonic-gate 	}
9610Sstevel@tonic-gate 
9620Sstevel@tonic-gate 	/*
9630Sstevel@tonic-gate 	 * Get dk_cinfo from driver
9640Sstevel@tonic-gate 	 */
965*2212Sartem 	if ((error = ioctl(h->fd, DKIOCINFO, (intptr_t)&dki_info)) != 0) {
9660Sstevel@tonic-gate 		return (error);
9670Sstevel@tonic-gate 	}
9680Sstevel@tonic-gate 
9690Sstevel@tonic-gate 	if (dki_info.dki_partition >= V_NUMPAR) {
9700Sstevel@tonic-gate 		return (EINVAL);
9710Sstevel@tonic-gate 	}
9720Sstevel@tonic-gate 
9730Sstevel@tonic-gate 	/*
9740Sstevel@tonic-gate 	 * Return the size of the partition
9750Sstevel@tonic-gate 	 */
9760Sstevel@tonic-gate 	*blkno = vtoc.v_part[dki_info.dki_partition].p_size;
9770Sstevel@tonic-gate 
9780Sstevel@tonic-gate 	return (0);
9790Sstevel@tonic-gate }
9800Sstevel@tonic-gate 
9810Sstevel@tonic-gate uint32_t
ud_xlate_to_daddr(ud_handle_t h,uint16_t prn,uint32_t blkno)982*2212Sartem ud_xlate_to_daddr(ud_handle_t h, uint16_t prn, uint32_t blkno)
9830Sstevel@tonic-gate {
9840Sstevel@tonic-gate 	int32_t i;
9850Sstevel@tonic-gate 	struct ud_map *m;
9860Sstevel@tonic-gate 	struct ud_part *p;
9870Sstevel@tonic-gate 
9880Sstevel@tonic-gate 
989*2212Sartem 	if (prn < h->n_maps) {
990*2212Sartem 		m = &h->maps[prn];
991*2212Sartem 		for (i = 0; i < h->n_parts; i++) {
992*2212Sartem 			p = &h->part[i];
9930Sstevel@tonic-gate 			if (m->udm_pn == p->udp_number) {
9940Sstevel@tonic-gate 				return (p->udp_start + blkno);
9950Sstevel@tonic-gate 			}
9960Sstevel@tonic-gate 		}
9970Sstevel@tonic-gate 	}
9980Sstevel@tonic-gate 	return (0);
9990Sstevel@tonic-gate }
10000Sstevel@tonic-gate 
10010Sstevel@tonic-gate /* ------ END Read and translate the on disk VDS to IN CORE format -------- */
10020Sstevel@tonic-gate 
10030Sstevel@tonic-gate int32_t
ud_verify_tag(ud_handle_t h,struct tag * tag,uint16_t id,uint32_t blockno,int32_t do_crc,int32_t print_msg)1004*2212Sartem ud_verify_tag(ud_handle_t h, struct tag *tag, uint16_t id,
10050Sstevel@tonic-gate 	uint32_t blockno, int32_t do_crc, int32_t print_msg)
10060Sstevel@tonic-gate {
10070Sstevel@tonic-gate 	int32_t i;
10080Sstevel@tonic-gate 	uint8_t *addr, cksum = 0;
10090Sstevel@tonic-gate 	uint16_t crc;
10100Sstevel@tonic-gate 
10110Sstevel@tonic-gate 
10120Sstevel@tonic-gate 	/*
10130Sstevel@tonic-gate 	 * Verify Tag Identifier
10140Sstevel@tonic-gate 	 */
10150Sstevel@tonic-gate 	if (tag->tag_id != SWAP_16(id)) {
10160Sstevel@tonic-gate 		if (print_msg != 0) {
1017*2212Sartem 			(void) fprintf(stderr,
10180Sstevel@tonic-gate 				gettext("tag does not verify tag %x req %x\n"),
10190Sstevel@tonic-gate 				SWAP_16(tag->tag_id), id);
10200Sstevel@tonic-gate 		}
10210Sstevel@tonic-gate 		return (1);
10220Sstevel@tonic-gate 	}
10230Sstevel@tonic-gate 
10240Sstevel@tonic-gate 	/*
10250Sstevel@tonic-gate 	 * Verify Tag Descriptor Version
10260Sstevel@tonic-gate 	 */
1027*2212Sartem 	if (SWAP_16(tag->tag_desc_ver) != h->udfs.ecma_version) {
10280Sstevel@tonic-gate 		if (print_msg != 0) {
1029*2212Sartem 			(void) fprintf(stderr,
10300Sstevel@tonic-gate 				gettext("tag version does not match with "
10310Sstevel@tonic-gate 				"NSR descriptor version TAG %x NSR %x\n"),
1032*2212Sartem 				SWAP_16(tag->tag_desc_ver),
1033*2212Sartem 				h->udfs.ecma_version);
10340Sstevel@tonic-gate 		}
10350Sstevel@tonic-gate 		return (1);
10360Sstevel@tonic-gate 	}
10370Sstevel@tonic-gate 
10380Sstevel@tonic-gate 	/*
10390Sstevel@tonic-gate 	 * Caliculate Tag Checksum
10400Sstevel@tonic-gate 	 */
10410Sstevel@tonic-gate 	addr = (uint8_t *)tag;
10420Sstevel@tonic-gate 	for (i = 0; i <= 15; i++) {
10430Sstevel@tonic-gate 		if (i != 4) {
10440Sstevel@tonic-gate 			cksum += addr[i];
10450Sstevel@tonic-gate 		}
10460Sstevel@tonic-gate 	}
10470Sstevel@tonic-gate 
10480Sstevel@tonic-gate 	/*
10490Sstevel@tonic-gate 	 * Verify Tag Checksum
10500Sstevel@tonic-gate 	 */
10510Sstevel@tonic-gate 	if (cksum != tag->tag_cksum) {
10520Sstevel@tonic-gate 		if (print_msg != 0) {
1053*2212Sartem 			(void) fprintf(stderr,
10540Sstevel@tonic-gate 				gettext("Checksum Does not Verify TAG"
10550Sstevel@tonic-gate 				" %x CALC %x\n"), tag->tag_cksum, cksum);
10560Sstevel@tonic-gate 		}
10570Sstevel@tonic-gate 		return (1);
10580Sstevel@tonic-gate 	}
10590Sstevel@tonic-gate 
10600Sstevel@tonic-gate 
10610Sstevel@tonic-gate 	/*
10620Sstevel@tonic-gate 	 * Do we want to do crc
10630Sstevel@tonic-gate 	 */
10640Sstevel@tonic-gate 	if (do_crc) {
10650Sstevel@tonic-gate 		if (tag->tag_crc_len) {
10660Sstevel@tonic-gate 
10670Sstevel@tonic-gate 			/*
10680Sstevel@tonic-gate 			 * Caliculate CRC for the descriptor
10690Sstevel@tonic-gate 			 */
10700Sstevel@tonic-gate 			crc = ud_crc(addr + 0x10, SWAP_16(tag->tag_crc_len));
10710Sstevel@tonic-gate 
10720Sstevel@tonic-gate 			/*
10730Sstevel@tonic-gate 			 * Verify CRC
10740Sstevel@tonic-gate 			 */
10750Sstevel@tonic-gate 			if (crc != SWAP_16(tag->tag_crc)) {
10760Sstevel@tonic-gate 				if (print_msg != 0) {
1077*2212Sartem 					(void) fprintf(stderr,
10780Sstevel@tonic-gate 						gettext("CRC Does not verify"
10790Sstevel@tonic-gate 						" TAG %x CALC %x %x\n"),
10800Sstevel@tonic-gate 						SWAP_16(tag->tag_crc),
10810Sstevel@tonic-gate 						crc, addr);
10820Sstevel@tonic-gate 				}
10830Sstevel@tonic-gate 			}
10840Sstevel@tonic-gate 		}
10850Sstevel@tonic-gate 
10860Sstevel@tonic-gate 		/*
10870Sstevel@tonic-gate 		 * Verify Tag Location
10880Sstevel@tonic-gate 		 */
10890Sstevel@tonic-gate 		if (SWAP_32(blockno) != tag->tag_loc) {
10900Sstevel@tonic-gate 			if (print_msg != 0) {
1091*2212Sartem 				(void) fprintf(stderr,
10920Sstevel@tonic-gate 					gettext("Tag Location Does not verify"
10930Sstevel@tonic-gate 					" blockno %x tag_blockno %x\n"),
10940Sstevel@tonic-gate 					blockno, SWAP_32(tag->tag_loc));
10950Sstevel@tonic-gate 			}
10960Sstevel@tonic-gate 		}
10970Sstevel@tonic-gate 	}
10980Sstevel@tonic-gate 
10990Sstevel@tonic-gate 	return (0);
11000Sstevel@tonic-gate }
11010Sstevel@tonic-gate 
11020Sstevel@tonic-gate 
11030Sstevel@tonic-gate /* ARGSUSED1 */
11040Sstevel@tonic-gate void
ud_make_tag(ud_handle_t h,struct tag * tag,uint16_t tag_id,uint32_t blkno,uint16_t crc_len)1105*2212Sartem ud_make_tag(ud_handle_t h, struct tag *tag, uint16_t tag_id,
11060Sstevel@tonic-gate 	uint32_t blkno, uint16_t crc_len)
11070Sstevel@tonic-gate {
11080Sstevel@tonic-gate 	int32_t i;
11090Sstevel@tonic-gate 	uint16_t crc;
11100Sstevel@tonic-gate 	uint8_t *addr, cksum = 0;
11110Sstevel@tonic-gate 
11120Sstevel@tonic-gate 	tag->tag_id = SWAP_16(tag_id);
1113*2212Sartem 	tag->tag_desc_ver = SWAP_16(h->udfs.ecma_version);
11140Sstevel@tonic-gate 	tag->tag_cksum = 0;
11150Sstevel@tonic-gate 	tag->tag_res = 0;
11160Sstevel@tonic-gate 
11170Sstevel@tonic-gate 	/*
11180Sstevel@tonic-gate 	 * Calicualte and assign CRC, CRC_LEN
11190Sstevel@tonic-gate 	 */
11200Sstevel@tonic-gate 	addr = (uint8_t *)tag;
11210Sstevel@tonic-gate 	crc = ud_crc(addr + 0x10, crc_len);
11220Sstevel@tonic-gate 	tag->tag_crc = SWAP_16(crc);
11230Sstevel@tonic-gate 	tag->tag_crc_len = SWAP_16(crc_len);
11240Sstevel@tonic-gate 	tag->tag_loc = SWAP_32(blkno);
11250Sstevel@tonic-gate 
11260Sstevel@tonic-gate 	/*
11270Sstevel@tonic-gate 	 * Caliculate Checksum
11280Sstevel@tonic-gate 	 */
11290Sstevel@tonic-gate 	for (i = 0; i <= 15; i++) {
11300Sstevel@tonic-gate 		cksum += addr[i];
11310Sstevel@tonic-gate 	}
11320Sstevel@tonic-gate 
11330Sstevel@tonic-gate 	/*
11340Sstevel@tonic-gate 	 * Assign Checksum
11350Sstevel@tonic-gate 	 */
11360Sstevel@tonic-gate 	tag->tag_cksum = cksum;
11370Sstevel@tonic-gate }
11380Sstevel@tonic-gate 
11390Sstevel@tonic-gate /* **************** udf specific subroutines *********************** */
11400Sstevel@tonic-gate 
1141*2212Sartem static uint16_t ud_crc_table[256] = {
11420Sstevel@tonic-gate 	0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
11430Sstevel@tonic-gate 	0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
11440Sstevel@tonic-gate 	0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
11450Sstevel@tonic-gate 	0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
11460Sstevel@tonic-gate 	0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
11470Sstevel@tonic-gate 	0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
11480Sstevel@tonic-gate 	0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
11490Sstevel@tonic-gate 	0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
11500Sstevel@tonic-gate 	0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
11510Sstevel@tonic-gate 	0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
11520Sstevel@tonic-gate 	0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
11530Sstevel@tonic-gate 	0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
11540Sstevel@tonic-gate 	0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
11550Sstevel@tonic-gate 	0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
11560Sstevel@tonic-gate 	0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
11570Sstevel@tonic-gate 	0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
11580Sstevel@tonic-gate 	0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
11590Sstevel@tonic-gate 	0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
11600Sstevel@tonic-gate 	0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
11610Sstevel@tonic-gate 	0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
11620Sstevel@tonic-gate 	0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
11630Sstevel@tonic-gate 	0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
11640Sstevel@tonic-gate 	0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
11650Sstevel@tonic-gate 	0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
11660Sstevel@tonic-gate 	0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
11670Sstevel@tonic-gate 	0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
11680Sstevel@tonic-gate 	0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
11690Sstevel@tonic-gate 	0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
11700Sstevel@tonic-gate 	0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
11710Sstevel@tonic-gate 	0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
11720Sstevel@tonic-gate 	0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
11730Sstevel@tonic-gate 	0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
11740Sstevel@tonic-gate };
11750Sstevel@tonic-gate 
1176*2212Sartem static uint16_t
ud_crc(uint8_t * addr,int32_t len)11770Sstevel@tonic-gate ud_crc(uint8_t *addr, int32_t len)
11780Sstevel@tonic-gate {
11790Sstevel@tonic-gate 	uint16_t crc = 0;
11800Sstevel@tonic-gate 
11810Sstevel@tonic-gate 	while (len-- > 0) {
11820Sstevel@tonic-gate 		crc = ud_crc_table[(crc >> 8 ^ *addr++) & 0xff] ^ (crc<<8);
11830Sstevel@tonic-gate 	}
11840Sstevel@tonic-gate 
11850Sstevel@tonic-gate 	return (crc);
11860Sstevel@tonic-gate }
11870Sstevel@tonic-gate 
11880Sstevel@tonic-gate #define	MAXNAMLEN	0x200
11890Sstevel@tonic-gate 
11900Sstevel@tonic-gate 
11910Sstevel@tonic-gate #define	POUND		0x0023
11920Sstevel@tonic-gate #define	DOT		0x002E
11930Sstevel@tonic-gate #define	SLASH		0x002F
11940Sstevel@tonic-gate #define	UNDERBAR	0x005F
11950Sstevel@tonic-gate 
11960Sstevel@tonic-gate 
11970Sstevel@tonic-gate static uint16_t htoc[16] = {'0', '1', '2', '3',
11980Sstevel@tonic-gate 	'4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
11990Sstevel@tonic-gate /*
12000Sstevel@tonic-gate  * unicode is the string of 16-bot characters
12010Sstevel@tonic-gate  * length is the number of 16-bit characters
12020Sstevel@tonic-gate  */
1203*2212Sartem static int32_t
UdfTxName(uint16_t * unicode,int32_t count)12040Sstevel@tonic-gate UdfTxName(uint16_t *unicode, int32_t count)
12050Sstevel@tonic-gate {
12060Sstevel@tonic-gate 	int32_t i, j, k, lic, make_crc, dot_loc;
12070Sstevel@tonic-gate 	uint16_t crc;
12080Sstevel@tonic-gate 
12090Sstevel@tonic-gate 	if ((unicode[0] == DOT) &&
12100Sstevel@tonic-gate 		((count == 1) || ((count == 2) && (unicode[1] == DOT)))) {
12110Sstevel@tonic-gate 		crc = DOT;
12120Sstevel@tonic-gate 		if (count == 2) {
12130Sstevel@tonic-gate 			crc += DOT;
12140Sstevel@tonic-gate 		}
12150Sstevel@tonic-gate 		unicode[0] = UNDERBAR;
12160Sstevel@tonic-gate 		unicode[1] = POUND;
12170Sstevel@tonic-gate 		unicode[2] = htoc[(uint16_t)(crc & 0xf000) >> 12];
12180Sstevel@tonic-gate 		unicode[3] = htoc[(uint16_t)(crc & 0xf00) >> 8];
12190Sstevel@tonic-gate 		unicode[4] = htoc[(uint16_t)(crc & 0xf0) >> 4];
12200Sstevel@tonic-gate 		unicode[5] = htoc[crc & 0xf];
12210Sstevel@tonic-gate 		return (6);
12220Sstevel@tonic-gate 	}
12230Sstevel@tonic-gate 	crc = 0;
12240Sstevel@tonic-gate 	j = make_crc = 0;
12250Sstevel@tonic-gate 	lic = dot_loc = -1;
12260Sstevel@tonic-gate 	for (i = 0; i < count; i++) {
12270Sstevel@tonic-gate 		if (make_crc) {
12280Sstevel@tonic-gate 			crc += unicode[i];
12290Sstevel@tonic-gate 		}
12300Sstevel@tonic-gate 		if (unicode[i] == DOT) {
12310Sstevel@tonic-gate 			dot_loc = j;
12320Sstevel@tonic-gate 		}
12330Sstevel@tonic-gate 		if ((unicode[i] == SLASH) ||
12340Sstevel@tonic-gate 			(unicode[i] == NULL)) {
12350Sstevel@tonic-gate 			if (make_crc == 0) {
12360Sstevel@tonic-gate 				for (k = 0; k <= i; k++) {
12370Sstevel@tonic-gate 					crc += unicode[k];
12380Sstevel@tonic-gate 				}
12390Sstevel@tonic-gate 				make_crc = 1;
12400Sstevel@tonic-gate 			}
12410Sstevel@tonic-gate 			if (lic != (i - 1)) {
12420Sstevel@tonic-gate 				unicode[j++] = UNDERBAR;
12430Sstevel@tonic-gate 			}
12440Sstevel@tonic-gate 			lic = i;
12450Sstevel@tonic-gate 		} else {
12460Sstevel@tonic-gate 			unicode[j++] = unicode[i];
12470Sstevel@tonic-gate 		}
12480Sstevel@tonic-gate 	}
12490Sstevel@tonic-gate 
12500Sstevel@tonic-gate 	if (make_crc) {
12510Sstevel@tonic-gate 		if (dot_loc != -1) {
12520Sstevel@tonic-gate 			if ((j + 5) > MAXNAMLEN) {
12530Sstevel@tonic-gate 				if ((j - dot_loc + 5) > MAXNAMLEN) {
12540Sstevel@tonic-gate 					j = MAXNAMLEN - 5 + dot_loc;
12550Sstevel@tonic-gate 					for (k = MAXNAMLEN;
12560Sstevel@tonic-gate 						j >= dot_loc; k --, j--) {
12570Sstevel@tonic-gate 						unicode[k] = unicode[j];
12580Sstevel@tonic-gate 					}
12590Sstevel@tonic-gate 					k = 0;
12600Sstevel@tonic-gate 				} else {
12610Sstevel@tonic-gate 					for (k = MAXNAMLEN;
12620Sstevel@tonic-gate 						j >= dot_loc; k--, j--) {
12630Sstevel@tonic-gate 						unicode[k] = unicode[j];
12640Sstevel@tonic-gate 					}
12650Sstevel@tonic-gate 					k -= 4;
12660Sstevel@tonic-gate 				}
12670Sstevel@tonic-gate 				j = MAXNAMLEN;
12680Sstevel@tonic-gate 			} else {
12690Sstevel@tonic-gate 				for (k = j; k >= dot_loc; k--) {
12700Sstevel@tonic-gate 					unicode[k + 5] = unicode[k];
12710Sstevel@tonic-gate 				}
12720Sstevel@tonic-gate 				k = dot_loc;
12730Sstevel@tonic-gate 				j += 5;
12740Sstevel@tonic-gate 			}
12750Sstevel@tonic-gate 		} else {
12760Sstevel@tonic-gate 			if ((j + 5) > MAXNAMLEN) {
12770Sstevel@tonic-gate 				j = MAXNAMLEN;
12780Sstevel@tonic-gate 				k = MAXNAMLEN - 5;
12790Sstevel@tonic-gate 			} else {
12800Sstevel@tonic-gate 				k = j;
12810Sstevel@tonic-gate 				j += 5;
12820Sstevel@tonic-gate 			}
12830Sstevel@tonic-gate 		}
12840Sstevel@tonic-gate 		unicode[k++] = POUND;
12850Sstevel@tonic-gate 		unicode[k++] = htoc[(uint16_t)(crc & 0xf000) >> 12];
12860Sstevel@tonic-gate 		unicode[k++] = htoc[(uint16_t)(crc & 0xf00) >> 8];
12870Sstevel@tonic-gate 		unicode[k++] = htoc[(uint16_t)(crc & 0xf0) >> 4];
12880Sstevel@tonic-gate 		unicode[k++] = htoc[crc & 0xf];
12890Sstevel@tonic-gate 	}
12900Sstevel@tonic-gate 	return (j);
12910Sstevel@tonic-gate }
12920Sstevel@tonic-gate 
12930Sstevel@tonic-gate /*
12940Sstevel@tonic-gate  * Assumes the output buffer is large
12950Sstevel@tonic-gate  * enough to hold the uncompressed
12960Sstevel@tonic-gate  * code
12970Sstevel@tonic-gate  */
1298*2212Sartem static int32_t
UncompressUnicode(int32_t numberOfBytes,uint8_t * UDFCompressed,uint16_t * unicode)12990Sstevel@tonic-gate UncompressUnicode(
13000Sstevel@tonic-gate 	int32_t numberOfBytes,	/* (Input) number of bytes read from media. */
13010Sstevel@tonic-gate 	uint8_t *UDFCompressed,	/* (Input) bytes read from media. */
13020Sstevel@tonic-gate 	uint16_t *unicode)	/* (Output) uncompressed unicode characters. */
13030Sstevel@tonic-gate {
13040Sstevel@tonic-gate 	int32_t compID;
13050Sstevel@tonic-gate 	int32_t returnValue, unicodeIndex, byteIndex;
13060Sstevel@tonic-gate 
13070Sstevel@tonic-gate 
13080Sstevel@tonic-gate 	/*
13090Sstevel@tonic-gate 	 * Use UDFCompressed to store current byte being read.
13100Sstevel@tonic-gate 	 */
13110Sstevel@tonic-gate 	compID = UDFCompressed[0];
13120Sstevel@tonic-gate 
13130Sstevel@tonic-gate 	/* First check for valid compID. */
13140Sstevel@tonic-gate 	if (compID != 8 && compID != 16) {
13150Sstevel@tonic-gate 		returnValue = -1;
13160Sstevel@tonic-gate 	} else {
13170Sstevel@tonic-gate 		unicodeIndex = 0;
13180Sstevel@tonic-gate 		byteIndex = 1;
13190Sstevel@tonic-gate 
13200Sstevel@tonic-gate 		/* Loop through all the bytes. */
13210Sstevel@tonic-gate 		while (byteIndex < numberOfBytes) {
13220Sstevel@tonic-gate 			if (compID == 16) {
13230Sstevel@tonic-gate 				/*
13240Sstevel@tonic-gate 				 * Move the first byte to the
13250Sstevel@tonic-gate 				 * high bits of the unicode char.
13260Sstevel@tonic-gate 				 */
13270Sstevel@tonic-gate 				unicode[unicodeIndex] =
13280Sstevel@tonic-gate 					UDFCompressed[byteIndex++] << 8;
13290Sstevel@tonic-gate 			} else {
13300Sstevel@tonic-gate 				unicode[unicodeIndex] = 0;
13310Sstevel@tonic-gate 			}
13320Sstevel@tonic-gate 			if (byteIndex < numberOfBytes) {
13330Sstevel@tonic-gate 				/*
13340Sstevel@tonic-gate 				 * Then the next byte to the low bits.
13350Sstevel@tonic-gate 				 */
13360Sstevel@tonic-gate 				unicode[unicodeIndex] |=
13370Sstevel@tonic-gate 					UDFCompressed[byteIndex++];
13380Sstevel@tonic-gate 			}
13390Sstevel@tonic-gate 			unicodeIndex++;
13400Sstevel@tonic-gate 		}
13410Sstevel@tonic-gate 		returnValue = unicodeIndex;
13420Sstevel@tonic-gate 	}
13430Sstevel@tonic-gate 	return (returnValue);
13440Sstevel@tonic-gate }
13450Sstevel@tonic-gate 
13460Sstevel@tonic-gate 
13470Sstevel@tonic-gate 
13480Sstevel@tonic-gate 
13490Sstevel@tonic-gate 
1350*2212Sartem static int32_t
ud_compressunicode(int32_t numberOfChars,int32_t compID,uint16_t * unicode,uint8_t * UDFCompressed)13510Sstevel@tonic-gate ud_compressunicode(
13520Sstevel@tonic-gate 	int32_t numberOfChars,	/* (Input) number of unicode characters. */
13530Sstevel@tonic-gate 	int32_t compID,		/* (Input) compression ID to be used. */
13540Sstevel@tonic-gate 	uint16_t *unicode,	/* (Input) unicode characters to compress. */
13550Sstevel@tonic-gate 	uint8_t *UDFCompressed) /* (Output) compressed string, as bytes. */
13560Sstevel@tonic-gate {
13570Sstevel@tonic-gate 	int32_t byteIndex;
13580Sstevel@tonic-gate 
13590Sstevel@tonic-gate 	if (compID != 8 && compID != 16) {
13600Sstevel@tonic-gate 		/*
13610Sstevel@tonic-gate 		 * Unsupported compression ID !
13620Sstevel@tonic-gate 		 */
13630Sstevel@tonic-gate 		byteIndex = -1;
13640Sstevel@tonic-gate 	} else {
13650Sstevel@tonic-gate 		/*
13660Sstevel@tonic-gate 		 * Place compression code in first byte.
13670Sstevel@tonic-gate 		 */
13680Sstevel@tonic-gate 		UDFCompressed[0] = (uint8_t)compID;
13690Sstevel@tonic-gate 		(void) strncpy((caddr_t)&UDFCompressed[1],
13700Sstevel@tonic-gate 			(caddr_t)unicode, numberOfChars);
13710Sstevel@tonic-gate 		byteIndex = numberOfChars + 1;
13720Sstevel@tonic-gate 	}
13730Sstevel@tonic-gate 	return (byteIndex);
13740Sstevel@tonic-gate }
13750Sstevel@tonic-gate 
13760Sstevel@tonic-gate 
1377*2212Sartem static int32_t
ud_convert2utf8(uint8_t * ibuf,uint8_t * obuf,int32_t length)13780Sstevel@tonic-gate ud_convert2utf8(uint8_t *ibuf, uint8_t *obuf, int32_t length)
13790Sstevel@tonic-gate {
13800Sstevel@tonic-gate 	int i, size;
13810Sstevel@tonic-gate 	uint16_t *buf;
13820Sstevel@tonic-gate 
13830Sstevel@tonic-gate 	/* LINTED */
13840Sstevel@tonic-gate 	buf = (uint16_t *)obuf;
13850Sstevel@tonic-gate 
13860Sstevel@tonic-gate 	size = UncompressUnicode(length, ibuf, buf);
13870Sstevel@tonic-gate 
13880Sstevel@tonic-gate 	size = UdfTxName(buf, size);
13890Sstevel@tonic-gate 
13900Sstevel@tonic-gate 	for (i = 0; i < size; i++) {
13910Sstevel@tonic-gate 		obuf[i] = (uint8_t)buf[i];
13920Sstevel@tonic-gate 	}
13930Sstevel@tonic-gate 	obuf[i] = '\0';
13940Sstevel@tonic-gate 
13950Sstevel@tonic-gate 	return (size);
13960Sstevel@tonic-gate }
13970Sstevel@tonic-gate 
1398*2212Sartem static int32_t
ud_convert2utf16(uint8_t * ibuf,uint8_t * obuf,int32_t length)13990Sstevel@tonic-gate ud_convert2utf16(uint8_t *ibuf, uint8_t *obuf, int32_t length)
14000Sstevel@tonic-gate {
14010Sstevel@tonic-gate 	int32_t comp_len;
14020Sstevel@tonic-gate 	uint16_t *ptr;
14030Sstevel@tonic-gate 
14040Sstevel@tonic-gate 	/* LINTED */
14050Sstevel@tonic-gate 	ptr = (uint16_t *)ibuf;
14060Sstevel@tonic-gate 	comp_len = ud_compressunicode(length, 8, ptr, obuf);
14070Sstevel@tonic-gate 
14080Sstevel@tonic-gate 	return (comp_len);
14090Sstevel@tonic-gate }
14100Sstevel@tonic-gate 
14110Sstevel@tonic-gate /*
14120Sstevel@tonic-gate  * Assumption code set is zero in udfs
14130Sstevel@tonic-gate  */
14140Sstevel@tonic-gate void
ud_convert2local(int8_t * ibuf,int8_t * obuf,int32_t length)14150Sstevel@tonic-gate ud_convert2local(int8_t *ibuf, int8_t *obuf, int32_t length)
14160Sstevel@tonic-gate {
14170Sstevel@tonic-gate 	wchar_t buf4c[128];
14180Sstevel@tonic-gate 	int32_t i, comp, index;
14190Sstevel@tonic-gate 
14200Sstevel@tonic-gate 	/*
14210Sstevel@tonic-gate 	 * Special uncompress code
14220Sstevel@tonic-gate 	 * written to accomodate solaris wchar_t
14230Sstevel@tonic-gate 	 */
14240Sstevel@tonic-gate 	comp = ibuf[0];
14250Sstevel@tonic-gate 	for (i = 0, index = 1; i < length; i++) {
14260Sstevel@tonic-gate 		if (comp == 16) {
14270Sstevel@tonic-gate 			buf4c[i] = ibuf[index++] << 8;
14280Sstevel@tonic-gate 		} else {
14290Sstevel@tonic-gate 			buf4c[i] = 0;
14300Sstevel@tonic-gate 		}
14310Sstevel@tonic-gate 		if (index < length) {
14320Sstevel@tonic-gate 			buf4c[i] |= ibuf[index++];
14330Sstevel@tonic-gate 		}
14340Sstevel@tonic-gate 	}
14350Sstevel@tonic-gate 	(void) wcstombs((char *)obuf, buf4c, 128);
14360Sstevel@tonic-gate }
14370Sstevel@tonic-gate 
14380Sstevel@tonic-gate 
14390Sstevel@tonic-gate /* ------------ Routines to print basic structures Part 1 ---------------- */
14400Sstevel@tonic-gate 
14410Sstevel@tonic-gate 
14420Sstevel@tonic-gate 
14430Sstevel@tonic-gate void
print_charspec(FILE * fout,char * name,struct charspec * cspec)1444*2212Sartem print_charspec(FILE *fout, char *name, struct charspec *cspec)
14450Sstevel@tonic-gate {
14460Sstevel@tonic-gate 	int i = 0;
14470Sstevel@tonic-gate 
1448*2212Sartem 	(void) fprintf(fout,
14490Sstevel@tonic-gate 		"%s : %x - \"", name, cspec->cs_type);
14500Sstevel@tonic-gate 	for (i = 0; i < 63; i++) {
1451*2212Sartem 		(void) fprintf(fout,
14520Sstevel@tonic-gate 			"%c", cspec->cs_info[i]);
14530Sstevel@tonic-gate 	}
1454*2212Sartem 	(void) fprintf(fout, "\n");
14550Sstevel@tonic-gate }
14560Sstevel@tonic-gate 
14570Sstevel@tonic-gate /* ARGSUSED */
14580Sstevel@tonic-gate void
print_dstring(FILE * fout,char * name,uint16_t cset,char * bufc,uint8_t length)1459*2212Sartem print_dstring(FILE *fout, char *name, uint16_t cset, char *bufc, uint8_t length)
14600Sstevel@tonic-gate {
14610Sstevel@tonic-gate 	int8_t bufmb[1024];
14620Sstevel@tonic-gate 
14630Sstevel@tonic-gate 	ud_convert2local(bufc, bufmb, length);
14640Sstevel@tonic-gate 
1465*2212Sartem 	(void) fprintf(fout,
14660Sstevel@tonic-gate 		"%s %s\n", name, bufmb);
14670Sstevel@tonic-gate }
14680Sstevel@tonic-gate 
14690Sstevel@tonic-gate void
set_dstring(dstring_t * dp,char * cp,int32_t len)14700Sstevel@tonic-gate set_dstring(dstring_t *dp, char *cp, int32_t len)
14710Sstevel@tonic-gate {
14720Sstevel@tonic-gate 	int32_t length;
14730Sstevel@tonic-gate 
14740Sstevel@tonic-gate 	bzero(dp, len);
14750Sstevel@tonic-gate 	length = strlen(cp);
14760Sstevel@tonic-gate 	if (length > len - 1) {
14770Sstevel@tonic-gate 		length = len - 1;
14780Sstevel@tonic-gate 	}
14790Sstevel@tonic-gate 	(void) strncpy(dp, cp, length);
14800Sstevel@tonic-gate 	dp[len - 1] = length;
14810Sstevel@tonic-gate }
14820Sstevel@tonic-gate 
14830Sstevel@tonic-gate void
print_tstamp(FILE * fout,char * name,tstamp_t * ts)1484*2212Sartem print_tstamp(FILE *fout, char *name, tstamp_t *ts)
14850Sstevel@tonic-gate {
1486*2212Sartem 	(void) fprintf(fout, "%s tz : %d yr : %d mo : %d da : %d "
14870Sstevel@tonic-gate 		"Time : %d : %d : %d : %d : %d : %d\n", name,
14880Sstevel@tonic-gate 		SWAP_16(ts->ts_tzone), SWAP_16(ts->ts_year), ts->ts_month,
14890Sstevel@tonic-gate 		ts->ts_day, ts->ts_hour, ts->ts_min, ts->ts_sec, ts->ts_csec,
14900Sstevel@tonic-gate 		ts->ts_husec, ts->ts_usec);
14910Sstevel@tonic-gate }
14920Sstevel@tonic-gate 
14930Sstevel@tonic-gate 
14940Sstevel@tonic-gate 
14950Sstevel@tonic-gate void
make_regid(ud_handle_t h,struct regid * reg,char * id,int32_t type)1496*2212Sartem make_regid(ud_handle_t h, struct regid *reg, char *id, int32_t type)
14970Sstevel@tonic-gate {
14980Sstevel@tonic-gate 	reg->reg_flags = 0;
14990Sstevel@tonic-gate 	(void) strncpy(reg->reg_id, id, 23);
15000Sstevel@tonic-gate 
15010Sstevel@tonic-gate 	if (type == REG_DOM_ID) {
15020Sstevel@tonic-gate 		struct dom_id_suffix *dis;
15030Sstevel@tonic-gate 
15040Sstevel@tonic-gate 		/* LINTED */
15050Sstevel@tonic-gate 		dis = (struct dom_id_suffix *)reg->reg_ids;
1506*2212Sartem 		dis->dis_udf_revison = SWAP_16(h->udfs.ma_write);
15070Sstevel@tonic-gate 		dis->dis_domain_flags = 0;
15080Sstevel@tonic-gate 
15090Sstevel@tonic-gate 	} else if (type == REG_UDF_ID) {
15100Sstevel@tonic-gate 		struct udf_id_suffix *uis;
15110Sstevel@tonic-gate 
15120Sstevel@tonic-gate 		/* LINTED */
15130Sstevel@tonic-gate 		uis = (struct udf_id_suffix *)reg->reg_ids;
1514*2212Sartem 		uis->uis_udf_revision = SWAP_16(h->udfs.ma_write);
15150Sstevel@tonic-gate 		uis->uis_os_class = OS_CLASS_UNIX;
15160Sstevel@tonic-gate 		uis->uis_os_identifier = OS_IDENTIFIER_SOLARIS;
15170Sstevel@tonic-gate 	} else if (type == REG_UDF_II) {
15180Sstevel@tonic-gate 		struct impl_id_suffix *iis;
15190Sstevel@tonic-gate 
15200Sstevel@tonic-gate 		iis = (struct impl_id_suffix *)reg->reg_ids;
15210Sstevel@tonic-gate 		iis->iis_os_class = OS_CLASS_UNIX;
15220Sstevel@tonic-gate 		iis->iis_os_identifier = OS_IDENTIFIER_SOLARIS;
15230Sstevel@tonic-gate 	}
15240Sstevel@tonic-gate }
15250Sstevel@tonic-gate 
15260Sstevel@tonic-gate void
print_regid(FILE * fout,char * name,struct regid * reg,int32_t type)1527*2212Sartem print_regid(FILE *fout, char *name, struct regid *reg, int32_t type)
15280Sstevel@tonic-gate {
1529*2212Sartem 	(void) fprintf(fout, "%s : 0x%x : \"%s\" :",
15300Sstevel@tonic-gate 		name, reg->reg_flags, reg->reg_id);
15310Sstevel@tonic-gate 
15320Sstevel@tonic-gate 	if (type == REG_DOM_ID) {
15330Sstevel@tonic-gate 		struct dom_id_suffix *dis;
15340Sstevel@tonic-gate 
15350Sstevel@tonic-gate 		/* LINTED */
15360Sstevel@tonic-gate 		dis = (struct dom_id_suffix *)reg->reg_ids;
1537*2212Sartem 		(void) fprintf(fout, " 0x%x : %s : %s\n",
15380Sstevel@tonic-gate 			SWAP_16(dis->dis_udf_revison),
15390Sstevel@tonic-gate 			(dis->dis_domain_flags & PROTECT_SOFT_WRITE) ?
15400Sstevel@tonic-gate 				"HW Protect" : "No HW Write Protect",
15410Sstevel@tonic-gate 			(dis->dis_domain_flags & PROTECT_HARD_WRITE) ?
15420Sstevel@tonic-gate 				"SW Protect" : "No SW Protect");
15430Sstevel@tonic-gate 	} else if (type == REG_UDF_ID) {
15440Sstevel@tonic-gate 		struct udf_id_suffix *uis;
15450Sstevel@tonic-gate 
15460Sstevel@tonic-gate 		/* LINTED */
15470Sstevel@tonic-gate 		uis = (struct udf_id_suffix *)reg->reg_ids;
1548*2212Sartem 		(void) fprintf(fout,
15490Sstevel@tonic-gate 			" 0x%x : OS Class 0x%x : OS Identifier 0x%x\n",
15500Sstevel@tonic-gate 			SWAP_16(uis->uis_udf_revision),
15510Sstevel@tonic-gate 			uis->uis_os_class, uis->uis_os_identifier);
15520Sstevel@tonic-gate 	} else {
15530Sstevel@tonic-gate 		struct impl_id_suffix *iis;
15540Sstevel@tonic-gate 
15550Sstevel@tonic-gate 		iis = (struct impl_id_suffix *)reg->reg_ids;
1556*2212Sartem 		(void) fprintf(fout,
15570Sstevel@tonic-gate 			" OS Class 0x%x : OS Identifier 0x%x\n",
15580Sstevel@tonic-gate 			iis->iis_os_class, iis->iis_os_identifier);
15590Sstevel@tonic-gate 	}
15600Sstevel@tonic-gate }
15610Sstevel@tonic-gate 
15620Sstevel@tonic-gate #ifdef	OLD
15630Sstevel@tonic-gate void
print_regid(FILE * fout,char * name,struct regid * reg)1564*2212Sartem print_regid(FILE *fout, char *name, struct regid *reg)
15650Sstevel@tonic-gate {
1566*2212Sartem 	(void) fprintf(fout, "%s : 0x%x : \"%s\" :",
15670Sstevel@tonic-gate 		name, reg->reg_flags, reg->reg_id);
15680Sstevel@tonic-gate 
15690Sstevel@tonic-gate 	if (strncmp(reg->reg_id, "*OSTA UDF Compliant", 19) == 0) {
1570*2212Sartem 		(void) fprintf(fout, " 0x%x : %s : %s\n",
15710Sstevel@tonic-gate 			reg->reg_ids[0] | (reg->reg_ids[1] << 8),
15720Sstevel@tonic-gate 			(reg->reg_ids[2] & 1) ?
15730Sstevel@tonic-gate 				"HW Protect" : "No HW Write Protect",
15740Sstevel@tonic-gate 			(reg->reg_ids[2] & 2) ?
15750Sstevel@tonic-gate 				"SW Protect" : "No SW Protect");
15760Sstevel@tonic-gate 	} else if ((strncmp(reg->reg_id, "*UDF Virtual Partition", 22) == 0) ||
15770Sstevel@tonic-gate 		(strncmp(reg->reg_id, "*UDF Sparable Partition", 23) == 0) ||
15780Sstevel@tonic-gate 		(strncmp(reg->reg_id, "*UDF Virtual Alloc Tbl", 22) == 0) ||
15790Sstevel@tonic-gate 		(strncmp(reg->reg_id, "*UDF Sparing Table", 18) == 0)) {
1580*2212Sartem 		(void) fprintf(fout,
15810Sstevel@tonic-gate 			" 0x%x : OS Class 0x%x : OS Identifier 0x%x\n",
15820Sstevel@tonic-gate 			reg->reg_ids[0] | (reg->reg_ids[1] << 8),
15830Sstevel@tonic-gate 			reg->reg_ids[2], reg->reg_ids[3]);
15840Sstevel@tonic-gate 	} else {
1585*2212Sartem 		(void) fprintf(fout,
15860Sstevel@tonic-gate 			" OS Class 0x%x : OS Identifier 0x%x\n",
15870Sstevel@tonic-gate 			reg->reg_ids[0], reg->reg_ids[1]);
15880Sstevel@tonic-gate 	}
15890Sstevel@tonic-gate }
15900Sstevel@tonic-gate #endif
15910Sstevel@tonic-gate 
15920Sstevel@tonic-gate 
15930Sstevel@tonic-gate /* ------------ Routines to print basic structures Part 2 ---------------- */
15940Sstevel@tonic-gate /*
15950Sstevel@tonic-gate  * Part 2
15960Sstevel@tonic-gate  * This part is OS specific and is currently
15970Sstevel@tonic-gate  * not supported
15980Sstevel@tonic-gate  */
15990Sstevel@tonic-gate 
16000Sstevel@tonic-gate /* ------------ Routines to print basic structures Part 3 ---------------- */
16010Sstevel@tonic-gate 
16020Sstevel@tonic-gate void
print_ext_ad(FILE * fout,char * name,struct extent_ad * ead)1603*2212Sartem print_ext_ad(FILE *fout, char *name, struct extent_ad *ead)
16040Sstevel@tonic-gate {
1605*2212Sartem 	(void) fprintf(fout,
16060Sstevel@tonic-gate 		"%s EAD Len %x Loc %x\n",
16070Sstevel@tonic-gate 		name, SWAP_32(ead->ext_len), SWAP_32(ead->ext_loc));
16080Sstevel@tonic-gate }
16090Sstevel@tonic-gate 
16100Sstevel@tonic-gate void
print_tag(FILE * fout,struct tag * tag)1611*2212Sartem print_tag(FILE *fout, struct tag *tag)
16120Sstevel@tonic-gate {
1613*2212Sartem 	(void) fprintf(fout,
16140Sstevel@tonic-gate 		"tag_id : %x ver : %x cksum : %x "
16150Sstevel@tonic-gate 		"sno : %x crc : %x crc_len : %x loc : %x\n",
16160Sstevel@tonic-gate 		SWAP_16(tag->tag_id), SWAP_16(tag->tag_desc_ver),
16170Sstevel@tonic-gate 		tag->tag_cksum, SWAP_16(tag->tag_sno),
16180Sstevel@tonic-gate 		SWAP_16(tag->tag_crc), SWAP_16(tag->tag_crc_len),
16190Sstevel@tonic-gate 		SWAP_32(tag->tag_loc));
16200Sstevel@tonic-gate }
16210Sstevel@tonic-gate 
16220Sstevel@tonic-gate 
16230Sstevel@tonic-gate void
print_pvd(FILE * fout,struct pri_vol_desc * pvd)1624*2212Sartem print_pvd(FILE *fout, struct pri_vol_desc *pvd)
16250Sstevel@tonic-gate {
1626*2212Sartem 	(void) fprintf(fout,
16270Sstevel@tonic-gate 		"\n\t\t\tPrimary Volume Descriptor\n");
1628*2212Sartem 	print_tag(fout, &pvd->pvd_tag);
1629*2212Sartem 	(void) fprintf(fout, "vdsn : %x vdn : %x\n",
16300Sstevel@tonic-gate 		SWAP_32(pvd->pvd_vdsn), SWAP_32(pvd->pvd_pvdn));
1631*2212Sartem 	print_dstring(fout, "volid : ", pvd->pvd_desc_cs.cs_type,
16320Sstevel@tonic-gate 			pvd->pvd_vol_id, 32);
1633*2212Sartem 	(void) fprintf(fout,
16340Sstevel@tonic-gate 		"vsn : %x mvsn : %x il : %x mil :"
16350Sstevel@tonic-gate 		" %x csl : %x mcsl %x\n",
16360Sstevel@tonic-gate 		SWAP_16(pvd->pvd_vsn), SWAP_16(pvd->pvd_mvsn),
16370Sstevel@tonic-gate 		SWAP_16(pvd->pvd_il), SWAP_16(pvd->pvd_mil),
16380Sstevel@tonic-gate 		SWAP_32(pvd->pvd_csl), SWAP_32(pvd->pvd_mcsl));
1639*2212Sartem 	print_dstring(fout, "vsid :", pvd->pvd_desc_cs.cs_type,
16400Sstevel@tonic-gate 			pvd->pvd_vsi, 128);
1641*2212Sartem 	print_charspec(fout, "desc_cs", &pvd->pvd_desc_cs);
1642*2212Sartem 	print_charspec(fout, "exp_cs", &pvd->pvd_exp_cs);
1643*2212Sartem 	print_ext_ad(fout, "val ", &pvd->pvd_vol_abs);
1644*2212Sartem 	print_ext_ad(fout, "vcnl ", &pvd->pvd_vcn);
1645*2212Sartem 	print_regid(fout, "ai", &pvd->pvd_appl_id, REG_UDF_II);
1646*2212Sartem 	print_regid(fout, "ii", &pvd->pvd_ii, REG_UDF_II);
1647*2212Sartem 	(void) fprintf(fout, "pvdsl : %x flags : %x\n",
16480Sstevel@tonic-gate 		SWAP_32(pvd->pvd_pvdsl),
16490Sstevel@tonic-gate 		SWAP_16(pvd->pvd_flags));
16500Sstevel@tonic-gate }
16510Sstevel@tonic-gate 
16520Sstevel@tonic-gate void
print_avd(FILE * fout,struct anch_vol_desc_ptr * avdp)1653*2212Sartem print_avd(FILE *fout, struct anch_vol_desc_ptr *avdp)
16540Sstevel@tonic-gate {
1655*2212Sartem 	(void) fprintf(fout,
16560Sstevel@tonic-gate 		"\n\t\t\tAnchor Volume Descriptor\n");
1657*2212Sartem 	print_tag(fout, &avdp->avd_tag);
1658*2212Sartem 	print_ext_ad(fout, "Main Volume Descriptor Sequence : ",
16590Sstevel@tonic-gate 			&avdp->avd_main_vdse);
1660*2212Sartem 	print_ext_ad(fout, "Reserve Volume Descriptor Sequence : ",
16610Sstevel@tonic-gate 			&avdp->avd_res_vdse);
16620Sstevel@tonic-gate }
16630Sstevel@tonic-gate 
16640Sstevel@tonic-gate void
print_vdp(FILE * fout,struct vol_desc_ptr * vdp)1665*2212Sartem print_vdp(FILE *fout, struct vol_desc_ptr *vdp)
16660Sstevel@tonic-gate {
1667*2212Sartem 	(void) fprintf(fout,
16680Sstevel@tonic-gate 		"\n\t\t\tVolume Descriptor Pointer\n");
1669*2212Sartem 	print_tag(fout, &vdp->vdp_tag);
1670*2212Sartem 	(void) fprintf(fout, "vdsn : %x ",
16710Sstevel@tonic-gate 		SWAP_32(vdp->vdp_vdsn));
1672*2212Sartem 	print_ext_ad(fout, "vdse ", &vdp->vdp_nvdse);
16730Sstevel@tonic-gate }
16740Sstevel@tonic-gate 
16750Sstevel@tonic-gate void
print_iuvd(FILE * fout,struct iuvd_desc * iuvd)1676*2212Sartem print_iuvd(FILE *fout, struct iuvd_desc *iuvd)
16770Sstevel@tonic-gate {
1678*2212Sartem 	(void) fprintf(fout,
16790Sstevel@tonic-gate 		"\n\t\t\tImplementation Use Volume Descriptor\n");
1680*2212Sartem 	print_tag(fout, &iuvd->iuvd_tag);
1681*2212Sartem 	(void) fprintf(fout,
16820Sstevel@tonic-gate 		"vdsn : %x ", SWAP_32(iuvd->iuvd_vdsn));
1683*2212Sartem 	print_regid(fout, "Impl Id : ", &iuvd->iuvd_ii, REG_UDF_ID);
1684*2212Sartem 	print_charspec(fout, "cset ", &iuvd->iuvd_cset);
1685*2212Sartem 	print_dstring(fout, "lvi : ", iuvd->iuvd_cset.cs_type,
16860Sstevel@tonic-gate 			iuvd->iuvd_lvi, 128);
1687*2212Sartem 	print_dstring(fout, "ifo1 : ", iuvd->iuvd_cset.cs_type,
16880Sstevel@tonic-gate 			iuvd->iuvd_ifo1, 36);
1689*2212Sartem 	print_dstring(fout, "ifo2 : ", iuvd->iuvd_cset.cs_type,
16900Sstevel@tonic-gate 			iuvd->iuvd_ifo2, 36);
1691*2212Sartem 	print_dstring(fout, "ifo3 : ", iuvd->iuvd_cset.cs_type,
16920Sstevel@tonic-gate 			iuvd->iuvd_ifo3, 36);
16930Sstevel@tonic-gate 
1694*2212Sartem 	print_regid(fout, "iid ", &iuvd->iuvd_iid, REG_UDF_II);
16950Sstevel@tonic-gate }
16960Sstevel@tonic-gate 
16970Sstevel@tonic-gate void
print_part(FILE * fout,struct part_desc * pd)1698*2212Sartem print_part(FILE *fout, struct part_desc *pd)
16990Sstevel@tonic-gate {
1700*2212Sartem 	(void) fprintf(fout,
17010Sstevel@tonic-gate 		"\n\t\t\tPartition Descriptor\n");
1702*2212Sartem 	print_tag(fout, &pd->pd_tag);
1703*2212Sartem 	(void) fprintf(fout,
17040Sstevel@tonic-gate 		"vdsn : %x flags : %x num : %x ",
17050Sstevel@tonic-gate 		SWAP_32(pd->pd_vdsn),
17060Sstevel@tonic-gate 		SWAP_16(pd->pd_pflags),
17070Sstevel@tonic-gate 		SWAP_16(pd->pd_pnum));
1708*2212Sartem 	print_regid(fout, "contents ", &pd->pd_pcontents, REG_UDF_II);
17090Sstevel@tonic-gate 	/* LINTED */
1710*2212Sartem 	print_phdr(fout, (struct phdr_desc *)(&pd->pd_pc_use));
1711*2212Sartem 	(void) fprintf(fout,
17120Sstevel@tonic-gate 		"acc : %x start : %x length : %x ",
17130Sstevel@tonic-gate 		SWAP_32(pd->pd_acc_type),
17140Sstevel@tonic-gate 		SWAP_32(pd->pd_part_start),
17150Sstevel@tonic-gate 		SWAP_32(pd->pd_part_length));
1716*2212Sartem 	print_regid(fout, "Impl Id : ", &pd->pd_ii, REG_UDF_II);
17170Sstevel@tonic-gate }
17180Sstevel@tonic-gate 
17190Sstevel@tonic-gate void
print_lvd(FILE * fout,struct log_vol_desc * lvd)1720*2212Sartem print_lvd(FILE *fout, struct log_vol_desc *lvd)
17210Sstevel@tonic-gate {
1722*2212Sartem 	(void) fprintf(fout,
17230Sstevel@tonic-gate 		"\n\t\t\tLogical Volume Descriptor\n");
1724*2212Sartem 	print_tag(fout, &lvd->lvd_tag);
1725*2212Sartem 	(void) fprintf(fout,
17260Sstevel@tonic-gate 		"vdsn : %x ", SWAP_32(lvd->lvd_vdsn));
1727*2212Sartem 	print_charspec(fout, "Desc Char Set ", &lvd->lvd_desc_cs);
1728*2212Sartem 	print_dstring(fout, "lvid : ", lvd->lvd_desc_cs.cs_type,
17290Sstevel@tonic-gate 			lvd->lvd_lvid, 28);
1730*2212Sartem 	(void) fprintf(fout,
17310Sstevel@tonic-gate 		"lbsize : %x ",
17320Sstevel@tonic-gate 		SWAP_32(lvd->lvd_log_bsize));
1733*2212Sartem 	print_regid(fout, "Dom Id", &lvd->lvd_dom_id, REG_DOM_ID);
1734*2212Sartem 	print_long_ad(fout, "lvcu", &lvd->lvd_lvcu);
1735*2212Sartem 	(void) fprintf(fout,
17360Sstevel@tonic-gate 		"mtlen : %x nmaps : %x ",
17370Sstevel@tonic-gate 		SWAP_32(lvd->lvd_mtbl_len),
17380Sstevel@tonic-gate 		SWAP_32(lvd->lvd_num_pmaps));
1739*2212Sartem 	print_regid(fout, "Impl Id : ", &lvd->lvd_ii, REG_UDF_II);
1740*2212Sartem 	print_ext_ad(fout, "Int Seq", &lvd->lvd_int_seq_ext);
1741*2212Sartem 	print_pmaps(fout, lvd->lvd_pmaps, SWAP_32(lvd->lvd_num_pmaps));
17420Sstevel@tonic-gate }
17430Sstevel@tonic-gate 
17440Sstevel@tonic-gate void
print_usd(FILE * fout,struct unall_spc_desc * ua)1745*2212Sartem print_usd(FILE *fout, struct unall_spc_desc *ua)
17460Sstevel@tonic-gate {
17470Sstevel@tonic-gate 	int32_t i, count;
17480Sstevel@tonic-gate 
1749*2212Sartem 	(void) fprintf(fout,
17500Sstevel@tonic-gate 		"\n\t\t\tUnallocated Space Descriptor\n");
1751*2212Sartem 	print_tag(fout, &ua->ua_tag);
17520Sstevel@tonic-gate 	count = SWAP_32(ua->ua_nad);
1753*2212Sartem 	(void) fprintf(fout,
17540Sstevel@tonic-gate 		"vdsn : %x nad : %x\n",
17550Sstevel@tonic-gate 		SWAP_32(ua->ua_vdsn), count);
17560Sstevel@tonic-gate 	for (i = 0; i < count; i++) {
1757*2212Sartem 		(void) fprintf(fout,
17580Sstevel@tonic-gate 			"loc : %x len : %x\n",
17590Sstevel@tonic-gate 			SWAP_32(ua->ua_al_dsc[i * 2]),
17600Sstevel@tonic-gate 			SWAP_32(ua->ua_al_dsc[i * 2 + 1]));
17610Sstevel@tonic-gate 	}
17620Sstevel@tonic-gate }
17630Sstevel@tonic-gate 
17640Sstevel@tonic-gate void
print_lvid(FILE * fout,struct log_vol_int_desc * lvid)1765*2212Sartem print_lvid(FILE *fout, struct log_vol_int_desc *lvid)
17660Sstevel@tonic-gate {
17670Sstevel@tonic-gate 	int32_t i, count;
17680Sstevel@tonic-gate 	caddr_t addr;
17690Sstevel@tonic-gate 	struct lvid_iu *liu;
17700Sstevel@tonic-gate 
1771*2212Sartem 	(void) fprintf(fout,
17720Sstevel@tonic-gate 		"\n\t\t\tLogical Volume Integrity Descriptor\n");
1773*2212Sartem 	print_tag(fout, &lvid->lvid_tag);
1774*2212Sartem 	print_tstamp(fout, "Rec TM ", &lvid->lvid_tstamp);
17750Sstevel@tonic-gate 	if (SWAP_32(lvid->lvid_int_type) == 0) {
1776*2212Sartem 		(void) fprintf(fout,
17770Sstevel@tonic-gate 			"int_typ : Open\n");
17780Sstevel@tonic-gate 	} else if (SWAP_32(lvid->lvid_int_type) == 1) {
1779*2212Sartem 		(void) fprintf(fout, "int_typ : Closed\n");
17800Sstevel@tonic-gate 	} else {
1781*2212Sartem 		(void) fprintf(fout, "int_typ : Unknown\n");
17820Sstevel@tonic-gate 	}
1783*2212Sartem 	print_ext_ad(fout, "Nie ", &lvid->lvid_nie);
17840Sstevel@tonic-gate 	count = SWAP_32(lvid->lvid_npart);
1785*2212Sartem 	(void) fprintf(fout,
17860Sstevel@tonic-gate 		"Uniq : %llx npart : %x liu : %x\n",
17870Sstevel@tonic-gate 		SWAP_64(lvid->lvid_lvcu.lvhd_uniqid),
17880Sstevel@tonic-gate 		count, SWAP_32(lvid->lvid_liu));
17890Sstevel@tonic-gate 	for (i = 0; i < count; i++) {
1790*2212Sartem 		(void) fprintf(fout,
17910Sstevel@tonic-gate 			"Part : %x Free : %x Size : %x\n",
17920Sstevel@tonic-gate 			i, SWAP_32(lvid->lvid_fst[i]),
17930Sstevel@tonic-gate 			SWAP_32(lvid->lvid_fst[count + i]));
17940Sstevel@tonic-gate 	}
17950Sstevel@tonic-gate 
17960Sstevel@tonic-gate 	addr = (caddr_t)lvid->lvid_fst;
17970Sstevel@tonic-gate 	/* LINTED */
17980Sstevel@tonic-gate 	liu = (struct lvid_iu *)(addr + 2 * count * 4);
1799*2212Sartem 	print_regid(fout, "Impl Id :", &liu->lvidiu_regid, REG_UDF_II);
1800*2212Sartem 	(void) fprintf(fout,
18010Sstevel@tonic-gate 		"nfiles : %x ndirs : %x miread : %x"
18020Sstevel@tonic-gate 		" miwrite : %x mawrite : %x\n",
18030Sstevel@tonic-gate 		SWAP_32(liu->lvidiu_nfiles), SWAP_32(liu->lvidiu_ndirs),
18040Sstevel@tonic-gate 		SWAP_16(liu->lvidiu_mread), SWAP_16(liu->lvidiu_mwrite),
18050Sstevel@tonic-gate 		SWAP_16(liu->lvidiu_maxwr));
18060Sstevel@tonic-gate }
18070Sstevel@tonic-gate 
18080Sstevel@tonic-gate 
18090Sstevel@tonic-gate /* ------------ Routines to print basic structures Part 4 ---------------- */
18100Sstevel@tonic-gate 
18110Sstevel@tonic-gate void
print_fsd(FILE * fout,ud_handle_t h,struct file_set_desc * fsd)1812*2212Sartem print_fsd(FILE *fout, ud_handle_t h, struct file_set_desc *fsd)
18130Sstevel@tonic-gate {
1814*2212Sartem 	(void) fprintf(fout,
18150Sstevel@tonic-gate 		"\n\t\t\tFile Set Descriptor\n");
18160Sstevel@tonic-gate 
1817*2212Sartem 	print_tag(fout, &fsd->fsd_tag);
1818*2212Sartem 	print_tstamp(fout, "Rec TM ", &fsd->fsd_time);
1819*2212Sartem 	(void) fprintf(fout,
18200Sstevel@tonic-gate 		"ilvl : %x milvl : %x csl : %x"
18210Sstevel@tonic-gate 		" mcsl : %x fsn : %x fsdn : %x\n",
18220Sstevel@tonic-gate 		SWAP_16(fsd->fsd_ilevel), SWAP_16(fsd->fsd_mi_level),
18230Sstevel@tonic-gate 		SWAP_32(fsd->fsd_cs_list), SWAP_32(fsd->fsd_mcs_list),
18240Sstevel@tonic-gate 		SWAP_32(fsd->fsd_fs_no), SWAP_32(fsd->fsd_fsd_no));
1825*2212Sartem 	print_charspec(fout, "ID CS ", &fsd->fsd_lvidcs);
1826*2212Sartem 	print_dstring(fout, "lvi : ", fsd->fsd_lvidcs.cs_type,
18270Sstevel@tonic-gate 			fsd->fsd_lvid, 128);
1828*2212Sartem 	print_charspec(fout, "ID CS ", &fsd->fsd_fscs);
1829*2212Sartem 	print_dstring(fout, "fsi : ", fsd->fsd_lvidcs.cs_type,
18300Sstevel@tonic-gate 			fsd->fsd_fsi, 32);
1831*2212Sartem 	print_dstring(fout, "cfi : ", fsd->fsd_lvidcs.cs_type,
18320Sstevel@tonic-gate 			fsd->fsd_cfi, 32);
1833*2212Sartem 	print_dstring(fout, "afi : ", fsd->fsd_lvidcs.cs_type,
18340Sstevel@tonic-gate 			fsd->fsd_afi, 32);
1835*2212Sartem 	print_long_ad(fout, "Ricb ", &fsd->fsd_root_icb);
1836*2212Sartem 	print_regid(fout, "DI ", &fsd->fsd_did, REG_DOM_ID);
1837*2212Sartem 	print_long_ad(fout, "Next Fsd ", &fsd->fsd_next);
1838*2212Sartem 	if (h->udfs.ecma_version == UD_ECMA_VER3) {
1839*2212Sartem 		print_long_ad(fout, "System Stream Directory ICB ",
1840*2212Sartem 				&fsd->fsd_next);
18410Sstevel@tonic-gate 	}
18420Sstevel@tonic-gate }
18430Sstevel@tonic-gate 
18440Sstevel@tonic-gate void
print_phdr(FILE * fout,struct phdr_desc * ph)1845*2212Sartem print_phdr(FILE *fout, struct phdr_desc *ph)
18460Sstevel@tonic-gate {
1847*2212Sartem 	print_short_ad(fout, "ust ", &ph->phdr_ust);
1848*2212Sartem 	print_short_ad(fout, "usb ", &ph->phdr_usb);
1849*2212Sartem 	print_short_ad(fout, "int ", &ph->phdr_it);
1850*2212Sartem 	print_short_ad(fout, "fst ", &ph->phdr_fst);
1851*2212Sartem 	print_short_ad(fout, "fsh ", &ph->phdr_fsb);
18520Sstevel@tonic-gate }
18530Sstevel@tonic-gate 
18540Sstevel@tonic-gate void
print_fid(FILE * fout,struct file_id * fid)1855*2212Sartem print_fid(FILE *fout, struct file_id *fid)
18560Sstevel@tonic-gate {
18570Sstevel@tonic-gate 	int32_t i;
18580Sstevel@tonic-gate 	uint8_t *addr;
18590Sstevel@tonic-gate 
1860*2212Sartem 	(void) fprintf(fout,
18610Sstevel@tonic-gate 		"File Identifier Descriptor\n");
1862*2212Sartem 	print_tag(fout, &fid->fid_tag);
1863*2212Sartem 	(void) fprintf(fout, "fvn : %x fc : %x length : %x ",
18640Sstevel@tonic-gate 		fid->fid_ver, fid->fid_flags, fid->fid_idlen);
1865*2212Sartem 	print_long_ad(fout, "ICB", &fid->fid_icb);
18660Sstevel@tonic-gate 	addr = &fid->fid_spec[SWAP_16(fid->fid_iulen)];
1867*2212Sartem 	(void) fprintf(fout, "iulen : %x comp : %x name : ",
18680Sstevel@tonic-gate 		SWAP_16(fid->fid_iulen), *addr);
18690Sstevel@tonic-gate 	addr++;
18700Sstevel@tonic-gate 	for (i = 0; i < fid->fid_idlen; i++) {
1871*2212Sartem 		(void) fprintf(fout, "%c", *addr++);
18720Sstevel@tonic-gate 	}
1873*2212Sartem 	(void) fprintf(fout, "\n");
18740Sstevel@tonic-gate }
18750Sstevel@tonic-gate 
18760Sstevel@tonic-gate void
print_aed(FILE * fout,struct alloc_ext_desc * aed)1877*2212Sartem print_aed(FILE *fout, struct alloc_ext_desc *aed)
18780Sstevel@tonic-gate {
1879*2212Sartem 	(void) fprintf(fout,
18800Sstevel@tonic-gate 		"Allocation Extent Descriptor\n");
1881*2212Sartem 	print_tag(fout, &aed->aed_tag);
1882*2212Sartem 	(void) fprintf(fout, "prev ael loc : %x laed : %x\n",
18830Sstevel@tonic-gate 		SWAP_32(aed->aed_rev_ael), SWAP_32(aed->aed_len_aed));
18840Sstevel@tonic-gate }
18850Sstevel@tonic-gate 
1886*2212Sartem static char *ftype[] = {
18870Sstevel@tonic-gate 	"NON",  "USE",  "PIE",  "IE",
18880Sstevel@tonic-gate 	"DIR",  "REG",  "BDEV", "CDEV",
18890Sstevel@tonic-gate 	"EATT", "FIFO", "SOCK", "TERM",
18900Sstevel@tonic-gate 	"SYML", "SDIR"
18910Sstevel@tonic-gate };
18920Sstevel@tonic-gate 
18930Sstevel@tonic-gate void
print_icb_tag(FILE * fout,struct icb_tag * itag)1894*2212Sartem print_icb_tag(FILE *fout, struct icb_tag *itag)
18950Sstevel@tonic-gate {
1896*2212Sartem 	(void) fprintf(fout,
18970Sstevel@tonic-gate 		"prnde : %x strat : %x param : %x max_ent %x\n",
18980Sstevel@tonic-gate 		SWAP_32(itag->itag_prnde), SWAP_16(itag->itag_strategy),
18990Sstevel@tonic-gate 		SWAP_16(itag->itag_param), SWAP_16(itag->itag_max_ent));
1900*2212Sartem 	(void) fprintf(fout,
19010Sstevel@tonic-gate 		"ftype : %s prn : %x loc : %x flags : %x\n",
19020Sstevel@tonic-gate 		(itag->itag_ftype >= 14) ? ftype[0] : ftype[itag->itag_ftype],
19030Sstevel@tonic-gate 		SWAP_16(itag->itag_lb_prn),
19040Sstevel@tonic-gate 		SWAP_32(itag->itag_lb_loc), SWAP_16(itag->itag_flags));
19050Sstevel@tonic-gate }
19060Sstevel@tonic-gate 
19070Sstevel@tonic-gate 
19080Sstevel@tonic-gate void
print_ie(FILE * fout,struct indirect_entry * ie)1909*2212Sartem print_ie(FILE *fout, struct indirect_entry *ie)
19100Sstevel@tonic-gate {
1911*2212Sartem 	(void) fprintf(fout,
19120Sstevel@tonic-gate 		"Indirect Entry\n");
1913*2212Sartem 	print_tag(fout, &ie->ie_tag);
1914*2212Sartem 	print_icb_tag(fout, &ie->ie_icb_tag);
1915*2212Sartem 	print_long_ad(fout, "ICB", &ie->ie_indirecticb);
19160Sstevel@tonic-gate }
19170Sstevel@tonic-gate 
19180Sstevel@tonic-gate void
print_td(FILE * fout,struct term_desc * td)1919*2212Sartem print_td(FILE *fout, struct term_desc *td)
19200Sstevel@tonic-gate {
1921*2212Sartem 	(void) fprintf(fout,
19220Sstevel@tonic-gate 		"Terminating Descriptor\n");
1923*2212Sartem 	print_tag(fout, &td->td_tag);
19240Sstevel@tonic-gate }
19250Sstevel@tonic-gate 
19260Sstevel@tonic-gate void
print_fe(FILE * fout,struct file_entry * fe)1927*2212Sartem print_fe(FILE *fout, struct file_entry *fe)
19280Sstevel@tonic-gate {
1929*2212Sartem 	(void) fprintf(fout,
19300Sstevel@tonic-gate 		"File Entry\n");
1931*2212Sartem 	print_tag(fout, &fe->fe_tag);
1932*2212Sartem 	print_icb_tag(fout, &fe->fe_icb_tag);
1933*2212Sartem 	(void) fprintf(fout,
19340Sstevel@tonic-gate 		"uid : %x gid : %x perms : %x nlnk : %x\n",
19350Sstevel@tonic-gate 		SWAP_32(fe->fe_uid), SWAP_32(fe->fe_gid),
19360Sstevel@tonic-gate 		SWAP_32(fe->fe_perms), SWAP_16(fe->fe_lcount));
1937*2212Sartem 	(void) fprintf(fout,
19380Sstevel@tonic-gate 		"rec_for : %x rec_dis : %x rec_len : %x "
19390Sstevel@tonic-gate 		"sz : %llx blks : %llx\n",
19400Sstevel@tonic-gate 		fe->fe_rec_for, fe->fe_rec_dis, SWAP_32(fe->fe_rec_len),
19410Sstevel@tonic-gate 		SWAP_64(fe->fe_info_len), SWAP_64(fe->fe_lbr));
1942*2212Sartem 	print_tstamp(fout, "ctime ", &fe->fe_acc_time);
1943*2212Sartem 	print_tstamp(fout, "mtime ", &fe->fe_mod_time);
1944*2212Sartem 	print_tstamp(fout, "atime ", &fe->fe_attr_time);
1945*2212Sartem 	(void) fprintf(fout,
19460Sstevel@tonic-gate 		"ckpoint : %x ", SWAP_32(fe->fe_ckpoint));
1947*2212Sartem 	print_long_ad(fout, "ICB", &fe->fe_ea_icb);
1948*2212Sartem 	print_regid(fout, "impl", &fe->fe_impl_id, REG_UDF_II);
1949*2212Sartem 	(void) fprintf(fout,
19500Sstevel@tonic-gate 		"uniq_id : %llx len_ear : %x len_adesc %x\n",
19510Sstevel@tonic-gate 		SWAP_64(fe->fe_uniq_id), SWAP_32(fe->fe_len_ear),
19520Sstevel@tonic-gate 		SWAP_32(fe->fe_len_adesc));
19530Sstevel@tonic-gate }
19540Sstevel@tonic-gate 
19550Sstevel@tonic-gate void
print_pmaps(FILE * fout,uint8_t * addr,int32_t count)1956*2212Sartem print_pmaps(FILE *fout, uint8_t *addr, int32_t count)
19570Sstevel@tonic-gate {
19580Sstevel@tonic-gate 	struct pmap_hdr *hdr;
19590Sstevel@tonic-gate 	struct pmap_typ1 *map1;
19600Sstevel@tonic-gate 	struct pmap_typ2 *map2;
19610Sstevel@tonic-gate 
19620Sstevel@tonic-gate 	while (count--) {
19630Sstevel@tonic-gate 		hdr = (struct pmap_hdr *)addr;
19640Sstevel@tonic-gate 		switch (hdr->maph_type) {
19650Sstevel@tonic-gate 		case 1 :
19660Sstevel@tonic-gate 			/* LINTED */
19670Sstevel@tonic-gate 			map1 = (struct pmap_typ1 *)hdr;
1968*2212Sartem 			(void) fprintf(fout, "Map type 1 ");
1969*2212Sartem 			(void) fprintf(fout, "VSN %x prn %x\n",
19700Sstevel@tonic-gate 					SWAP_16(map1->map1_vsn),
19710Sstevel@tonic-gate 					SWAP_16(map1->map1_pn));
19720Sstevel@tonic-gate 			break;
19730Sstevel@tonic-gate 		case 2 :
19740Sstevel@tonic-gate 			/* LINTED */
19750Sstevel@tonic-gate 			map2 = (struct pmap_typ2 *)hdr;
1976*2212Sartem 			(void) fprintf(fout, "Map type 2 ");
1977*2212Sartem 			(void) fprintf(fout, "VSN %x prn %x\n",
19780Sstevel@tonic-gate 					SWAP_16(map2->map2_vsn),
19790Sstevel@tonic-gate 					SWAP_16(map2->map2_pn));
1980*2212Sartem 			print_regid(fout, "Partition Type Identifier",
19810Sstevel@tonic-gate 					&map2->map2_pti, REG_UDF_ID);
19820Sstevel@tonic-gate 			break;
19830Sstevel@tonic-gate 		default :
1984*2212Sartem 			(void) fprintf(fout, "unknown map type\n");
19850Sstevel@tonic-gate 		}
19860Sstevel@tonic-gate 		addr += hdr->maph_length;
19870Sstevel@tonic-gate 	}
19880Sstevel@tonic-gate }
19890Sstevel@tonic-gate 
19900Sstevel@tonic-gate 
19910Sstevel@tonic-gate 
19920Sstevel@tonic-gate void
print_short_ad(FILE * fout,char * name,struct short_ad * sad)1993*2212Sartem print_short_ad(FILE *fout, char *name, struct short_ad *sad)
19940Sstevel@tonic-gate {
1995*2212Sartem 	(void) fprintf(fout,
19960Sstevel@tonic-gate 		"%s loc : %x len : %x\n", name,
19970Sstevel@tonic-gate 		SWAP_32(sad->sad_ext_loc), SWAP_32(sad->sad_ext_len));
19980Sstevel@tonic-gate }
19990Sstevel@tonic-gate 
20000Sstevel@tonic-gate void
print_long_ad(FILE * fout,char * name,struct long_ad * lad)2001*2212Sartem print_long_ad(FILE *fout, char *name, struct long_ad *lad)
20020Sstevel@tonic-gate {
2003*2212Sartem 	(void) fprintf(fout,
20040Sstevel@tonic-gate 		"%s prn : %x loc : %x len : %x\n", name,
20050Sstevel@tonic-gate 		SWAP_16(lad->lad_ext_prn), SWAP_32(lad->lad_ext_loc),
20060Sstevel@tonic-gate 		SWAP_32(lad->lad_ext_len));
20070Sstevel@tonic-gate }
2008