8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / fs.d / udfs / fstyp / ud_lib.c
blob10ab2009b6fb5fbb9daf10dcb3bbb52baf74de46
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <malloc.h>
31 #include <unistd.h>
32 #include <strings.h>
33 #include <errno.h>
34 #include <libintl.h>
35 #include <libgen.h>
36 #include <fcntl.h>
37 #include <sys/types.h>
38 #include <sys/int_types.h>
39 #include <sys/dkio.h>
40 #include <sys/cdio.h>
41 #include <sys/vtoc.h>
42 #include <sys/stat.h>
43 #include <sys/param.h>
44 #include <sys/fs/udf_volume.h>
45 #include "ud_lib.h"
47 extern char *getfullrawname(char *);
49 static int32_t ud_get_ecma_ver(ud_handle_t, uint32_t);
50 static int32_t ud_get_fs_bsize(ud_handle_t, uint32_t, uint32_t *);
51 static int32_t ud_parse_fill_vds(ud_handle_t, struct vds *, uint32_t, uint32_t);
52 static int32_t ud_read_and_translate_lvd(ud_handle_t, uint32_t, uint32_t);
53 static int32_t ud_get_latest_lvid(ud_handle_t, uint32_t, uint32_t);
54 static int32_t ud_get_latest_fsd(ud_handle_t, uint16_t, uint32_t, uint32_t);
56 static uint16_t ud_crc(uint8_t *, int32_t);
57 static int32_t UdfTxName(uint16_t *, int32_t);
58 static int32_t UncompressUnicode(int32_t, uint8_t *, uint16_t *);
59 static int32_t ud_compressunicode(int32_t, int32_t, uint16_t *, uint8_t *);
60 static int32_t ud_convert2utf8(uint8_t *, uint8_t *, int32_t);
61 static int32_t ud_convert2utf16(uint8_t *, uint8_t *, int32_t);
64 int
65 ud_init(int fd, ud_handle_t *hp)
67 struct ud_handle *h;
69 if ((h = calloc(1, sizeof (struct ud_handle))) == NULL) {
70 return (ENOMEM);
72 h->fd = fd;
73 *hp = h;
74 return (0);
77 void
78 ud_fini(ud_handle_t h)
80 free(h);
83 /* ARGSUSED */
84 int32_t
85 ud_open_dev(ud_handle_t h, char *special, uint32_t flags)
87 char *temp;
88 struct stat i_stat, r_stat;
90 (void) bzero(&i_stat, sizeof (struct stat));
91 (void) bzero(&r_stat, sizeof (struct stat));
94 * Get the stat structure
96 if (stat(special, &i_stat) < 0) {
97 temp = special;
98 } else {
100 if ((i_stat.st_mode & S_IFMT) == S_IFCHR) {
103 * If Raw deivce is given use it as it is
106 temp = special;
107 } else if ((i_stat.st_mode & S_IFMT) == S_IFBLK) {
110 * Block device try to convert to raw device
113 temp = getfullrawname(special);
116 * Stat the converted device name and verify
117 * both the raw and block device belong to
118 * the same device
120 if (stat(temp, &r_stat) < 0) {
121 temp = special;
122 } else {
123 if (((r_stat.st_mode & S_IFMT) == S_IFBLK) ||
124 (r_stat.st_rdev != i_stat.st_rdev)) {
125 temp = special;
132 * Now finally open the device
134 h->fd = open(temp, flags);
136 return (h->fd);
139 /* ARGSUSED */
140 void
141 ud_close_dev(ud_handle_t h)
144 * Too simple Just close it
146 (void) close(h->fd);
149 int32_t
150 ud_read_dev(ud_handle_t h, uint64_t offset, uint8_t *buf, uint32_t count)
153 * Seek to the given offset
155 if (lseek(h->fd, offset, SEEK_SET) == -1) {
156 return (1);
160 * Read the required number of bytes
162 if (read(h->fd, buf, count) != count) {
163 return (1);
165 return (0);
168 int32_t
169 ud_write_dev(ud_handle_t h, uint64_t offset, uint8_t *buf, uint32_t count)
172 * Seek to the given offset
174 if (lseek(h->fd, offset, SEEK_SET) == -1) {
175 return (1);
179 * Read the appropriate number of bytes
181 if (write(h->fd, buf, count) != count) {
182 return (1);
184 return (0);
187 /* ----- BEGIN Read and translate the on disk VDS to IN CORE format -------- */
189 int32_t
190 ud_fill_udfs_info(ud_handle_t h)
192 struct anch_vol_desc_ptr *avdp = NULL;
193 uint32_t offset = 0;
195 if (ioctl(h->fd, CDROMREADOFFSET, &offset) == -1) {
196 offset = 0;
199 h->udfs.flags = INVALID_UDFS;
201 h->udfs.ecma_version = ud_get_ecma_ver(h, offset);
202 if (h->udfs.ecma_version == UD_ECMA_UNKN) {
203 return (1);
206 h->udfs.lbsize = ud_get_fs_bsize(h, offset, &h->udfs.avdp_loc);
207 if (h->udfs.lbsize == 0) {
208 return (2);
211 h->udfs.avdp_len = lb_roundup(512, h->udfs.lbsize);
214 if ((avdp = (struct anch_vol_desc_ptr *)
215 malloc(h->udfs.lbsize)) == NULL) {
216 return (3);
218 if (ud_read_dev(h, h->udfs.avdp_loc * h->udfs.lbsize,
219 (uint8_t *)avdp, h->udfs.lbsize) != 0) {
220 free(avdp);
221 return (4);
223 if (ud_verify_tag(h, &avdp->avd_tag, UD_ANCH_VOL_DESC,
224 h->udfs.avdp_loc, 1, 0) != 0) {
225 free(avdp);
226 return (5);
229 h->udfs.mvds_loc = SWAP_32(avdp->avd_main_vdse.ext_loc);
230 h->udfs.mvds_len = SWAP_32(avdp->avd_main_vdse.ext_len);
232 h->udfs.rvds_loc = SWAP_32(avdp->avd_res_vdse.ext_loc);
233 h->udfs.rvds_len = SWAP_32(avdp->avd_res_vdse.ext_len);
235 free(avdp);
238 * get information from mvds and rvds
240 if (ud_parse_fill_vds(h, &h->udfs.mvds,
241 h->udfs.mvds_loc, h->udfs.mvds_len) == 0) {
242 h->udfs.flags |= VALID_MVDS;
244 if (ud_parse_fill_vds(h, &h->udfs.rvds,
245 h->udfs.rvds_loc, h->udfs.rvds_len) == 0) {
246 h->udfs.flags |= VALID_RVDS;
249 if ((h->udfs.flags & (VALID_MVDS | VALID_RVDS)) == 0) {
250 return (6);
254 * If we are here we have
255 * a valid Volume Descriptor Seqence
256 * Read and understand lvd
258 if (h->udfs.flags & VALID_MVDS) {
259 if (ud_read_and_translate_lvd(h, h->udfs.mvds.lvd_loc,
260 h->udfs.mvds.lvd_len) != 0) {
261 return (7);
263 } else {
264 if (ud_read_and_translate_lvd(h, h->udfs.rvds.lvd_loc,
265 h->udfs.rvds.lvd_len) != 0) {
266 return (8);
270 h->udfs.flags |= VALID_UDFS;
272 return (0);
275 static int32_t
276 ud_get_ecma_ver(ud_handle_t h, uint32_t offset)
278 uint8_t *buf;
279 uint64_t off;
280 uint64_t end_off;
281 struct nsr_desc *ndsc;
282 uint32_t ecma_ver = UD_ECMA_UNKN;
285 * Allocate a buffer of size UD_VOL_REC_BSZ
287 if ((buf = (uint8_t *)malloc(UD_VOL_REC_BSZ)) == NULL) {
290 * Uh could not even allocate this much
292 goto end;
296 * Start from 32k and keep reading 2k blocks we
297 * should be able to find NSR if we have one by 256 * 2k bytes
299 off = offset * 2048 + UD_VOL_REC_START;
300 end_off = offset * 2048 + UD_VOL_REC_END;
301 for (; off < end_off; off += UD_VOL_REC_BSZ) {
303 if (ud_read_dev(h, off, buf, UD_VOL_REC_BSZ) == 0) {
305 ndsc = (struct nsr_desc *)buf;
307 * Is this either NSR02 or NSR03
309 if ((ndsc->nsr_str_type == 0) &&
310 (ndsc->nsr_ver == 1) &&
311 (ndsc->nsr_id[0] == 'N') &&
312 (ndsc->nsr_id[1] == 'S') &&
313 (ndsc->nsr_id[2] == 'R') &&
314 (ndsc->nsr_id[3] == '0') &&
315 ((ndsc->nsr_id[4] == '2') ||
316 (ndsc->nsr_id[4] == '3'))) {
318 (void) strncpy((char *)h->udfs.ecma_id,
319 (char *)ndsc->nsr_id, 5);
321 switch (ndsc->nsr_id[4]) {
322 case '2' :
325 * ECMA 167/2
327 ecma_ver = UD_ECMA_VER2;
328 goto end;
329 case '3' :
332 * ECMA 167/3
334 ecma_ver = UD_ECMA_VER3;
335 goto end;
341 end:
343 * Cleanup
345 free(buf);
346 return (ecma_ver);
349 static uint32_t last_block_index[] = {0, 0, 256, 2, 2 + 256,
350 150, 150 + 256, 152, 152 + 256};
352 static int32_t
353 ud_get_fs_bsize(ud_handle_t h, uint32_t offset, uint32_t *avd_loc)
355 uint64_t off;
356 int32_t index, bsize, shift, end_index;
357 uint32_t num_blocks, sub_blk;
358 uint8_t *buf = NULL;
359 struct anch_vol_desc_ptr *avdp;
361 if ((buf = (uint8_t *)malloc(MAXBSIZE)) == NULL) {
362 return (0);
366 * If we could figure out the last block
367 * search at 256, N, N - 256 blocks
368 * otherwise just check at 256
370 if (ud_get_num_blks(h, &num_blocks) != 0) {
371 end_index = 1;
372 num_blocks = 0;
373 } else {
374 end_index = sizeof (last_block_index) / 4;
377 for (index = 0; index < end_index; index++) {
378 sub_blk = last_block_index[index];
381 * Start guessing from DEV_BSIZE to MAXBSIZE
383 for (bsize = DEV_BSIZE, shift = 0;
384 bsize <= MAXBSIZE; bsize <<= 1, shift++) {
386 if (index == 0) {
389 * Check if we atleast have 256 of bsize
390 * blocks on the device
392 if ((end_index == 0) ||
393 (num_blocks > (256 << shift))) {
394 *avd_loc = 256;
395 if (bsize <= 2048) {
396 *avd_loc +=
397 offset * 2048 / bsize;
398 } else {
399 *avd_loc +=
400 offset / (bsize / 2048);
402 } else {
403 continue;
405 } else {
407 * Calculate the bsize avd block
409 if ((num_blocks) &&
410 (num_blocks > (sub_blk << shift))) {
411 *avd_loc = (num_blocks >> shift) -
412 sub_blk;
413 } else {
414 continue;
418 off = (uint64_t)*avd_loc * bsize;
421 * Read bsize bytes at off
423 if (ud_read_dev(h, off, buf, bsize) != 0) {
424 continue;
428 * Check if we have a Anchor Volume Descriptor here
431 /* LINTED */
432 avdp = (struct anch_vol_desc_ptr *)buf;
433 if (ud_verify_tag(h, &avdp->avd_tag,
434 UD_ANCH_VOL_DESC, *avd_loc, 1, 0) != 0) {
435 continue;
437 goto end;
441 end:
442 if (bsize > MAXBSIZE) {
443 bsize = 0;
444 *avd_loc = 0;
446 free(buf);
447 return (bsize);
450 static int32_t
451 ud_parse_fill_vds(ud_handle_t h, struct vds *v,
452 uint32_t vds_loc, uint32_t vds_len)
454 uint8_t *addr, *taddr, *eaddr;
455 uint16_t id;
456 int32_t i;
457 uint64_t off;
458 struct tag *tag;
459 struct pri_vol_desc *pvd;
460 struct log_vol_desc *lvd;
461 struct vol_desc_ptr *vds;
462 struct unall_spc_desc *usd;
464 begin:
465 if ((addr = (uint8_t *)malloc(vds_len)) == NULL) {
466 return (1);
469 off = vds_loc * h->udfs.lbsize;
470 if (ud_read_dev(h, off, addr, vds_len) != 0) {
471 goto end;
474 for (taddr = addr, eaddr = addr + h->udfs.mvds_len; taddr < eaddr;
475 taddr += h->udfs.lbsize, vds_loc ++) {
477 /* LINTED */
478 tag = (struct tag *)taddr;
479 id = SWAP_16(tag->tag_id);
481 * If you cannot verify the tag just skip it
482 * This is not a fatal error
484 if (ud_verify_tag(h, tag, id, vds_loc, 1, 0) != 0) {
485 continue;
487 switch (id) {
488 case UD_PRI_VOL_DESC :
491 * Primary Volume Descriptor
493 /* LINTED */
494 pvd = (struct pri_vol_desc *)taddr;
495 if ((v->pvd_len == 0) ||
496 (SWAP_32(pvd->pvd_vdsn) > v->pvd_vdsn)) {
497 v->pvd_vdsn = SWAP_32(pvd->pvd_vdsn);
498 v->pvd_loc = vds_loc;
499 v->pvd_len = h->udfs.lbsize;
501 break;
502 case UD_VOL_DESC_PTR :
505 * Curent sequence is continued from
506 * the location pointed by vdp
508 /* LINTED */
509 vds = (struct vol_desc_ptr *)taddr;
511 if (SWAP_32(vds->vdp_nvdse.ext_len) != 0) {
512 vds_loc = SWAP_32(vds->vdp_nvdse.ext_loc);
513 vds_len = SWAP_32(vds->vdp_nvdse.ext_len);
514 free(addr);
515 goto begin;
517 break;
518 case UD_IMPL_USE_DESC :
521 * Implementation Use Volume Descriptor
523 v->iud_loc = vds_loc;
524 v->iud_len = lb_roundup(512, h->udfs.lbsize);
525 break;
526 case UD_PART_DESC :
528 struct ud_part *p;
529 struct phdr_desc *ph;
530 struct part_desc *pd;
533 * Partition Descriptor
535 /* LINTED */
536 pd = (struct part_desc *)taddr;
538 for (i = 0; i < h->n_parts; i++) {
539 p = &h->part[i];
541 if ((SWAP_16(pd->pd_pnum) ==
542 p->udp_number) &&
543 (SWAP_32(pd->pd_vdsn) >
544 p->udp_seqno)) {
545 break;
549 v->part_loc[i] = vds_loc;
550 v->part_len[i] =
551 lb_roundup(512, h->udfs.lbsize);
553 p = &h->part[i];
554 p->udp_number = SWAP_16(pd->pd_pnum);
555 p->udp_seqno = SWAP_32(pd->pd_vdsn);
556 p->udp_access = SWAP_32(pd->pd_acc_type);
557 p->udp_start = SWAP_32(pd->pd_part_start);
558 p->udp_length = SWAP_32(pd->pd_part_length);
560 /* LINTED */
561 ph = (struct phdr_desc *)pd->pd_pc_use;
562 if (ph->phdr_ust.sad_ext_len) {
563 p->udp_flags = UDP_SPACETBLS;
564 p->udp_unall_loc = SWAP_32(ph->phdr_ust.sad_ext_loc);
565 p->udp_unall_len = SWAP_32(ph->phdr_ust.sad_ext_len);
566 p->udp_freed_loc = SWAP_32(ph->phdr_fst.sad_ext_loc);
567 p->udp_freed_len = SWAP_32(ph->phdr_fst.sad_ext_len);
568 } else {
569 p->udp_flags = UDP_BITMAPS;
570 p->udp_unall_loc = SWAP_32(ph->phdr_usb.sad_ext_loc);
571 p->udp_unall_len = SWAP_32(ph->phdr_usb.sad_ext_len);
572 p->udp_freed_loc = SWAP_32(ph->phdr_fsb.sad_ext_loc);
573 p->udp_freed_len = SWAP_32(ph->phdr_fsb.sad_ext_len);
576 if (i == h->n_parts) {
577 h->n_parts ++;
580 break;
581 case UD_LOG_VOL_DESC :
584 * Logical Volume Descriptor
586 /* LINTED */
587 lvd = (struct log_vol_desc *)taddr;
588 if ((v->lvd_len == 0) ||
589 (SWAP_32(lvd->lvd_vdsn) > v->lvd_vdsn)) {
590 v->lvd_vdsn = SWAP_32(lvd->lvd_vdsn);
591 v->lvd_loc = vds_loc;
592 v->lvd_len = ((uint32_t)
593 &((struct log_vol_desc *)0)->lvd_pmaps);
594 v->lvd_len =
595 lb_roundup(v->lvd_len, h->udfs.lbsize);
597 break;
598 case UD_UNALL_SPA_DESC :
601 * Unallocated Space Descriptor
603 /* LINTED */
604 usd = (struct unall_spc_desc *)taddr;
605 v->usd_loc = vds_loc;
606 v->usd_len = ((uint32_t)
607 &((unall_spc_desc_t *)0)->ua_al_dsc) +
608 SWAP_32(usd->ua_nad) *
609 sizeof (struct extent_ad);
610 v->usd_len = lb_roundup(v->usd_len, h->udfs.lbsize);
611 break;
612 case UD_TERM_DESC :
614 * Success fully completed
616 goto end;
617 default :
619 * If you donot undetstand any tag just skip
620 * it. This is not a fatal error
622 break;
626 end:
627 free(addr);
628 if ((v->pvd_len == 0) ||
629 (v->part_len[0] == 0) ||
630 (v->lvd_len == 0)) {
631 return (1);
634 return (0);
637 static int32_t
638 ud_read_and_translate_lvd(ud_handle_t h, uint32_t lvd_loc, uint32_t lvd_len)
640 caddr_t addr;
641 uint16_t fsd_prn;
642 uint32_t fsd_loc, fsd_len;
643 uint32_t lvds_loc, lvds_len;
644 uint64_t off;
645 struct log_vol_desc *lvd = NULL;
647 int32_t max_maps, i, mp_sz, index;
648 struct ud_map *m;
649 struct pmap_hdr *ph;
650 struct pmap_typ1 *typ1;
651 struct pmap_typ2 *typ2;
653 if (lvd_len == 0) {
654 return (1);
657 if ((lvd = (struct log_vol_desc *)
658 malloc(lvd_len)) == NULL) {
659 return (1);
662 off = lvd_loc * h->udfs.lbsize;
663 if (ud_read_dev(h, off, (uint8_t *)lvd, lvd_len) != 0) {
664 free(lvd);
665 return (1);
668 if (ud_verify_tag(h, &lvd->lvd_tag, UD_LOG_VOL_DESC,
669 lvd_loc, 1, 0) != 0) {
670 free(lvd);
671 return (1);
675 * Take care of maps
677 max_maps = SWAP_32(lvd->lvd_num_pmaps);
678 ph = (struct pmap_hdr *)lvd->lvd_pmaps;
679 for (h->n_maps = index = 0; index < max_maps; index++) {
680 m = &h->maps[h->n_maps];
681 switch (ph->maph_type) {
682 case MAP_TYPE1 :
684 /* LINTED */
685 typ1 = (struct pmap_typ1 *)ph;
687 m->udm_flags = UDM_MAP_NORM;
688 m->udm_vsn = SWAP_16(typ1->map1_vsn);
689 m->udm_pn = SWAP_16(typ1->map1_pn);
690 h->n_maps++;
691 break;
693 case MAP_TYPE2 :
695 /* LINTED */
696 typ2 = (struct pmap_typ2 *)ph;
698 if (strncmp(typ2->map2_pti.reg_id,
699 UDF_VIRT_PART, 23) == 0) {
701 m->udm_flags = UDM_MAP_VPM;
702 m->udm_vsn = SWAP_16(typ2->map2_vsn);
703 m->udm_pn = SWAP_16(typ2->map2_pn);
704 } else if (strncmp(typ2->map2_pti.reg_id,
705 UDF_SPAR_PART, 23) == 0) {
707 if ((SWAP_16(typ2->map2_pl) != 32) ||
708 (typ2->map2_nst < 1) ||
709 (typ2->map2_nst > 4)) {
710 break;
712 m->udm_flags = UDM_MAP_SPM;
713 m->udm_vsn = SWAP_16(typ2->map2_vsn);
714 m->udm_pn = SWAP_16(typ2->map2_pn);
716 m->udm_plen = SWAP_16(typ2->map2_pl);
717 m->udm_nspm = typ2->map2_nst;
718 m->udm_spsz = SWAP_32(typ2->map2_sest);
720 mp_sz = lb_roundup(m->udm_spsz, h->udfs.lbsize);
722 if ((addr = malloc(mp_sz * m->udm_nspm)) ==
723 NULL) {
724 break;
727 for (i = 0; i < m->udm_nspm; i++) {
728 m->udm_loc[i] =
729 SWAP_32(typ2->map2_st[index]);
730 m->udm_spaddr[i] = addr + i * mp_sz;
732 off = m->udm_loc[i] * h->udfs.lbsize;
733 if (ud_read_dev(h, off,
734 (uint8_t *)m->udm_spaddr[i],
735 mp_sz) != 0) {
736 m->udm_spaddr[i] = NULL;
737 continue;
741 h->n_maps++;
742 default :
743 break;
745 ph = (struct pmap_hdr *)(((uint8_t *)h) + ph->maph_length);
748 lvds_loc = SWAP_32(lvd->lvd_int_seq_ext.ext_loc);
749 lvds_len = SWAP_32(lvd->lvd_int_seq_ext.ext_len);
751 fsd_prn = SWAP_16(lvd->lvd_lvcu.lad_ext_prn);
752 fsd_loc = SWAP_32(lvd->lvd_lvcu.lad_ext_loc);
753 fsd_len = SWAP_32(lvd->lvd_lvcu.lad_ext_len);
755 free(lvd);
758 * Get the latest LVID
760 if (ud_get_latest_lvid(h, lvds_loc, lvds_len) != 0) {
761 return (1);
764 if (ud_get_latest_fsd(h, fsd_prn, fsd_loc, fsd_len) != 0) {
765 return (1);
768 return (0);
771 static int32_t
772 ud_get_latest_lvid(ud_handle_t h, uint32_t lvds_loc, uint32_t lvds_len)
774 uint8_t *addr, *taddr, *eaddr;
775 uint16_t id;
776 uint64_t off;
777 struct tag *tag;
778 struct log_vol_int_desc *lvid;
780 begin:
781 if ((addr = (uint8_t *)malloc(lvds_len)) == NULL) {
782 return (1);
785 off = lvds_loc * h->udfs.lbsize;
786 if (ud_read_dev(h, off, addr, lvds_len) != 0) {
787 goto end;
790 for (taddr = addr, eaddr = addr + h->udfs.mvds_len; taddr < eaddr;
791 taddr += h->udfs.lbsize, lvds_loc ++) {
793 /* LINTED */
794 tag = (struct tag *)taddr;
795 id = SWAP_16(tag->tag_id);
797 * If you cannot verify the tag just skip it
798 * This is not a fatal error
800 if (ud_verify_tag(h, tag, id, lvds_loc, 1, 0) != 0) {
801 continue;
803 switch (id) {
804 case UD_LOG_VOL_INT :
807 * Logical Volume Integrity Descriptor
809 /* LINTED */
810 lvid = (struct log_vol_int_desc *)taddr;
811 h->udfs.lvid_loc = lvds_loc;
812 h->udfs.lvid_len = ((uint32_t)
813 &((struct log_vol_int_desc *)0)->lvid_fst) +
814 SWAP_32(lvid->lvid_npart) * 8 +
815 SWAP_32(lvid->lvid_liu);
816 h->udfs.lvid_len = lb_roundup(h->udfs.lvid_len,
817 h->udfs.lbsize);
820 * It seems we have a next integrity
821 * sequence
823 if (SWAP_32(lvid->lvid_nie.ext_len) != 0) {
824 free(addr);
825 lvds_loc = SWAP_32(lvid->lvid_nie.ext_loc);
826 lvds_len = SWAP_32(lvid->lvid_nie.ext_len);
827 goto begin;
829 goto end;
830 case UD_TERM_DESC :
833 * Success fully completed
835 goto end;
836 default :
838 * If you donot undetstand any tag just skip
839 * it. This is not a fatal error
841 break;
844 end:
845 free(addr);
846 if (h->udfs.lvid_len == 0) {
847 return (1);
849 return (0);
852 static int32_t
853 ud_get_latest_fsd(ud_handle_t h, uint16_t fsd_prn,
854 uint32_t fsd_loc, uint32_t fsd_len)
856 uint8_t *addr, *taddr, *eaddr;
857 uint16_t id;
858 uint64_t off;
859 uint32_t fsds_loc, fsds_len;
860 struct tag *tag;
861 struct file_set_desc *fsd;
862 uint32_t old_fsn = 0;
864 begin:
865 h->udfs.fsds_prn = fsd_prn;
866 h->udfs.fsds_loc = fsd_loc;
867 h->udfs.fsds_len = fsd_len;
869 fsds_loc = ud_xlate_to_daddr(h, fsd_prn, fsd_loc);
870 fsds_len = lb_roundup(fsd_len, h->udfs.lbsize);
872 if ((addr = (uint8_t *)malloc(fsds_len)) == NULL) {
873 return (1);
876 off = fsds_loc * h->udfs.lbsize;
877 if (ud_read_dev(h, off, addr, fsds_len) != 0) {
878 goto end;
881 for (taddr = addr, eaddr = addr + h->udfs.mvds_len; taddr < eaddr;
882 taddr += h->udfs.lbsize, fsds_loc ++) {
884 /* LINTED */
885 tag = (struct tag *)taddr;
886 id = SWAP_16(tag->tag_id);
888 * If you cannot verify the tag just skip it
889 * This is not a fatal error
891 if (ud_verify_tag(h, tag, id, fsds_loc, 1, 0) != 0) {
892 continue;
894 switch (id) {
895 case UD_FILE_SET_DESC :
896 /* LINTED */
897 fsd = (struct file_set_desc *)taddr;
898 if ((h->udfs.fsd_len == 0) ||
899 (SWAP_32(fsd->fsd_fs_no) > old_fsn)) {
900 old_fsn = SWAP_32(fsd->fsd_fs_no);
901 h->udfs.fsd_loc = fsds_loc;
902 h->udfs.fsd_len = lb_roundup(512,
903 h->udfs.lbsize);
904 h->udfs.ricb_prn =
905 SWAP_16(fsd->fsd_root_icb.lad_ext_prn);
906 h->udfs.ricb_loc =
907 SWAP_32(fsd->fsd_root_icb.lad_ext_loc);
908 h->udfs.ricb_len =
909 SWAP_32(fsd->fsd_root_icb.lad_ext_len);
911 if (SWAP_32(fsd->fsd_next.lad_ext_len) != 0) {
912 fsd_prn = SWAP_16(fsd->fsd_next.lad_ext_prn);
913 fsd_loc = SWAP_32(fsd->fsd_next.lad_ext_loc);
914 fsd_len = SWAP_32(fsd->fsd_next.lad_ext_len);
915 goto begin;
917 break;
918 case UD_TERM_DESC :
921 * Success fully completed
923 goto end;
924 default :
926 * If you donot undetstand any tag just skip
927 * it. This is not a fatal error
929 break;
933 end:
934 free(addr);
935 if (h->udfs.fsd_len == 0) {
936 return (1);
938 return (0);
941 int32_t
942 ud_get_num_blks(ud_handle_t h, uint32_t *blkno)
944 struct vtoc vtoc;
945 struct dk_cinfo dki_info;
946 int32_t error;
949 * Get VTOC from driver
951 if ((error = ioctl(h->fd, DKIOCGVTOC, (intptr_t)&vtoc)) != 0) {
952 return (error);
956 * Verify if is proper
958 if (vtoc.v_sanity != VTOC_SANE) {
959 return (EINVAL);
963 * Get dk_cinfo from driver
965 if ((error = ioctl(h->fd, DKIOCINFO, (intptr_t)&dki_info)) != 0) {
966 return (error);
969 if (dki_info.dki_partition >= V_NUMPAR) {
970 return (EINVAL);
974 * Return the size of the partition
976 *blkno = vtoc.v_part[dki_info.dki_partition].p_size;
978 return (0);
981 uint32_t
982 ud_xlate_to_daddr(ud_handle_t h, uint16_t prn, uint32_t blkno)
984 int32_t i;
985 struct ud_map *m;
986 struct ud_part *p;
989 if (prn < h->n_maps) {
990 m = &h->maps[prn];
991 for (i = 0; i < h->n_parts; i++) {
992 p = &h->part[i];
993 if (m->udm_pn == p->udp_number) {
994 return (p->udp_start + blkno);
998 return (0);
1001 /* ------ END Read and translate the on disk VDS to IN CORE format -------- */
1003 int32_t
1004 ud_verify_tag(ud_handle_t h, struct tag *tag, uint16_t id,
1005 uint32_t blockno, int32_t do_crc, int32_t print_msg)
1007 int32_t i;
1008 uint8_t *addr, cksum = 0;
1009 uint16_t crc;
1013 * Verify Tag Identifier
1015 if (tag->tag_id != SWAP_16(id)) {
1016 if (print_msg != 0) {
1017 (void) fprintf(stderr,
1018 gettext("tag does not verify tag %x req %x\n"),
1019 SWAP_16(tag->tag_id), id);
1021 return (1);
1025 * Verify Tag Descriptor Version
1027 if (SWAP_16(tag->tag_desc_ver) != h->udfs.ecma_version) {
1028 if (print_msg != 0) {
1029 (void) fprintf(stderr,
1030 gettext("tag version does not match with "
1031 "NSR descriptor version TAG %x NSR %x\n"),
1032 SWAP_16(tag->tag_desc_ver),
1033 h->udfs.ecma_version);
1035 return (1);
1039 * Caliculate Tag Checksum
1041 addr = (uint8_t *)tag;
1042 for (i = 0; i <= 15; i++) {
1043 if (i != 4) {
1044 cksum += addr[i];
1049 * Verify Tag Checksum
1051 if (cksum != tag->tag_cksum) {
1052 if (print_msg != 0) {
1053 (void) fprintf(stderr,
1054 gettext("Checksum Does not Verify TAG"
1055 " %x CALC %x\n"), tag->tag_cksum, cksum);
1057 return (1);
1062 * Do we want to do crc
1064 if (do_crc) {
1065 if (tag->tag_crc_len) {
1068 * Caliculate CRC for the descriptor
1070 crc = ud_crc(addr + 0x10, SWAP_16(tag->tag_crc_len));
1073 * Verify CRC
1075 if (crc != SWAP_16(tag->tag_crc)) {
1076 if (print_msg != 0) {
1077 (void) fprintf(stderr,
1078 gettext("CRC Does not verify"
1079 " TAG %x CALC %x %x\n"),
1080 SWAP_16(tag->tag_crc),
1081 crc, addr);
1087 * Verify Tag Location
1089 if (SWAP_32(blockno) != tag->tag_loc) {
1090 if (print_msg != 0) {
1091 (void) fprintf(stderr,
1092 gettext("Tag Location Does not verify"
1093 " blockno %x tag_blockno %x\n"),
1094 blockno, SWAP_32(tag->tag_loc));
1099 return (0);
1103 /* ARGSUSED1 */
1104 void
1105 ud_make_tag(ud_handle_t h, struct tag *tag, uint16_t tag_id,
1106 uint32_t blkno, uint16_t crc_len)
1108 int32_t i;
1109 uint16_t crc;
1110 uint8_t *addr, cksum = 0;
1112 tag->tag_id = SWAP_16(tag_id);
1113 tag->tag_desc_ver = SWAP_16(h->udfs.ecma_version);
1114 tag->tag_cksum = 0;
1115 tag->tag_res = 0;
1118 * Calicualte and assign CRC, CRC_LEN
1120 addr = (uint8_t *)tag;
1121 crc = ud_crc(addr + 0x10, crc_len);
1122 tag->tag_crc = SWAP_16(crc);
1123 tag->tag_crc_len = SWAP_16(crc_len);
1124 tag->tag_loc = SWAP_32(blkno);
1127 * Caliculate Checksum
1129 for (i = 0; i <= 15; i++) {
1130 cksum += addr[i];
1134 * Assign Checksum
1136 tag->tag_cksum = cksum;
1139 /* **************** udf specific subroutines *********************** */
1141 static uint16_t ud_crc_table[256] = {
1142 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
1143 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
1144 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
1145 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
1146 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
1147 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
1148 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
1149 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
1150 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
1151 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
1152 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
1153 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
1154 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
1155 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
1156 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
1157 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
1158 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
1159 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
1160 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
1161 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
1162 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
1163 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
1164 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
1165 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
1166 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
1167 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
1168 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
1169 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
1170 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
1171 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
1172 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
1173 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
1176 static uint16_t
1177 ud_crc(uint8_t *addr, int32_t len)
1179 uint16_t crc = 0;
1181 while (len-- > 0) {
1182 crc = ud_crc_table[(crc >> 8 ^ *addr++) & 0xff] ^ (crc<<8);
1185 return (crc);
1188 #define MAXNAMLEN 0x200
1191 #define POUND 0x0023
1192 #define DOT 0x002E
1193 #define SLASH 0x002F
1194 #define UNDERBAR 0x005F
1197 static uint16_t htoc[16] = {'0', '1', '2', '3',
1198 '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
1200 * unicode is the string of 16-bot characters
1201 * length is the number of 16-bit characters
1203 static int32_t
1204 UdfTxName(uint16_t *unicode, int32_t count)
1206 int32_t i, j, k, lic, make_crc, dot_loc;
1207 uint16_t crc;
1209 if ((unicode[0] == DOT) &&
1210 ((count == 1) || ((count == 2) && (unicode[1] == DOT)))) {
1211 crc = DOT;
1212 if (count == 2) {
1213 crc += DOT;
1215 unicode[0] = UNDERBAR;
1216 unicode[1] = POUND;
1217 unicode[2] = htoc[(uint16_t)(crc & 0xf000) >> 12];
1218 unicode[3] = htoc[(uint16_t)(crc & 0xf00) >> 8];
1219 unicode[4] = htoc[(uint16_t)(crc & 0xf0) >> 4];
1220 unicode[5] = htoc[crc & 0xf];
1221 return (6);
1223 crc = 0;
1224 j = make_crc = 0;
1225 lic = dot_loc = -1;
1226 for (i = 0; i < count; i++) {
1227 if (make_crc) {
1228 crc += unicode[i];
1230 if (unicode[i] == DOT) {
1231 dot_loc = j;
1233 if ((unicode[i] == SLASH) ||
1234 (unicode[i] == NULL)) {
1235 if (make_crc == 0) {
1236 for (k = 0; k <= i; k++) {
1237 crc += unicode[k];
1239 make_crc = 1;
1241 if (lic != (i - 1)) {
1242 unicode[j++] = UNDERBAR;
1244 lic = i;
1245 } else {
1246 unicode[j++] = unicode[i];
1250 if (make_crc) {
1251 if (dot_loc != -1) {
1252 if ((j + 5) > MAXNAMLEN) {
1253 if ((j - dot_loc + 5) > MAXNAMLEN) {
1254 j = MAXNAMLEN - 5 + dot_loc;
1255 for (k = MAXNAMLEN;
1256 j >= dot_loc; k --, j--) {
1257 unicode[k] = unicode[j];
1259 k = 0;
1260 } else {
1261 for (k = MAXNAMLEN;
1262 j >= dot_loc; k--, j--) {
1263 unicode[k] = unicode[j];
1265 k -= 4;
1267 j = MAXNAMLEN;
1268 } else {
1269 for (k = j; k >= dot_loc; k--) {
1270 unicode[k + 5] = unicode[k];
1272 k = dot_loc;
1273 j += 5;
1275 } else {
1276 if ((j + 5) > MAXNAMLEN) {
1277 j = MAXNAMLEN;
1278 k = MAXNAMLEN - 5;
1279 } else {
1280 k = j;
1281 j += 5;
1284 unicode[k++] = POUND;
1285 unicode[k++] = htoc[(uint16_t)(crc & 0xf000) >> 12];
1286 unicode[k++] = htoc[(uint16_t)(crc & 0xf00) >> 8];
1287 unicode[k++] = htoc[(uint16_t)(crc & 0xf0) >> 4];
1288 unicode[k++] = htoc[crc & 0xf];
1290 return (j);
1294 * Assumes the output buffer is large
1295 * enough to hold the uncompressed
1296 * code
1298 static int32_t
1299 UncompressUnicode(
1300 int32_t numberOfBytes, /* (Input) number of bytes read from media. */
1301 uint8_t *UDFCompressed, /* (Input) bytes read from media. */
1302 uint16_t *unicode) /* (Output) uncompressed unicode characters. */
1304 int32_t compID;
1305 int32_t returnValue, unicodeIndex, byteIndex;
1309 * Use UDFCompressed to store current byte being read.
1311 compID = UDFCompressed[0];
1313 /* First check for valid compID. */
1314 if (compID != 8 && compID != 16) {
1315 returnValue = -1;
1316 } else {
1317 unicodeIndex = 0;
1318 byteIndex = 1;
1320 /* Loop through all the bytes. */
1321 while (byteIndex < numberOfBytes) {
1322 if (compID == 16) {
1324 * Move the first byte to the
1325 * high bits of the unicode char.
1327 unicode[unicodeIndex] =
1328 UDFCompressed[byteIndex++] << 8;
1329 } else {
1330 unicode[unicodeIndex] = 0;
1332 if (byteIndex < numberOfBytes) {
1334 * Then the next byte to the low bits.
1336 unicode[unicodeIndex] |=
1337 UDFCompressed[byteIndex++];
1339 unicodeIndex++;
1341 returnValue = unicodeIndex;
1343 return (returnValue);
1350 static int32_t
1351 ud_compressunicode(
1352 int32_t numberOfChars, /* (Input) number of unicode characters. */
1353 int32_t compID, /* (Input) compression ID to be used. */
1354 uint16_t *unicode, /* (Input) unicode characters to compress. */
1355 uint8_t *UDFCompressed) /* (Output) compressed string, as bytes. */
1357 int32_t byteIndex;
1359 if (compID != 8 && compID != 16) {
1361 * Unsupported compression ID !
1363 byteIndex = -1;
1364 } else {
1366 * Place compression code in first byte.
1368 UDFCompressed[0] = (uint8_t)compID;
1369 (void) strncpy((caddr_t)&UDFCompressed[1],
1370 (caddr_t)unicode, numberOfChars);
1371 byteIndex = numberOfChars + 1;
1373 return (byteIndex);
1377 static int32_t
1378 ud_convert2utf8(uint8_t *ibuf, uint8_t *obuf, int32_t length)
1380 int i, size;
1381 uint16_t *buf;
1383 /* LINTED */
1384 buf = (uint16_t *)obuf;
1386 size = UncompressUnicode(length, ibuf, buf);
1388 size = UdfTxName(buf, size);
1390 for (i = 0; i < size; i++) {
1391 obuf[i] = (uint8_t)buf[i];
1393 obuf[i] = '\0';
1395 return (size);
1398 static int32_t
1399 ud_convert2utf16(uint8_t *ibuf, uint8_t *obuf, int32_t length)
1401 int32_t comp_len;
1402 uint16_t *ptr;
1404 /* LINTED */
1405 ptr = (uint16_t *)ibuf;
1406 comp_len = ud_compressunicode(length, 8, ptr, obuf);
1408 return (comp_len);
1412 * Assumption code set is zero in udfs
1414 void
1415 ud_convert2local(int8_t *ibuf, int8_t *obuf, int32_t length)
1417 wchar_t buf4c[128];
1418 int32_t i, comp, index;
1421 * Special uncompress code
1422 * written to accomodate solaris wchar_t
1424 comp = ibuf[0];
1425 for (i = 0, index = 1; i < length; i++) {
1426 if (comp == 16) {
1427 buf4c[i] = ibuf[index++] << 8;
1428 } else {
1429 buf4c[i] = 0;
1431 if (index < length) {
1432 buf4c[i] |= ibuf[index++];
1435 (void) wcstombs((char *)obuf, buf4c, 128);
1439 /* ------------ Routines to print basic structures Part 1 ---------------- */
1443 void
1444 print_charspec(FILE *fout, char *name, struct charspec *cspec)
1446 int i = 0;
1448 (void) fprintf(fout,
1449 "%s : %x - \"", name, cspec->cs_type);
1450 for (i = 0; i < 63; i++) {
1451 (void) fprintf(fout,
1452 "%c", cspec->cs_info[i]);
1454 (void) fprintf(fout, "\n");
1457 /* ARGSUSED */
1458 void
1459 print_dstring(FILE *fout, char *name, uint16_t cset, char *bufc, uint8_t length)
1461 int8_t bufmb[1024];
1463 ud_convert2local(bufc, bufmb, length);
1465 (void) fprintf(fout,
1466 "%s %s\n", name, bufmb);
1469 void
1470 set_dstring(dstring_t *dp, char *cp, int32_t len)
1472 int32_t length;
1474 bzero(dp, len);
1475 length = strlen(cp);
1476 if (length > len - 1) {
1477 length = len - 1;
1479 (void) strncpy(dp, cp, length);
1480 dp[len - 1] = length;
1483 void
1484 print_tstamp(FILE *fout, char *name, tstamp_t *ts)
1486 (void) fprintf(fout, "%s tz : %d yr : %d mo : %d da : %d "
1487 "Time : %d : %d : %d : %d : %d : %d\n", name,
1488 SWAP_16(ts->ts_tzone), SWAP_16(ts->ts_year), ts->ts_month,
1489 ts->ts_day, ts->ts_hour, ts->ts_min, ts->ts_sec, ts->ts_csec,
1490 ts->ts_husec, ts->ts_usec);
1495 void
1496 make_regid(ud_handle_t h, struct regid *reg, char *id, int32_t type)
1498 reg->reg_flags = 0;
1499 (void) strncpy(reg->reg_id, id, 23);
1501 if (type == REG_DOM_ID) {
1502 struct dom_id_suffix *dis;
1504 /* LINTED */
1505 dis = (struct dom_id_suffix *)reg->reg_ids;
1506 dis->dis_udf_revison = SWAP_16(h->udfs.ma_write);
1507 dis->dis_domain_flags = 0;
1509 } else if (type == REG_UDF_ID) {
1510 struct udf_id_suffix *uis;
1512 /* LINTED */
1513 uis = (struct udf_id_suffix *)reg->reg_ids;
1514 uis->uis_udf_revision = SWAP_16(h->udfs.ma_write);
1515 uis->uis_os_class = OS_CLASS_UNIX;
1516 uis->uis_os_identifier = OS_IDENTIFIER_SOLARIS;
1517 } else if (type == REG_UDF_II) {
1518 struct impl_id_suffix *iis;
1520 iis = (struct impl_id_suffix *)reg->reg_ids;
1521 iis->iis_os_class = OS_CLASS_UNIX;
1522 iis->iis_os_identifier = OS_IDENTIFIER_SOLARIS;
1526 void
1527 print_regid(FILE *fout, char *name, struct regid *reg, int32_t type)
1529 (void) fprintf(fout, "%s : 0x%x : \"%s\" :",
1530 name, reg->reg_flags, reg->reg_id);
1532 if (type == REG_DOM_ID) {
1533 struct dom_id_suffix *dis;
1535 /* LINTED */
1536 dis = (struct dom_id_suffix *)reg->reg_ids;
1537 (void) fprintf(fout, " 0x%x : %s : %s\n",
1538 SWAP_16(dis->dis_udf_revison),
1539 (dis->dis_domain_flags & PROTECT_SOFT_WRITE) ?
1540 "HW Protect" : "No HW Write Protect",
1541 (dis->dis_domain_flags & PROTECT_HARD_WRITE) ?
1542 "SW Protect" : "No SW Protect");
1543 } else if (type == REG_UDF_ID) {
1544 struct udf_id_suffix *uis;
1546 /* LINTED */
1547 uis = (struct udf_id_suffix *)reg->reg_ids;
1548 (void) fprintf(fout,
1549 " 0x%x : OS Class 0x%x : OS Identifier 0x%x\n",
1550 SWAP_16(uis->uis_udf_revision),
1551 uis->uis_os_class, uis->uis_os_identifier);
1552 } else {
1553 struct impl_id_suffix *iis;
1555 iis = (struct impl_id_suffix *)reg->reg_ids;
1556 (void) fprintf(fout,
1557 " OS Class 0x%x : OS Identifier 0x%x\n",
1558 iis->iis_os_class, iis->iis_os_identifier);
1562 #ifdef OLD
1563 void
1564 print_regid(FILE *fout, char *name, struct regid *reg)
1566 (void) fprintf(fout, "%s : 0x%x : \"%s\" :",
1567 name, reg->reg_flags, reg->reg_id);
1569 if (strncmp(reg->reg_id, "*OSTA UDF Compliant", 19) == 0) {
1570 (void) fprintf(fout, " 0x%x : %s : %s\n",
1571 reg->reg_ids[0] | (reg->reg_ids[1] << 8),
1572 (reg->reg_ids[2] & 1) ?
1573 "HW Protect" : "No HW Write Protect",
1574 (reg->reg_ids[2] & 2) ?
1575 "SW Protect" : "No SW Protect");
1576 } else if ((strncmp(reg->reg_id, "*UDF Virtual Partition", 22) == 0) ||
1577 (strncmp(reg->reg_id, "*UDF Sparable Partition", 23) == 0) ||
1578 (strncmp(reg->reg_id, "*UDF Virtual Alloc Tbl", 22) == 0) ||
1579 (strncmp(reg->reg_id, "*UDF Sparing Table", 18) == 0)) {
1580 (void) fprintf(fout,
1581 " 0x%x : OS Class 0x%x : OS Identifier 0x%x\n",
1582 reg->reg_ids[0] | (reg->reg_ids[1] << 8),
1583 reg->reg_ids[2], reg->reg_ids[3]);
1584 } else {
1585 (void) fprintf(fout,
1586 " OS Class 0x%x : OS Identifier 0x%x\n",
1587 reg->reg_ids[0], reg->reg_ids[1]);
1590 #endif
1593 /* ------------ Routines to print basic structures Part 2 ---------------- */
1595 * Part 2
1596 * This part is OS specific and is currently
1597 * not supported
1600 /* ------------ Routines to print basic structures Part 3 ---------------- */
1602 void
1603 print_ext_ad(FILE *fout, char *name, struct extent_ad *ead)
1605 (void) fprintf(fout,
1606 "%s EAD Len %x Loc %x\n",
1607 name, SWAP_32(ead->ext_len), SWAP_32(ead->ext_loc));
1610 void
1611 print_tag(FILE *fout, struct tag *tag)
1613 (void) fprintf(fout,
1614 "tag_id : %x ver : %x cksum : %x "
1615 "sno : %x crc : %x crc_len : %x loc : %x\n",
1616 SWAP_16(tag->tag_id), SWAP_16(tag->tag_desc_ver),
1617 tag->tag_cksum, SWAP_16(tag->tag_sno),
1618 SWAP_16(tag->tag_crc), SWAP_16(tag->tag_crc_len),
1619 SWAP_32(tag->tag_loc));
1623 void
1624 print_pvd(FILE *fout, struct pri_vol_desc *pvd)
1626 (void) fprintf(fout,
1627 "\n\t\t\tPrimary Volume Descriptor\n");
1628 print_tag(fout, &pvd->pvd_tag);
1629 (void) fprintf(fout, "vdsn : %x vdn : %x\n",
1630 SWAP_32(pvd->pvd_vdsn), SWAP_32(pvd->pvd_pvdn));
1631 print_dstring(fout, "volid : ", pvd->pvd_desc_cs.cs_type,
1632 pvd->pvd_vol_id, 32);
1633 (void) fprintf(fout,
1634 "vsn : %x mvsn : %x il : %x mil :"
1635 " %x csl : %x mcsl %x\n",
1636 SWAP_16(pvd->pvd_vsn), SWAP_16(pvd->pvd_mvsn),
1637 SWAP_16(pvd->pvd_il), SWAP_16(pvd->pvd_mil),
1638 SWAP_32(pvd->pvd_csl), SWAP_32(pvd->pvd_mcsl));
1639 print_dstring(fout, "vsid :", pvd->pvd_desc_cs.cs_type,
1640 pvd->pvd_vsi, 128);
1641 print_charspec(fout, "desc_cs", &pvd->pvd_desc_cs);
1642 print_charspec(fout, "exp_cs", &pvd->pvd_exp_cs);
1643 print_ext_ad(fout, "val ", &pvd->pvd_vol_abs);
1644 print_ext_ad(fout, "vcnl ", &pvd->pvd_vcn);
1645 print_regid(fout, "ai", &pvd->pvd_appl_id, REG_UDF_II);
1646 print_regid(fout, "ii", &pvd->pvd_ii, REG_UDF_II);
1647 (void) fprintf(fout, "pvdsl : %x flags : %x\n",
1648 SWAP_32(pvd->pvd_pvdsl),
1649 SWAP_16(pvd->pvd_flags));
1652 void
1653 print_avd(FILE *fout, struct anch_vol_desc_ptr *avdp)
1655 (void) fprintf(fout,
1656 "\n\t\t\tAnchor Volume Descriptor\n");
1657 print_tag(fout, &avdp->avd_tag);
1658 print_ext_ad(fout, "Main Volume Descriptor Sequence : ",
1659 &avdp->avd_main_vdse);
1660 print_ext_ad(fout, "Reserve Volume Descriptor Sequence : ",
1661 &avdp->avd_res_vdse);
1664 void
1665 print_vdp(FILE *fout, struct vol_desc_ptr *vdp)
1667 (void) fprintf(fout,
1668 "\n\t\t\tVolume Descriptor Pointer\n");
1669 print_tag(fout, &vdp->vdp_tag);
1670 (void) fprintf(fout, "vdsn : %x ",
1671 SWAP_32(vdp->vdp_vdsn));
1672 print_ext_ad(fout, "vdse ", &vdp->vdp_nvdse);
1675 void
1676 print_iuvd(FILE *fout, struct iuvd_desc *iuvd)
1678 (void) fprintf(fout,
1679 "\n\t\t\tImplementation Use Volume Descriptor\n");
1680 print_tag(fout, &iuvd->iuvd_tag);
1681 (void) fprintf(fout,
1682 "vdsn : %x ", SWAP_32(iuvd->iuvd_vdsn));
1683 print_regid(fout, "Impl Id : ", &iuvd->iuvd_ii, REG_UDF_ID);
1684 print_charspec(fout, "cset ", &iuvd->iuvd_cset);
1685 print_dstring(fout, "lvi : ", iuvd->iuvd_cset.cs_type,
1686 iuvd->iuvd_lvi, 128);
1687 print_dstring(fout, "ifo1 : ", iuvd->iuvd_cset.cs_type,
1688 iuvd->iuvd_ifo1, 36);
1689 print_dstring(fout, "ifo2 : ", iuvd->iuvd_cset.cs_type,
1690 iuvd->iuvd_ifo2, 36);
1691 print_dstring(fout, "ifo3 : ", iuvd->iuvd_cset.cs_type,
1692 iuvd->iuvd_ifo3, 36);
1694 print_regid(fout, "iid ", &iuvd->iuvd_iid, REG_UDF_II);
1697 void
1698 print_part(FILE *fout, struct part_desc *pd)
1700 (void) fprintf(fout,
1701 "\n\t\t\tPartition Descriptor\n");
1702 print_tag(fout, &pd->pd_tag);
1703 (void) fprintf(fout,
1704 "vdsn : %x flags : %x num : %x ",
1705 SWAP_32(pd->pd_vdsn),
1706 SWAP_16(pd->pd_pflags),
1707 SWAP_16(pd->pd_pnum));
1708 print_regid(fout, "contents ", &pd->pd_pcontents, REG_UDF_II);
1709 /* LINTED */
1710 print_phdr(fout, (struct phdr_desc *)(&pd->pd_pc_use));
1711 (void) fprintf(fout,
1712 "acc : %x start : %x length : %x ",
1713 SWAP_32(pd->pd_acc_type),
1714 SWAP_32(pd->pd_part_start),
1715 SWAP_32(pd->pd_part_length));
1716 print_regid(fout, "Impl Id : ", &pd->pd_ii, REG_UDF_II);
1719 void
1720 print_lvd(FILE *fout, struct log_vol_desc *lvd)
1722 (void) fprintf(fout,
1723 "\n\t\t\tLogical Volume Descriptor\n");
1724 print_tag(fout, &lvd->lvd_tag);
1725 (void) fprintf(fout,
1726 "vdsn : %x ", SWAP_32(lvd->lvd_vdsn));
1727 print_charspec(fout, "Desc Char Set ", &lvd->lvd_desc_cs);
1728 print_dstring(fout, "lvid : ", lvd->lvd_desc_cs.cs_type,
1729 lvd->lvd_lvid, 28);
1730 (void) fprintf(fout,
1731 "lbsize : %x ",
1732 SWAP_32(lvd->lvd_log_bsize));
1733 print_regid(fout, "Dom Id", &lvd->lvd_dom_id, REG_DOM_ID);
1734 print_long_ad(fout, "lvcu", &lvd->lvd_lvcu);
1735 (void) fprintf(fout,
1736 "mtlen : %x nmaps : %x ",
1737 SWAP_32(lvd->lvd_mtbl_len),
1738 SWAP_32(lvd->lvd_num_pmaps));
1739 print_regid(fout, "Impl Id : ", &lvd->lvd_ii, REG_UDF_II);
1740 print_ext_ad(fout, "Int Seq", &lvd->lvd_int_seq_ext);
1741 print_pmaps(fout, lvd->lvd_pmaps, SWAP_32(lvd->lvd_num_pmaps));
1744 void
1745 print_usd(FILE *fout, struct unall_spc_desc *ua)
1747 int32_t i, count;
1749 (void) fprintf(fout,
1750 "\n\t\t\tUnallocated Space Descriptor\n");
1751 print_tag(fout, &ua->ua_tag);
1752 count = SWAP_32(ua->ua_nad);
1753 (void) fprintf(fout,
1754 "vdsn : %x nad : %x\n",
1755 SWAP_32(ua->ua_vdsn), count);
1756 for (i = 0; i < count; i++) {
1757 (void) fprintf(fout,
1758 "loc : %x len : %x\n",
1759 SWAP_32(ua->ua_al_dsc[i * 2]),
1760 SWAP_32(ua->ua_al_dsc[i * 2 + 1]));
1764 void
1765 print_lvid(FILE *fout, struct log_vol_int_desc *lvid)
1767 int32_t i, count;
1768 caddr_t addr;
1769 struct lvid_iu *liu;
1771 (void) fprintf(fout,
1772 "\n\t\t\tLogical Volume Integrity Descriptor\n");
1773 print_tag(fout, &lvid->lvid_tag);
1774 print_tstamp(fout, "Rec TM ", &lvid->lvid_tstamp);
1775 if (SWAP_32(lvid->lvid_int_type) == 0) {
1776 (void) fprintf(fout,
1777 "int_typ : Open\n");
1778 } else if (SWAP_32(lvid->lvid_int_type) == 1) {
1779 (void) fprintf(fout, "int_typ : Closed\n");
1780 } else {
1781 (void) fprintf(fout, "int_typ : Unknown\n");
1783 print_ext_ad(fout, "Nie ", &lvid->lvid_nie);
1784 count = SWAP_32(lvid->lvid_npart);
1785 (void) fprintf(fout,
1786 "Uniq : %llx npart : %x liu : %x\n",
1787 SWAP_64(lvid->lvid_lvcu.lvhd_uniqid),
1788 count, SWAP_32(lvid->lvid_liu));
1789 for (i = 0; i < count; i++) {
1790 (void) fprintf(fout,
1791 "Part : %x Free : %x Size : %x\n",
1792 i, SWAP_32(lvid->lvid_fst[i]),
1793 SWAP_32(lvid->lvid_fst[count + i]));
1796 addr = (caddr_t)lvid->lvid_fst;
1797 /* LINTED */
1798 liu = (struct lvid_iu *)(addr + 2 * count * 4);
1799 print_regid(fout, "Impl Id :", &liu->lvidiu_regid, REG_UDF_II);
1800 (void) fprintf(fout,
1801 "nfiles : %x ndirs : %x miread : %x"
1802 " miwrite : %x mawrite : %x\n",
1803 SWAP_32(liu->lvidiu_nfiles), SWAP_32(liu->lvidiu_ndirs),
1804 SWAP_16(liu->lvidiu_mread), SWAP_16(liu->lvidiu_mwrite),
1805 SWAP_16(liu->lvidiu_maxwr));
1809 /* ------------ Routines to print basic structures Part 4 ---------------- */
1811 void
1812 print_fsd(FILE *fout, ud_handle_t h, struct file_set_desc *fsd)
1814 (void) fprintf(fout,
1815 "\n\t\t\tFile Set Descriptor\n");
1817 print_tag(fout, &fsd->fsd_tag);
1818 print_tstamp(fout, "Rec TM ", &fsd->fsd_time);
1819 (void) fprintf(fout,
1820 "ilvl : %x milvl : %x csl : %x"
1821 " mcsl : %x fsn : %x fsdn : %x\n",
1822 SWAP_16(fsd->fsd_ilevel), SWAP_16(fsd->fsd_mi_level),
1823 SWAP_32(fsd->fsd_cs_list), SWAP_32(fsd->fsd_mcs_list),
1824 SWAP_32(fsd->fsd_fs_no), SWAP_32(fsd->fsd_fsd_no));
1825 print_charspec(fout, "ID CS ", &fsd->fsd_lvidcs);
1826 print_dstring(fout, "lvi : ", fsd->fsd_lvidcs.cs_type,
1827 fsd->fsd_lvid, 128);
1828 print_charspec(fout, "ID CS ", &fsd->fsd_fscs);
1829 print_dstring(fout, "fsi : ", fsd->fsd_lvidcs.cs_type,
1830 fsd->fsd_fsi, 32);
1831 print_dstring(fout, "cfi : ", fsd->fsd_lvidcs.cs_type,
1832 fsd->fsd_cfi, 32);
1833 print_dstring(fout, "afi : ", fsd->fsd_lvidcs.cs_type,
1834 fsd->fsd_afi, 32);
1835 print_long_ad(fout, "Ricb ", &fsd->fsd_root_icb);
1836 print_regid(fout, "DI ", &fsd->fsd_did, REG_DOM_ID);
1837 print_long_ad(fout, "Next Fsd ", &fsd->fsd_next);
1838 if (h->udfs.ecma_version == UD_ECMA_VER3) {
1839 print_long_ad(fout, "System Stream Directory ICB ",
1840 &fsd->fsd_next);
1844 void
1845 print_phdr(FILE *fout, struct phdr_desc *ph)
1847 print_short_ad(fout, "ust ", &ph->phdr_ust);
1848 print_short_ad(fout, "usb ", &ph->phdr_usb);
1849 print_short_ad(fout, "int ", &ph->phdr_it);
1850 print_short_ad(fout, "fst ", &ph->phdr_fst);
1851 print_short_ad(fout, "fsh ", &ph->phdr_fsb);
1854 void
1855 print_fid(FILE *fout, struct file_id *fid)
1857 int32_t i;
1858 uint8_t *addr;
1860 (void) fprintf(fout,
1861 "File Identifier Descriptor\n");
1862 print_tag(fout, &fid->fid_tag);
1863 (void) fprintf(fout, "fvn : %x fc : %x length : %x ",
1864 fid->fid_ver, fid->fid_flags, fid->fid_idlen);
1865 print_long_ad(fout, "ICB", &fid->fid_icb);
1866 addr = &fid->fid_spec[SWAP_16(fid->fid_iulen)];
1867 (void) fprintf(fout, "iulen : %x comp : %x name : ",
1868 SWAP_16(fid->fid_iulen), *addr);
1869 addr++;
1870 for (i = 0; i < fid->fid_idlen; i++) {
1871 (void) fprintf(fout, "%c", *addr++);
1873 (void) fprintf(fout, "\n");
1876 void
1877 print_aed(FILE *fout, struct alloc_ext_desc *aed)
1879 (void) fprintf(fout,
1880 "Allocation Extent Descriptor\n");
1881 print_tag(fout, &aed->aed_tag);
1882 (void) fprintf(fout, "prev ael loc : %x laed : %x\n",
1883 SWAP_32(aed->aed_rev_ael), SWAP_32(aed->aed_len_aed));
1886 static char *ftype[] = {
1887 "NON", "USE", "PIE", "IE",
1888 "DIR", "REG", "BDEV", "CDEV",
1889 "EATT", "FIFO", "SOCK", "TERM",
1890 "SYML", "SDIR"
1893 void
1894 print_icb_tag(FILE *fout, struct icb_tag *itag)
1896 (void) fprintf(fout,
1897 "prnde : %x strat : %x param : %x max_ent %x\n",
1898 SWAP_32(itag->itag_prnde), SWAP_16(itag->itag_strategy),
1899 SWAP_16(itag->itag_param), SWAP_16(itag->itag_max_ent));
1900 (void) fprintf(fout,
1901 "ftype : %s prn : %x loc : %x flags : %x\n",
1902 (itag->itag_ftype >= 14) ? ftype[0] : ftype[itag->itag_ftype],
1903 SWAP_16(itag->itag_lb_prn),
1904 SWAP_32(itag->itag_lb_loc), SWAP_16(itag->itag_flags));
1908 void
1909 print_ie(FILE *fout, struct indirect_entry *ie)
1911 (void) fprintf(fout,
1912 "Indirect Entry\n");
1913 print_tag(fout, &ie->ie_tag);
1914 print_icb_tag(fout, &ie->ie_icb_tag);
1915 print_long_ad(fout, "ICB", &ie->ie_indirecticb);
1918 void
1919 print_td(FILE *fout, struct term_desc *td)
1921 (void) fprintf(fout,
1922 "Terminating Descriptor\n");
1923 print_tag(fout, &td->td_tag);
1926 void
1927 print_fe(FILE *fout, struct file_entry *fe)
1929 (void) fprintf(fout,
1930 "File Entry\n");
1931 print_tag(fout, &fe->fe_tag);
1932 print_icb_tag(fout, &fe->fe_icb_tag);
1933 (void) fprintf(fout,
1934 "uid : %x gid : %x perms : %x nlnk : %x\n",
1935 SWAP_32(fe->fe_uid), SWAP_32(fe->fe_gid),
1936 SWAP_32(fe->fe_perms), SWAP_16(fe->fe_lcount));
1937 (void) fprintf(fout,
1938 "rec_for : %x rec_dis : %x rec_len : %x "
1939 "sz : %llx blks : %llx\n",
1940 fe->fe_rec_for, fe->fe_rec_dis, SWAP_32(fe->fe_rec_len),
1941 SWAP_64(fe->fe_info_len), SWAP_64(fe->fe_lbr));
1942 print_tstamp(fout, "ctime ", &fe->fe_acc_time);
1943 print_tstamp(fout, "mtime ", &fe->fe_mod_time);
1944 print_tstamp(fout, "atime ", &fe->fe_attr_time);
1945 (void) fprintf(fout,
1946 "ckpoint : %x ", SWAP_32(fe->fe_ckpoint));
1947 print_long_ad(fout, "ICB", &fe->fe_ea_icb);
1948 print_regid(fout, "impl", &fe->fe_impl_id, REG_UDF_II);
1949 (void) fprintf(fout,
1950 "uniq_id : %llx len_ear : %x len_adesc %x\n",
1951 SWAP_64(fe->fe_uniq_id), SWAP_32(fe->fe_len_ear),
1952 SWAP_32(fe->fe_len_adesc));
1955 void
1956 print_pmaps(FILE *fout, uint8_t *addr, int32_t count)
1958 struct pmap_hdr *hdr;
1959 struct pmap_typ1 *map1;
1960 struct pmap_typ2 *map2;
1962 while (count--) {
1963 hdr = (struct pmap_hdr *)addr;
1964 switch (hdr->maph_type) {
1965 case 1 :
1966 /* LINTED */
1967 map1 = (struct pmap_typ1 *)hdr;
1968 (void) fprintf(fout, "Map type 1 ");
1969 (void) fprintf(fout, "VSN %x prn %x\n",
1970 SWAP_16(map1->map1_vsn),
1971 SWAP_16(map1->map1_pn));
1972 break;
1973 case 2 :
1974 /* LINTED */
1975 map2 = (struct pmap_typ2 *)hdr;
1976 (void) fprintf(fout, "Map type 2 ");
1977 (void) fprintf(fout, "VSN %x prn %x\n",
1978 SWAP_16(map2->map2_vsn),
1979 SWAP_16(map2->map2_pn));
1980 print_regid(fout, "Partition Type Identifier",
1981 &map2->map2_pti, REG_UDF_ID);
1982 break;
1983 default :
1984 (void) fprintf(fout, "unknown map type\n");
1986 addr += hdr->maph_length;
1992 void
1993 print_short_ad(FILE *fout, char *name, struct short_ad *sad)
1995 (void) fprintf(fout,
1996 "%s loc : %x len : %x\n", name,
1997 SWAP_32(sad->sad_ext_loc), SWAP_32(sad->sad_ext_len));
2000 void
2001 print_long_ad(FILE *fout, char *name, struct long_ad *lad)
2003 (void) fprintf(fout,
2004 "%s prn : %x loc : %x len : %x\n", name,
2005 SWAP_16(lad->lad_ext_prn), SWAP_32(lad->lad_ext_loc),
2006 SWAP_32(lad->lad_ext_len));