dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / fs.d / udfs / fstyp / ud_lib.c
blobf42c6eea0b0555fb656e63aacf1335eb544f472d
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 #include <stdio.h>
27 #include <stdlib.h>
28 #include <malloc.h>
29 #include <unistd.h>
30 #include <strings.h>
31 #include <errno.h>
32 #include <libintl.h>
33 #include <libgen.h>
34 #include <fcntl.h>
35 #include <sys/types.h>
36 #include <sys/int_types.h>
37 #include <sys/dkio.h>
38 #include <sys/cdio.h>
39 #include <sys/vtoc.h>
40 #include <sys/stat.h>
41 #include <sys/param.h>
42 #include <sys/fs/udf_volume.h>
43 #include "ud_lib.h"
45 extern char *getfullrawname(char *);
47 static int32_t ud_get_ecma_ver(ud_handle_t, uint32_t);
48 static int32_t ud_get_fs_bsize(ud_handle_t, uint32_t, uint32_t *);
49 static int32_t ud_parse_fill_vds(ud_handle_t, struct vds *, uint32_t, uint32_t);
50 static int32_t ud_read_and_translate_lvd(ud_handle_t, uint32_t, uint32_t);
51 static int32_t ud_get_latest_lvid(ud_handle_t, uint32_t, uint32_t);
52 static int32_t ud_get_latest_fsd(ud_handle_t, uint16_t, uint32_t, uint32_t);
54 static uint16_t ud_crc(uint8_t *, int32_t);
55 static int32_t UdfTxName(uint16_t *, int32_t);
56 static int32_t UncompressUnicode(int32_t, uint8_t *, uint16_t *);
57 static int32_t ud_compressunicode(int32_t, int32_t, uint16_t *, uint8_t *);
58 static int32_t ud_convert2utf8(uint8_t *, uint8_t *, int32_t);
59 static int32_t ud_convert2utf16(uint8_t *, uint8_t *, int32_t);
62 int
63 ud_init(int fd, ud_handle_t *hp)
65 struct ud_handle *h;
67 if ((h = calloc(1, sizeof (struct ud_handle))) == NULL) {
68 return (ENOMEM);
70 h->fd = fd;
71 *hp = h;
72 return (0);
75 void
76 ud_fini(ud_handle_t h)
78 free(h);
81 /* ARGSUSED */
82 int32_t
83 ud_open_dev(ud_handle_t h, char *special, uint32_t flags)
85 char *temp;
86 struct stat i_stat, r_stat;
88 (void) bzero(&i_stat, sizeof (struct stat));
89 (void) bzero(&r_stat, sizeof (struct stat));
92 * Get the stat structure
94 if (stat(special, &i_stat) < 0) {
95 temp = special;
96 } else {
98 if ((i_stat.st_mode & S_IFMT) == S_IFCHR) {
101 * If Raw deivce is given use it as it is
104 temp = special;
105 } else if ((i_stat.st_mode & S_IFMT) == S_IFBLK) {
108 * Block device try to convert to raw device
111 temp = getfullrawname(special);
114 * Stat the converted device name and verify
115 * both the raw and block device belong to
116 * the same device
118 if (stat(temp, &r_stat) < 0) {
119 temp = special;
120 } else {
121 if (((r_stat.st_mode & S_IFMT) == S_IFBLK) ||
122 (r_stat.st_rdev != i_stat.st_rdev)) {
123 temp = special;
130 * Now finally open the device
132 h->fd = open(temp, flags);
134 return (h->fd);
137 /* ARGSUSED */
138 void
139 ud_close_dev(ud_handle_t h)
142 * Too simple Just close it
144 (void) close(h->fd);
147 int32_t
148 ud_read_dev(ud_handle_t h, uint64_t offset, uint8_t *buf, uint32_t count)
151 * Seek to the given offset
153 if (lseek(h->fd, offset, SEEK_SET) == -1) {
154 return (1);
158 * Read the required number of bytes
160 if (read(h->fd, buf, count) != count) {
161 return (1);
163 return (0);
166 int32_t
167 ud_write_dev(ud_handle_t h, uint64_t offset, uint8_t *buf, uint32_t count)
170 * Seek to the given offset
172 if (lseek(h->fd, offset, SEEK_SET) == -1) {
173 return (1);
177 * Read the appropriate number of bytes
179 if (write(h->fd, buf, count) != count) {
180 return (1);
182 return (0);
185 /* ----- BEGIN Read and translate the on disk VDS to IN CORE format -------- */
187 int32_t
188 ud_fill_udfs_info(ud_handle_t h)
190 struct anch_vol_desc_ptr *avdp = NULL;
191 uint32_t offset = 0;
193 if (ioctl(h->fd, CDROMREADOFFSET, &offset) == -1) {
194 offset = 0;
197 h->udfs.flags = INVALID_UDFS;
199 h->udfs.ecma_version = ud_get_ecma_ver(h, offset);
200 if (h->udfs.ecma_version == UD_ECMA_UNKN) {
201 return (1);
204 h->udfs.lbsize = ud_get_fs_bsize(h, offset, &h->udfs.avdp_loc);
205 if (h->udfs.lbsize == 0) {
206 return (2);
209 h->udfs.avdp_len = lb_roundup(512, h->udfs.lbsize);
212 if ((avdp = (struct anch_vol_desc_ptr *)
213 malloc(h->udfs.lbsize)) == NULL) {
214 return (3);
216 if (ud_read_dev(h, h->udfs.avdp_loc * h->udfs.lbsize,
217 (uint8_t *)avdp, h->udfs.lbsize) != 0) {
218 free(avdp);
219 return (4);
221 if (ud_verify_tag(h, &avdp->avd_tag, UD_ANCH_VOL_DESC,
222 h->udfs.avdp_loc, 1, 0) != 0) {
223 free(avdp);
224 return (5);
227 h->udfs.mvds_loc = SWAP_32(avdp->avd_main_vdse.ext_loc);
228 h->udfs.mvds_len = SWAP_32(avdp->avd_main_vdse.ext_len);
230 h->udfs.rvds_loc = SWAP_32(avdp->avd_res_vdse.ext_loc);
231 h->udfs.rvds_len = SWAP_32(avdp->avd_res_vdse.ext_len);
233 free(avdp);
236 * get information from mvds and rvds
238 if (ud_parse_fill_vds(h, &h->udfs.mvds,
239 h->udfs.mvds_loc, h->udfs.mvds_len) == 0) {
240 h->udfs.flags |= VALID_MVDS;
242 if (ud_parse_fill_vds(h, &h->udfs.rvds,
243 h->udfs.rvds_loc, h->udfs.rvds_len) == 0) {
244 h->udfs.flags |= VALID_RVDS;
247 if ((h->udfs.flags & (VALID_MVDS | VALID_RVDS)) == 0) {
248 return (6);
252 * If we are here we have
253 * a valid Volume Descriptor Seqence
254 * Read and understand lvd
256 if (h->udfs.flags & VALID_MVDS) {
257 if (ud_read_and_translate_lvd(h, h->udfs.mvds.lvd_loc,
258 h->udfs.mvds.lvd_len) != 0) {
259 return (7);
261 } else {
262 if (ud_read_and_translate_lvd(h, h->udfs.rvds.lvd_loc,
263 h->udfs.rvds.lvd_len) != 0) {
264 return (8);
268 h->udfs.flags |= VALID_UDFS;
270 return (0);
273 static int32_t
274 ud_get_ecma_ver(ud_handle_t h, uint32_t offset)
276 uint8_t *buf;
277 uint64_t off;
278 uint64_t end_off;
279 struct nsr_desc *ndsc;
280 uint32_t ecma_ver = UD_ECMA_UNKN;
283 * Allocate a buffer of size UD_VOL_REC_BSZ
285 if ((buf = (uint8_t *)malloc(UD_VOL_REC_BSZ)) == NULL) {
288 * Uh could not even allocate this much
290 goto end;
294 * Start from 32k and keep reading 2k blocks we
295 * should be able to find NSR if we have one by 256 * 2k bytes
297 off = offset * 2048 + UD_VOL_REC_START;
298 end_off = offset * 2048 + UD_VOL_REC_END;
299 for (; off < end_off; off += UD_VOL_REC_BSZ) {
301 if (ud_read_dev(h, off, buf, UD_VOL_REC_BSZ) == 0) {
303 ndsc = (struct nsr_desc *)buf;
305 * Is this either NSR02 or NSR03
307 if ((ndsc->nsr_str_type == 0) &&
308 (ndsc->nsr_ver == 1) &&
309 (ndsc->nsr_id[0] == 'N') &&
310 (ndsc->nsr_id[1] == 'S') &&
311 (ndsc->nsr_id[2] == 'R') &&
312 (ndsc->nsr_id[3] == '0') &&
313 ((ndsc->nsr_id[4] == '2') ||
314 (ndsc->nsr_id[4] == '3'))) {
316 (void) strncpy((char *)h->udfs.ecma_id,
317 (char *)ndsc->nsr_id, 5);
319 switch (ndsc->nsr_id[4]) {
320 case '2' :
323 * ECMA 167/2
325 ecma_ver = UD_ECMA_VER2;
326 goto end;
327 case '3' :
330 * ECMA 167/3
332 ecma_ver = UD_ECMA_VER3;
333 goto end;
339 end:
341 * Cleanup
343 free(buf);
344 return (ecma_ver);
347 static uint32_t last_block_index[] = {0, 0, 256, 2, 2 + 256,
348 150, 150 + 256, 152, 152 + 256};
350 static int32_t
351 ud_get_fs_bsize(ud_handle_t h, uint32_t offset, uint32_t *avd_loc)
353 uint64_t off;
354 int32_t index, bsize, shift, end_index;
355 uint32_t num_blocks, sub_blk;
356 uint8_t *buf = NULL;
357 struct anch_vol_desc_ptr *avdp;
359 if ((buf = (uint8_t *)malloc(MAXBSIZE)) == NULL) {
360 return (0);
364 * If we could figure out the last block
365 * search at 256, N, N - 256 blocks
366 * otherwise just check at 256
368 if (ud_get_num_blks(h, &num_blocks) != 0) {
369 end_index = 1;
370 num_blocks = 0;
371 } else {
372 end_index = sizeof (last_block_index) / 4;
375 for (index = 0; index < end_index; index++) {
376 sub_blk = last_block_index[index];
379 * Start guessing from DEV_BSIZE to MAXBSIZE
381 for (bsize = DEV_BSIZE, shift = 0;
382 bsize <= MAXBSIZE; bsize <<= 1, shift++) {
384 if (index == 0) {
387 * Check if we atleast have 256 of bsize
388 * blocks on the device
390 if ((end_index == 0) ||
391 (num_blocks > (256 << shift))) {
392 *avd_loc = 256;
393 if (bsize <= 2048) {
394 *avd_loc +=
395 offset * 2048 / bsize;
396 } else {
397 *avd_loc +=
398 offset / (bsize / 2048);
400 } else {
401 continue;
403 } else {
405 * Calculate the bsize avd block
407 if ((num_blocks) &&
408 (num_blocks > (sub_blk << shift))) {
409 *avd_loc = (num_blocks >> shift) -
410 sub_blk;
411 } else {
412 continue;
416 off = (uint64_t)*avd_loc * bsize;
419 * Read bsize bytes at off
421 if (ud_read_dev(h, off, buf, bsize) != 0) {
422 continue;
426 * Check if we have a Anchor Volume Descriptor here
429 /* LINTED */
430 avdp = (struct anch_vol_desc_ptr *)buf;
431 if (ud_verify_tag(h, &avdp->avd_tag,
432 UD_ANCH_VOL_DESC, *avd_loc, 1, 0) != 0) {
433 continue;
435 goto end;
439 end:
440 if (bsize > MAXBSIZE) {
441 bsize = 0;
442 *avd_loc = 0;
444 free(buf);
445 return (bsize);
448 static int32_t
449 ud_parse_fill_vds(ud_handle_t h, struct vds *v,
450 uint32_t vds_loc, uint32_t vds_len)
452 uint8_t *addr, *taddr, *eaddr;
453 uint16_t id;
454 int32_t i;
455 uint64_t off;
456 struct tag *tag;
457 struct pri_vol_desc *pvd;
458 struct log_vol_desc *lvd;
459 struct vol_desc_ptr *vds;
460 struct unall_spc_desc *usd;
462 begin:
463 if ((addr = (uint8_t *)malloc(vds_len)) == NULL) {
464 return (1);
467 off = vds_loc * h->udfs.lbsize;
468 if (ud_read_dev(h, off, addr, vds_len) != 0) {
469 goto end;
472 for (taddr = addr, eaddr = addr + h->udfs.mvds_len; taddr < eaddr;
473 taddr += h->udfs.lbsize, vds_loc ++) {
475 /* LINTED */
476 tag = (struct tag *)taddr;
477 id = SWAP_16(tag->tag_id);
479 * If you cannot verify the tag just skip it
480 * This is not a fatal error
482 if (ud_verify_tag(h, tag, id, vds_loc, 1, 0) != 0) {
483 continue;
485 switch (id) {
486 case UD_PRI_VOL_DESC :
489 * Primary Volume Descriptor
491 /* LINTED */
492 pvd = (struct pri_vol_desc *)taddr;
493 if ((v->pvd_len == 0) ||
494 (SWAP_32(pvd->pvd_vdsn) > v->pvd_vdsn)) {
495 v->pvd_vdsn = SWAP_32(pvd->pvd_vdsn);
496 v->pvd_loc = vds_loc;
497 v->pvd_len = h->udfs.lbsize;
499 break;
500 case UD_VOL_DESC_PTR :
503 * Curent sequence is continued from
504 * the location pointed by vdp
506 /* LINTED */
507 vds = (struct vol_desc_ptr *)taddr;
509 if (SWAP_32(vds->vdp_nvdse.ext_len) != 0) {
510 vds_loc = SWAP_32(vds->vdp_nvdse.ext_loc);
511 vds_len = SWAP_32(vds->vdp_nvdse.ext_len);
512 free(addr);
513 goto begin;
515 break;
516 case UD_IMPL_USE_DESC :
519 * Implementation Use Volume Descriptor
521 v->iud_loc = vds_loc;
522 v->iud_len = lb_roundup(512, h->udfs.lbsize);
523 break;
524 case UD_PART_DESC :
526 struct ud_part *p;
527 struct phdr_desc *ph;
528 struct part_desc *pd;
531 * Partition Descriptor
533 /* LINTED */
534 pd = (struct part_desc *)taddr;
536 for (i = 0; i < h->n_parts; i++) {
537 p = &h->part[i];
539 if ((SWAP_16(pd->pd_pnum) ==
540 p->udp_number) &&
541 (SWAP_32(pd->pd_vdsn) >
542 p->udp_seqno)) {
543 break;
547 v->part_loc[i] = vds_loc;
548 v->part_len[i] =
549 lb_roundup(512, h->udfs.lbsize);
551 p = &h->part[i];
552 p->udp_number = SWAP_16(pd->pd_pnum);
553 p->udp_seqno = SWAP_32(pd->pd_vdsn);
554 p->udp_access = SWAP_32(pd->pd_acc_type);
555 p->udp_start = SWAP_32(pd->pd_part_start);
556 p->udp_length = SWAP_32(pd->pd_part_length);
558 /* LINTED */
559 ph = (struct phdr_desc *)pd->pd_pc_use;
560 if (ph->phdr_ust.sad_ext_len) {
561 p->udp_flags = UDP_SPACETBLS;
562 p->udp_unall_loc = SWAP_32(ph->phdr_ust.sad_ext_loc);
563 p->udp_unall_len = SWAP_32(ph->phdr_ust.sad_ext_len);
564 p->udp_freed_loc = SWAP_32(ph->phdr_fst.sad_ext_loc);
565 p->udp_freed_len = SWAP_32(ph->phdr_fst.sad_ext_len);
566 } else {
567 p->udp_flags = UDP_BITMAPS;
568 p->udp_unall_loc = SWAP_32(ph->phdr_usb.sad_ext_loc);
569 p->udp_unall_len = SWAP_32(ph->phdr_usb.sad_ext_len);
570 p->udp_freed_loc = SWAP_32(ph->phdr_fsb.sad_ext_loc);
571 p->udp_freed_len = SWAP_32(ph->phdr_fsb.sad_ext_len);
574 if (i == h->n_parts) {
575 h->n_parts ++;
578 break;
579 case UD_LOG_VOL_DESC :
582 * Logical Volume Descriptor
584 /* LINTED */
585 lvd = (struct log_vol_desc *)taddr;
586 if ((v->lvd_len == 0) ||
587 (SWAP_32(lvd->lvd_vdsn) > v->lvd_vdsn)) {
588 v->lvd_vdsn = SWAP_32(lvd->lvd_vdsn);
589 v->lvd_loc = vds_loc;
590 v->lvd_len = ((uint32_t)
591 &((struct log_vol_desc *)0)->lvd_pmaps);
592 v->lvd_len =
593 lb_roundup(v->lvd_len, h->udfs.lbsize);
595 break;
596 case UD_UNALL_SPA_DESC :
599 * Unallocated Space Descriptor
601 /* LINTED */
602 usd = (struct unall_spc_desc *)taddr;
603 v->usd_loc = vds_loc;
604 v->usd_len = ((uint32_t)
605 &((unall_spc_desc_t *)0)->ua_al_dsc) +
606 SWAP_32(usd->ua_nad) *
607 sizeof (struct extent_ad);
608 v->usd_len = lb_roundup(v->usd_len, h->udfs.lbsize);
609 break;
610 case UD_TERM_DESC :
612 * Success fully completed
614 goto end;
615 default :
617 * If you donot undetstand any tag just skip
618 * it. This is not a fatal error
620 break;
624 end:
625 free(addr);
626 if ((v->pvd_len == 0) ||
627 (v->part_len[0] == 0) ||
628 (v->lvd_len == 0)) {
629 return (1);
632 return (0);
635 static int32_t
636 ud_read_and_translate_lvd(ud_handle_t h, uint32_t lvd_loc, uint32_t lvd_len)
638 caddr_t addr;
639 uint16_t fsd_prn;
640 uint32_t fsd_loc, fsd_len;
641 uint32_t lvds_loc, lvds_len;
642 uint64_t off;
643 struct log_vol_desc *lvd = NULL;
645 int32_t max_maps, i, mp_sz, index;
646 struct ud_map *m;
647 struct pmap_hdr *ph;
648 struct pmap_typ1 *typ1;
649 struct pmap_typ2 *typ2;
651 if (lvd_len == 0) {
652 return (1);
655 if ((lvd = (struct log_vol_desc *)
656 malloc(lvd_len)) == NULL) {
657 return (1);
660 off = lvd_loc * h->udfs.lbsize;
661 if (ud_read_dev(h, off, (uint8_t *)lvd, lvd_len) != 0) {
662 free(lvd);
663 return (1);
666 if (ud_verify_tag(h, &lvd->lvd_tag, UD_LOG_VOL_DESC,
667 lvd_loc, 1, 0) != 0) {
668 free(lvd);
669 return (1);
673 * Take care of maps
675 max_maps = SWAP_32(lvd->lvd_num_pmaps);
676 ph = (struct pmap_hdr *)lvd->lvd_pmaps;
677 for (h->n_maps = index = 0; index < max_maps; index++) {
678 m = &h->maps[h->n_maps];
679 switch (ph->maph_type) {
680 case MAP_TYPE1 :
682 /* LINTED */
683 typ1 = (struct pmap_typ1 *)ph;
685 m->udm_flags = UDM_MAP_NORM;
686 m->udm_vsn = SWAP_16(typ1->map1_vsn);
687 m->udm_pn = SWAP_16(typ1->map1_pn);
688 h->n_maps++;
689 break;
691 case MAP_TYPE2 :
693 /* LINTED */
694 typ2 = (struct pmap_typ2 *)ph;
696 if (strncmp(typ2->map2_pti.reg_id,
697 UDF_VIRT_PART, 23) == 0) {
699 m->udm_flags = UDM_MAP_VPM;
700 m->udm_vsn = SWAP_16(typ2->map2_vsn);
701 m->udm_pn = SWAP_16(typ2->map2_pn);
702 } else if (strncmp(typ2->map2_pti.reg_id,
703 UDF_SPAR_PART, 23) == 0) {
705 if ((SWAP_16(typ2->map2_pl) != 32) ||
706 (typ2->map2_nst < 1) ||
707 (typ2->map2_nst > 4)) {
708 break;
710 m->udm_flags = UDM_MAP_SPM;
711 m->udm_vsn = SWAP_16(typ2->map2_vsn);
712 m->udm_pn = SWAP_16(typ2->map2_pn);
714 m->udm_plen = SWAP_16(typ2->map2_pl);
715 m->udm_nspm = typ2->map2_nst;
716 m->udm_spsz = SWAP_32(typ2->map2_sest);
718 mp_sz = lb_roundup(m->udm_spsz, h->udfs.lbsize);
720 if ((addr = malloc(mp_sz * m->udm_nspm)) ==
721 NULL) {
722 break;
725 for (i = 0; i < m->udm_nspm; i++) {
726 m->udm_loc[i] =
727 SWAP_32(typ2->map2_st[index]);
728 m->udm_spaddr[i] = addr + i * mp_sz;
730 off = m->udm_loc[i] * h->udfs.lbsize;
731 if (ud_read_dev(h, off,
732 (uint8_t *)m->udm_spaddr[i],
733 mp_sz) != 0) {
734 m->udm_spaddr[i] = NULL;
735 continue;
739 h->n_maps++;
740 default :
741 break;
743 ph = (struct pmap_hdr *)(((uint8_t *)h) + ph->maph_length);
746 lvds_loc = SWAP_32(lvd->lvd_int_seq_ext.ext_loc);
747 lvds_len = SWAP_32(lvd->lvd_int_seq_ext.ext_len);
749 fsd_prn = SWAP_16(lvd->lvd_lvcu.lad_ext_prn);
750 fsd_loc = SWAP_32(lvd->lvd_lvcu.lad_ext_loc);
751 fsd_len = SWAP_32(lvd->lvd_lvcu.lad_ext_len);
753 free(lvd);
756 * Get the latest LVID
758 if (ud_get_latest_lvid(h, lvds_loc, lvds_len) != 0) {
759 return (1);
762 if (ud_get_latest_fsd(h, fsd_prn, fsd_loc, fsd_len) != 0) {
763 return (1);
766 return (0);
769 static int32_t
770 ud_get_latest_lvid(ud_handle_t h, uint32_t lvds_loc, uint32_t lvds_len)
772 uint8_t *addr, *taddr, *eaddr;
773 uint16_t id;
774 uint64_t off;
775 struct tag *tag;
776 struct log_vol_int_desc *lvid;
778 begin:
779 if ((addr = (uint8_t *)malloc(lvds_len)) == NULL) {
780 return (1);
783 off = lvds_loc * h->udfs.lbsize;
784 if (ud_read_dev(h, off, addr, lvds_len) != 0) {
785 goto end;
788 for (taddr = addr, eaddr = addr + h->udfs.mvds_len; taddr < eaddr;
789 taddr += h->udfs.lbsize, lvds_loc ++) {
791 /* LINTED */
792 tag = (struct tag *)taddr;
793 id = SWAP_16(tag->tag_id);
795 * If you cannot verify the tag just skip it
796 * This is not a fatal error
798 if (ud_verify_tag(h, tag, id, lvds_loc, 1, 0) != 0) {
799 continue;
801 switch (id) {
802 case UD_LOG_VOL_INT :
805 * Logical Volume Integrity Descriptor
807 /* LINTED */
808 lvid = (struct log_vol_int_desc *)taddr;
809 h->udfs.lvid_loc = lvds_loc;
810 h->udfs.lvid_len = ((uint32_t)
811 &((struct log_vol_int_desc *)0)->lvid_fst) +
812 SWAP_32(lvid->lvid_npart) * 8 +
813 SWAP_32(lvid->lvid_liu);
814 h->udfs.lvid_len = lb_roundup(h->udfs.lvid_len,
815 h->udfs.lbsize);
818 * It seems we have a next integrity
819 * sequence
821 if (SWAP_32(lvid->lvid_nie.ext_len) != 0) {
822 free(addr);
823 lvds_loc = SWAP_32(lvid->lvid_nie.ext_loc);
824 lvds_len = SWAP_32(lvid->lvid_nie.ext_len);
825 goto begin;
827 goto end;
828 case UD_TERM_DESC :
831 * Success fully completed
833 goto end;
834 default :
836 * If you donot undetstand any tag just skip
837 * it. This is not a fatal error
839 break;
842 end:
843 free(addr);
844 if (h->udfs.lvid_len == 0) {
845 return (1);
847 return (0);
850 static int32_t
851 ud_get_latest_fsd(ud_handle_t h, uint16_t fsd_prn,
852 uint32_t fsd_loc, uint32_t fsd_len)
854 uint8_t *addr, *taddr, *eaddr;
855 uint16_t id;
856 uint64_t off;
857 uint32_t fsds_loc, fsds_len;
858 struct tag *tag;
859 struct file_set_desc *fsd;
860 uint32_t old_fsn = 0;
862 begin:
863 h->udfs.fsds_prn = fsd_prn;
864 h->udfs.fsds_loc = fsd_loc;
865 h->udfs.fsds_len = fsd_len;
867 fsds_loc = ud_xlate_to_daddr(h, fsd_prn, fsd_loc);
868 fsds_len = lb_roundup(fsd_len, h->udfs.lbsize);
870 if ((addr = (uint8_t *)malloc(fsds_len)) == NULL) {
871 return (1);
874 off = fsds_loc * h->udfs.lbsize;
875 if (ud_read_dev(h, off, addr, fsds_len) != 0) {
876 goto end;
879 for (taddr = addr, eaddr = addr + h->udfs.mvds_len; taddr < eaddr;
880 taddr += h->udfs.lbsize, fsds_loc ++) {
882 /* LINTED */
883 tag = (struct tag *)taddr;
884 id = SWAP_16(tag->tag_id);
886 * If you cannot verify the tag just skip it
887 * This is not a fatal error
889 if (ud_verify_tag(h, tag, id, fsds_loc, 1, 0) != 0) {
890 continue;
892 switch (id) {
893 case UD_FILE_SET_DESC :
894 /* LINTED */
895 fsd = (struct file_set_desc *)taddr;
896 if ((h->udfs.fsd_len == 0) ||
897 (SWAP_32(fsd->fsd_fs_no) > old_fsn)) {
898 old_fsn = SWAP_32(fsd->fsd_fs_no);
899 h->udfs.fsd_loc = fsds_loc;
900 h->udfs.fsd_len = lb_roundup(512,
901 h->udfs.lbsize);
902 h->udfs.ricb_prn =
903 SWAP_16(fsd->fsd_root_icb.lad_ext_prn);
904 h->udfs.ricb_loc =
905 SWAP_32(fsd->fsd_root_icb.lad_ext_loc);
906 h->udfs.ricb_len =
907 SWAP_32(fsd->fsd_root_icb.lad_ext_len);
909 if (SWAP_32(fsd->fsd_next.lad_ext_len) != 0) {
910 fsd_prn = SWAP_16(fsd->fsd_next.lad_ext_prn);
911 fsd_loc = SWAP_32(fsd->fsd_next.lad_ext_loc);
912 fsd_len = SWAP_32(fsd->fsd_next.lad_ext_len);
913 goto begin;
915 break;
916 case UD_TERM_DESC :
919 * Success fully completed
921 goto end;
922 default :
924 * If you donot undetstand any tag just skip
925 * it. This is not a fatal error
927 break;
931 end:
932 free(addr);
933 if (h->udfs.fsd_len == 0) {
934 return (1);
936 return (0);
939 int32_t
940 ud_get_num_blks(ud_handle_t h, uint32_t *blkno)
942 struct vtoc vtoc;
943 struct dk_cinfo dki_info;
944 int32_t error;
947 * Get VTOC from driver
949 if ((error = ioctl(h->fd, DKIOCGVTOC, (intptr_t)&vtoc)) != 0) {
950 return (error);
954 * Verify if is proper
956 if (vtoc.v_sanity != VTOC_SANE) {
957 return (EINVAL);
961 * Get dk_cinfo from driver
963 if ((error = ioctl(h->fd, DKIOCINFO, (intptr_t)&dki_info)) != 0) {
964 return (error);
967 if (dki_info.dki_partition >= V_NUMPAR) {
968 return (EINVAL);
972 * Return the size of the partition
974 *blkno = vtoc.v_part[dki_info.dki_partition].p_size;
976 return (0);
979 uint32_t
980 ud_xlate_to_daddr(ud_handle_t h, uint16_t prn, uint32_t blkno)
982 int32_t i;
983 struct ud_map *m;
984 struct ud_part *p;
987 if (prn < h->n_maps) {
988 m = &h->maps[prn];
989 for (i = 0; i < h->n_parts; i++) {
990 p = &h->part[i];
991 if (m->udm_pn == p->udp_number) {
992 return (p->udp_start + blkno);
996 return (0);
999 /* ------ END Read and translate the on disk VDS to IN CORE format -------- */
1001 int32_t
1002 ud_verify_tag(ud_handle_t h, struct tag *tag, uint16_t id,
1003 uint32_t blockno, int32_t do_crc, int32_t print_msg)
1005 int32_t i;
1006 uint8_t *addr, cksum = 0;
1007 uint16_t crc;
1011 * Verify Tag Identifier
1013 if (tag->tag_id != SWAP_16(id)) {
1014 if (print_msg != 0) {
1015 (void) fprintf(stderr,
1016 gettext("tag does not verify tag %x req %x\n"),
1017 SWAP_16(tag->tag_id), id);
1019 return (1);
1023 * Verify Tag Descriptor Version
1025 if (SWAP_16(tag->tag_desc_ver) != h->udfs.ecma_version) {
1026 if (print_msg != 0) {
1027 (void) fprintf(stderr,
1028 gettext("tag version does not match with "
1029 "NSR descriptor version TAG %x NSR %x\n"),
1030 SWAP_16(tag->tag_desc_ver),
1031 h->udfs.ecma_version);
1033 return (1);
1037 * Caliculate Tag Checksum
1039 addr = (uint8_t *)tag;
1040 for (i = 0; i <= 15; i++) {
1041 if (i != 4) {
1042 cksum += addr[i];
1047 * Verify Tag Checksum
1049 if (cksum != tag->tag_cksum) {
1050 if (print_msg != 0) {
1051 (void) fprintf(stderr,
1052 gettext("Checksum Does not Verify TAG"
1053 " %x CALC %x\n"), tag->tag_cksum, cksum);
1055 return (1);
1060 * Do we want to do crc
1062 if (do_crc) {
1063 if (tag->tag_crc_len) {
1066 * Caliculate CRC for the descriptor
1068 crc = ud_crc(addr + 0x10, SWAP_16(tag->tag_crc_len));
1071 * Verify CRC
1073 if (crc != SWAP_16(tag->tag_crc)) {
1074 if (print_msg != 0) {
1075 (void) fprintf(stderr,
1076 gettext("CRC Does not verify"
1077 " TAG %x CALC %x %x\n"),
1078 SWAP_16(tag->tag_crc),
1079 crc, addr);
1085 * Verify Tag Location
1087 if (SWAP_32(blockno) != tag->tag_loc) {
1088 if (print_msg != 0) {
1089 (void) fprintf(stderr,
1090 gettext("Tag Location Does not verify"
1091 " blockno %x tag_blockno %x\n"),
1092 blockno, SWAP_32(tag->tag_loc));
1097 return (0);
1101 /* ARGSUSED1 */
1102 void
1103 ud_make_tag(ud_handle_t h, struct tag *tag, uint16_t tag_id,
1104 uint32_t blkno, uint16_t crc_len)
1106 int32_t i;
1107 uint16_t crc;
1108 uint8_t *addr, cksum = 0;
1110 tag->tag_id = SWAP_16(tag_id);
1111 tag->tag_desc_ver = SWAP_16(h->udfs.ecma_version);
1112 tag->tag_cksum = 0;
1113 tag->tag_res = 0;
1116 * Calicualte and assign CRC, CRC_LEN
1118 addr = (uint8_t *)tag;
1119 crc = ud_crc(addr + 0x10, crc_len);
1120 tag->tag_crc = SWAP_16(crc);
1121 tag->tag_crc_len = SWAP_16(crc_len);
1122 tag->tag_loc = SWAP_32(blkno);
1125 * Caliculate Checksum
1127 for (i = 0; i <= 15; i++) {
1128 cksum += addr[i];
1132 * Assign Checksum
1134 tag->tag_cksum = cksum;
1137 /* **************** udf specific subroutines *********************** */
1139 static uint16_t ud_crc_table[256] = {
1140 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
1141 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
1142 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
1143 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
1144 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
1145 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
1146 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
1147 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
1148 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
1149 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
1150 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
1151 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
1152 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
1153 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
1154 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
1155 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
1156 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
1157 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
1158 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
1159 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
1160 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
1161 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
1162 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
1163 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
1164 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
1165 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
1166 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
1167 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
1168 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
1169 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
1170 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
1171 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
1174 static uint16_t
1175 ud_crc(uint8_t *addr, int32_t len)
1177 uint16_t crc = 0;
1179 while (len-- > 0) {
1180 crc = ud_crc_table[(crc >> 8 ^ *addr++) & 0xff] ^ (crc<<8);
1183 return (crc);
1186 #define MAXNAMLEN 0x200
1189 #define POUND 0x0023
1190 #define DOT 0x002E
1191 #define SLASH 0x002F
1192 #define UNDERBAR 0x005F
1195 static uint16_t htoc[16] = {'0', '1', '2', '3',
1196 '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
1198 * unicode is the string of 16-bot characters
1199 * length is the number of 16-bit characters
1201 static int32_t
1202 UdfTxName(uint16_t *unicode, int32_t count)
1204 int32_t i, j, k, lic, make_crc, dot_loc;
1205 uint16_t crc;
1207 if ((unicode[0] == DOT) &&
1208 ((count == 1) || ((count == 2) && (unicode[1] == DOT)))) {
1209 crc = DOT;
1210 if (count == 2) {
1211 crc += DOT;
1213 unicode[0] = UNDERBAR;
1214 unicode[1] = POUND;
1215 unicode[2] = htoc[(uint16_t)(crc & 0xf000) >> 12];
1216 unicode[3] = htoc[(uint16_t)(crc & 0xf00) >> 8];
1217 unicode[4] = htoc[(uint16_t)(crc & 0xf0) >> 4];
1218 unicode[5] = htoc[crc & 0xf];
1219 return (6);
1221 crc = 0;
1222 j = make_crc = 0;
1223 lic = dot_loc = -1;
1224 for (i = 0; i < count; i++) {
1225 if (make_crc) {
1226 crc += unicode[i];
1228 if (unicode[i] == DOT) {
1229 dot_loc = j;
1231 if ((unicode[i] == SLASH) ||
1232 (unicode[i] == 0)) {
1233 if (make_crc == 0) {
1234 for (k = 0; k <= i; k++) {
1235 crc += unicode[k];
1237 make_crc = 1;
1239 if (lic != (i - 1)) {
1240 unicode[j++] = UNDERBAR;
1242 lic = i;
1243 } else {
1244 unicode[j++] = unicode[i];
1248 if (make_crc) {
1249 if (dot_loc != -1) {
1250 if ((j + 5) > MAXNAMLEN) {
1251 if ((j - dot_loc + 5) > MAXNAMLEN) {
1252 j = MAXNAMLEN - 5 + dot_loc;
1253 for (k = MAXNAMLEN;
1254 j >= dot_loc; k --, j--) {
1255 unicode[k] = unicode[j];
1257 k = 0;
1258 } else {
1259 for (k = MAXNAMLEN;
1260 j >= dot_loc; k--, j--) {
1261 unicode[k] = unicode[j];
1263 k -= 4;
1265 j = MAXNAMLEN;
1266 } else {
1267 for (k = j; k >= dot_loc; k--) {
1268 unicode[k + 5] = unicode[k];
1270 k = dot_loc;
1271 j += 5;
1273 } else {
1274 if ((j + 5) > MAXNAMLEN) {
1275 j = MAXNAMLEN;
1276 k = MAXNAMLEN - 5;
1277 } else {
1278 k = j;
1279 j += 5;
1282 unicode[k++] = POUND;
1283 unicode[k++] = htoc[(uint16_t)(crc & 0xf000) >> 12];
1284 unicode[k++] = htoc[(uint16_t)(crc & 0xf00) >> 8];
1285 unicode[k++] = htoc[(uint16_t)(crc & 0xf0) >> 4];
1286 unicode[k++] = htoc[crc & 0xf];
1288 return (j);
1292 * Assumes the output buffer is large
1293 * enough to hold the uncompressed
1294 * code
1296 static int32_t
1297 UncompressUnicode(
1298 int32_t numberOfBytes, /* (Input) number of bytes read from media. */
1299 uint8_t *UDFCompressed, /* (Input) bytes read from media. */
1300 uint16_t *unicode) /* (Output) uncompressed unicode characters. */
1302 int32_t compID;
1303 int32_t returnValue, unicodeIndex, byteIndex;
1307 * Use UDFCompressed to store current byte being read.
1309 compID = UDFCompressed[0];
1311 /* First check for valid compID. */
1312 if (compID != 8 && compID != 16) {
1313 returnValue = -1;
1314 } else {
1315 unicodeIndex = 0;
1316 byteIndex = 1;
1318 /* Loop through all the bytes. */
1319 while (byteIndex < numberOfBytes) {
1320 if (compID == 16) {
1322 * Move the first byte to the
1323 * high bits of the unicode char.
1325 unicode[unicodeIndex] =
1326 UDFCompressed[byteIndex++] << 8;
1327 } else {
1328 unicode[unicodeIndex] = 0;
1330 if (byteIndex < numberOfBytes) {
1332 * Then the next byte to the low bits.
1334 unicode[unicodeIndex] |=
1335 UDFCompressed[byteIndex++];
1337 unicodeIndex++;
1339 returnValue = unicodeIndex;
1341 return (returnValue);
1348 static int32_t
1349 ud_compressunicode(
1350 int32_t numberOfChars, /* (Input) number of unicode characters. */
1351 int32_t compID, /* (Input) compression ID to be used. */
1352 uint16_t *unicode, /* (Input) unicode characters to compress. */
1353 uint8_t *UDFCompressed) /* (Output) compressed string, as bytes. */
1355 int32_t byteIndex;
1357 if (compID != 8 && compID != 16) {
1359 * Unsupported compression ID !
1361 byteIndex = -1;
1362 } else {
1364 * Place compression code in first byte.
1366 UDFCompressed[0] = (uint8_t)compID;
1367 (void) strncpy((caddr_t)&UDFCompressed[1],
1368 (caddr_t)unicode, numberOfChars);
1369 byteIndex = numberOfChars + 1;
1371 return (byteIndex);
1375 static int32_t
1376 ud_convert2utf8(uint8_t *ibuf, uint8_t *obuf, int32_t length)
1378 int i, size;
1379 uint16_t *buf;
1381 /* LINTED */
1382 buf = (uint16_t *)obuf;
1384 size = UncompressUnicode(length, ibuf, buf);
1386 size = UdfTxName(buf, size);
1388 for (i = 0; i < size; i++) {
1389 obuf[i] = (uint8_t)buf[i];
1391 obuf[i] = '\0';
1393 return (size);
1396 static int32_t
1397 ud_convert2utf16(uint8_t *ibuf, uint8_t *obuf, int32_t length)
1399 int32_t comp_len;
1400 uint16_t *ptr;
1402 /* LINTED */
1403 ptr = (uint16_t *)ibuf;
1404 comp_len = ud_compressunicode(length, 8, ptr, obuf);
1406 return (comp_len);
1410 * Assumption code set is zero in udfs
1412 void
1413 ud_convert2local(int8_t *ibuf, int8_t *obuf, int32_t length)
1415 wchar_t buf4c[128];
1416 int32_t i, comp, index;
1419 * Special uncompress code
1420 * written to accomodate solaris wchar_t
1422 comp = ibuf[0];
1423 for (i = 0, index = 1; i < length; i++) {
1424 if (comp == 16) {
1425 buf4c[i] = ibuf[index++] << 8;
1426 } else {
1427 buf4c[i] = 0;
1429 if (index < length) {
1430 buf4c[i] |= ibuf[index++];
1433 (void) wcstombs((char *)obuf, buf4c, 128);
1437 /* ------------ Routines to print basic structures Part 1 ---------------- */
1441 void
1442 print_charspec(FILE *fout, char *name, struct charspec *cspec)
1444 int i = 0;
1446 (void) fprintf(fout,
1447 "%s : %x - \"", name, cspec->cs_type);
1448 for (i = 0; i < 63; i++) {
1449 (void) fprintf(fout,
1450 "%c", cspec->cs_info[i]);
1452 (void) fprintf(fout, "\n");
1455 /* ARGSUSED */
1456 void
1457 print_dstring(FILE *fout, char *name, uint16_t cset, char *bufc, uint8_t length)
1459 int8_t bufmb[1024];
1461 ud_convert2local(bufc, bufmb, length);
1463 (void) fprintf(fout,
1464 "%s %s\n", name, bufmb);
1467 void
1468 set_dstring(dstring_t *dp, char *cp, int32_t len)
1470 int32_t length;
1472 bzero(dp, len);
1473 length = strlen(cp);
1474 if (length > len - 1) {
1475 length = len - 1;
1477 (void) strncpy(dp, cp, length);
1478 dp[len - 1] = length;
1481 void
1482 print_tstamp(FILE *fout, char *name, tstamp_t *ts)
1484 (void) fprintf(fout, "%s tz : %d yr : %d mo : %d da : %d "
1485 "Time : %d : %d : %d : %d : %d : %d\n", name,
1486 SWAP_16(ts->ts_tzone), SWAP_16(ts->ts_year), ts->ts_month,
1487 ts->ts_day, ts->ts_hour, ts->ts_min, ts->ts_sec, ts->ts_csec,
1488 ts->ts_husec, ts->ts_usec);
1493 void
1494 make_regid(ud_handle_t h, struct regid *reg, char *id, int32_t type)
1496 reg->reg_flags = 0;
1497 (void) strncpy(reg->reg_id, id, 23);
1499 if (type == REG_DOM_ID) {
1500 struct dom_id_suffix *dis;
1502 /* LINTED */
1503 dis = (struct dom_id_suffix *)reg->reg_ids;
1504 dis->dis_udf_revison = SWAP_16(h->udfs.ma_write);
1505 dis->dis_domain_flags = 0;
1507 } else if (type == REG_UDF_ID) {
1508 struct udf_id_suffix *uis;
1510 /* LINTED */
1511 uis = (struct udf_id_suffix *)reg->reg_ids;
1512 uis->uis_udf_revision = SWAP_16(h->udfs.ma_write);
1513 uis->uis_os_class = OS_CLASS_UNIX;
1514 uis->uis_os_identifier = OS_IDENTIFIER_SOLARIS;
1515 } else if (type == REG_UDF_II) {
1516 struct impl_id_suffix *iis;
1518 iis = (struct impl_id_suffix *)reg->reg_ids;
1519 iis->iis_os_class = OS_CLASS_UNIX;
1520 iis->iis_os_identifier = OS_IDENTIFIER_SOLARIS;
1524 void
1525 print_regid(FILE *fout, char *name, struct regid *reg, int32_t type)
1527 (void) fprintf(fout, "%s : 0x%x : \"%s\" :",
1528 name, reg->reg_flags, reg->reg_id);
1530 if (type == REG_DOM_ID) {
1531 struct dom_id_suffix *dis;
1533 /* LINTED */
1534 dis = (struct dom_id_suffix *)reg->reg_ids;
1535 (void) fprintf(fout, " 0x%x : %s : %s\n",
1536 SWAP_16(dis->dis_udf_revison),
1537 (dis->dis_domain_flags & PROTECT_SOFT_WRITE) ?
1538 "HW Protect" : "No HW Write Protect",
1539 (dis->dis_domain_flags & PROTECT_HARD_WRITE) ?
1540 "SW Protect" : "No SW Protect");
1541 } else if (type == REG_UDF_ID) {
1542 struct udf_id_suffix *uis;
1544 /* LINTED */
1545 uis = (struct udf_id_suffix *)reg->reg_ids;
1546 (void) fprintf(fout,
1547 " 0x%x : OS Class 0x%x : OS Identifier 0x%x\n",
1548 SWAP_16(uis->uis_udf_revision),
1549 uis->uis_os_class, uis->uis_os_identifier);
1550 } else {
1551 struct impl_id_suffix *iis;
1553 iis = (struct impl_id_suffix *)reg->reg_ids;
1554 (void) fprintf(fout,
1555 " OS Class 0x%x : OS Identifier 0x%x\n",
1556 iis->iis_os_class, iis->iis_os_identifier);
1560 #ifdef OLD
1561 void
1562 print_regid(FILE *fout, char *name, struct regid *reg)
1564 (void) fprintf(fout, "%s : 0x%x : \"%s\" :",
1565 name, reg->reg_flags, reg->reg_id);
1567 if (strncmp(reg->reg_id, "*OSTA UDF Compliant", 19) == 0) {
1568 (void) fprintf(fout, " 0x%x : %s : %s\n",
1569 reg->reg_ids[0] | (reg->reg_ids[1] << 8),
1570 (reg->reg_ids[2] & 1) ?
1571 "HW Protect" : "No HW Write Protect",
1572 (reg->reg_ids[2] & 2) ?
1573 "SW Protect" : "No SW Protect");
1574 } else if ((strncmp(reg->reg_id, "*UDF Virtual Partition", 22) == 0) ||
1575 (strncmp(reg->reg_id, "*UDF Sparable Partition", 23) == 0) ||
1576 (strncmp(reg->reg_id, "*UDF Virtual Alloc Tbl", 22) == 0) ||
1577 (strncmp(reg->reg_id, "*UDF Sparing Table", 18) == 0)) {
1578 (void) fprintf(fout,
1579 " 0x%x : OS Class 0x%x : OS Identifier 0x%x\n",
1580 reg->reg_ids[0] | (reg->reg_ids[1] << 8),
1581 reg->reg_ids[2], reg->reg_ids[3]);
1582 } else {
1583 (void) fprintf(fout,
1584 " OS Class 0x%x : OS Identifier 0x%x\n",
1585 reg->reg_ids[0], reg->reg_ids[1]);
1588 #endif
1591 /* ------------ Routines to print basic structures Part 2 ---------------- */
1593 * Part 2
1594 * This part is OS specific and is currently
1595 * not supported
1598 /* ------------ Routines to print basic structures Part 3 ---------------- */
1600 void
1601 print_ext_ad(FILE *fout, char *name, struct extent_ad *ead)
1603 (void) fprintf(fout,
1604 "%s EAD Len %x Loc %x\n",
1605 name, SWAP_32(ead->ext_len), SWAP_32(ead->ext_loc));
1608 void
1609 print_tag(FILE *fout, struct tag *tag)
1611 (void) fprintf(fout,
1612 "tag_id : %x ver : %x cksum : %x "
1613 "sno : %x crc : %x crc_len : %x loc : %x\n",
1614 SWAP_16(tag->tag_id), SWAP_16(tag->tag_desc_ver),
1615 tag->tag_cksum, SWAP_16(tag->tag_sno),
1616 SWAP_16(tag->tag_crc), SWAP_16(tag->tag_crc_len),
1617 SWAP_32(tag->tag_loc));
1621 void
1622 print_pvd(FILE *fout, struct pri_vol_desc *pvd)
1624 (void) fprintf(fout,
1625 "\n\t\t\tPrimary Volume Descriptor\n");
1626 print_tag(fout, &pvd->pvd_tag);
1627 (void) fprintf(fout, "vdsn : %x vdn : %x\n",
1628 SWAP_32(pvd->pvd_vdsn), SWAP_32(pvd->pvd_pvdn));
1629 print_dstring(fout, "volid : ", pvd->pvd_desc_cs.cs_type,
1630 pvd->pvd_vol_id, 32);
1631 (void) fprintf(fout,
1632 "vsn : %x mvsn : %x il : %x mil :"
1633 " %x csl : %x mcsl %x\n",
1634 SWAP_16(pvd->pvd_vsn), SWAP_16(pvd->pvd_mvsn),
1635 SWAP_16(pvd->pvd_il), SWAP_16(pvd->pvd_mil),
1636 SWAP_32(pvd->pvd_csl), SWAP_32(pvd->pvd_mcsl));
1637 print_dstring(fout, "vsid :", pvd->pvd_desc_cs.cs_type,
1638 pvd->pvd_vsi, 128);
1639 print_charspec(fout, "desc_cs", &pvd->pvd_desc_cs);
1640 print_charspec(fout, "exp_cs", &pvd->pvd_exp_cs);
1641 print_ext_ad(fout, "val ", &pvd->pvd_vol_abs);
1642 print_ext_ad(fout, "vcnl ", &pvd->pvd_vcn);
1643 print_regid(fout, "ai", &pvd->pvd_appl_id, REG_UDF_II);
1644 print_regid(fout, "ii", &pvd->pvd_ii, REG_UDF_II);
1645 (void) fprintf(fout, "pvdsl : %x flags : %x\n",
1646 SWAP_32(pvd->pvd_pvdsl),
1647 SWAP_16(pvd->pvd_flags));
1650 void
1651 print_avd(FILE *fout, struct anch_vol_desc_ptr *avdp)
1653 (void) fprintf(fout,
1654 "\n\t\t\tAnchor Volume Descriptor\n");
1655 print_tag(fout, &avdp->avd_tag);
1656 print_ext_ad(fout, "Main Volume Descriptor Sequence : ",
1657 &avdp->avd_main_vdse);
1658 print_ext_ad(fout, "Reserve Volume Descriptor Sequence : ",
1659 &avdp->avd_res_vdse);
1662 void
1663 print_vdp(FILE *fout, struct vol_desc_ptr *vdp)
1665 (void) fprintf(fout,
1666 "\n\t\t\tVolume Descriptor Pointer\n");
1667 print_tag(fout, &vdp->vdp_tag);
1668 (void) fprintf(fout, "vdsn : %x ",
1669 SWAP_32(vdp->vdp_vdsn));
1670 print_ext_ad(fout, "vdse ", &vdp->vdp_nvdse);
1673 void
1674 print_iuvd(FILE *fout, struct iuvd_desc *iuvd)
1676 (void) fprintf(fout,
1677 "\n\t\t\tImplementation Use Volume Descriptor\n");
1678 print_tag(fout, &iuvd->iuvd_tag);
1679 (void) fprintf(fout,
1680 "vdsn : %x ", SWAP_32(iuvd->iuvd_vdsn));
1681 print_regid(fout, "Impl Id : ", &iuvd->iuvd_ii, REG_UDF_ID);
1682 print_charspec(fout, "cset ", &iuvd->iuvd_cset);
1683 print_dstring(fout, "lvi : ", iuvd->iuvd_cset.cs_type,
1684 iuvd->iuvd_lvi, 128);
1685 print_dstring(fout, "ifo1 : ", iuvd->iuvd_cset.cs_type,
1686 iuvd->iuvd_ifo1, 36);
1687 print_dstring(fout, "ifo2 : ", iuvd->iuvd_cset.cs_type,
1688 iuvd->iuvd_ifo2, 36);
1689 print_dstring(fout, "ifo3 : ", iuvd->iuvd_cset.cs_type,
1690 iuvd->iuvd_ifo3, 36);
1692 print_regid(fout, "iid ", &iuvd->iuvd_iid, REG_UDF_II);
1695 void
1696 print_part(FILE *fout, struct part_desc *pd)
1698 (void) fprintf(fout,
1699 "\n\t\t\tPartition Descriptor\n");
1700 print_tag(fout, &pd->pd_tag);
1701 (void) fprintf(fout,
1702 "vdsn : %x flags : %x num : %x ",
1703 SWAP_32(pd->pd_vdsn),
1704 SWAP_16(pd->pd_pflags),
1705 SWAP_16(pd->pd_pnum));
1706 print_regid(fout, "contents ", &pd->pd_pcontents, REG_UDF_II);
1707 /* LINTED */
1708 print_phdr(fout, (struct phdr_desc *)(&pd->pd_pc_use));
1709 (void) fprintf(fout,
1710 "acc : %x start : %x length : %x ",
1711 SWAP_32(pd->pd_acc_type),
1712 SWAP_32(pd->pd_part_start),
1713 SWAP_32(pd->pd_part_length));
1714 print_regid(fout, "Impl Id : ", &pd->pd_ii, REG_UDF_II);
1717 void
1718 print_lvd(FILE *fout, struct log_vol_desc *lvd)
1720 (void) fprintf(fout,
1721 "\n\t\t\tLogical Volume Descriptor\n");
1722 print_tag(fout, &lvd->lvd_tag);
1723 (void) fprintf(fout,
1724 "vdsn : %x ", SWAP_32(lvd->lvd_vdsn));
1725 print_charspec(fout, "Desc Char Set ", &lvd->lvd_desc_cs);
1726 print_dstring(fout, "lvid : ", lvd->lvd_desc_cs.cs_type,
1727 lvd->lvd_lvid, 28);
1728 (void) fprintf(fout,
1729 "lbsize : %x ",
1730 SWAP_32(lvd->lvd_log_bsize));
1731 print_regid(fout, "Dom Id", &lvd->lvd_dom_id, REG_DOM_ID);
1732 print_long_ad(fout, "lvcu", &lvd->lvd_lvcu);
1733 (void) fprintf(fout,
1734 "mtlen : %x nmaps : %x ",
1735 SWAP_32(lvd->lvd_mtbl_len),
1736 SWAP_32(lvd->lvd_num_pmaps));
1737 print_regid(fout, "Impl Id : ", &lvd->lvd_ii, REG_UDF_II);
1738 print_ext_ad(fout, "Int Seq", &lvd->lvd_int_seq_ext);
1739 print_pmaps(fout, lvd->lvd_pmaps, SWAP_32(lvd->lvd_num_pmaps));
1742 void
1743 print_usd(FILE *fout, struct unall_spc_desc *ua)
1745 int32_t i, count;
1747 (void) fprintf(fout,
1748 "\n\t\t\tUnallocated Space Descriptor\n");
1749 print_tag(fout, &ua->ua_tag);
1750 count = SWAP_32(ua->ua_nad);
1751 (void) fprintf(fout,
1752 "vdsn : %x nad : %x\n",
1753 SWAP_32(ua->ua_vdsn), count);
1754 for (i = 0; i < count; i++) {
1755 (void) fprintf(fout,
1756 "loc : %x len : %x\n",
1757 SWAP_32(ua->ua_al_dsc[i * 2]),
1758 SWAP_32(ua->ua_al_dsc[i * 2 + 1]));
1762 void
1763 print_lvid(FILE *fout, struct log_vol_int_desc *lvid)
1765 int32_t i, count;
1766 caddr_t addr;
1767 struct lvid_iu *liu;
1769 (void) fprintf(fout,
1770 "\n\t\t\tLogical Volume Integrity Descriptor\n");
1771 print_tag(fout, &lvid->lvid_tag);
1772 print_tstamp(fout, "Rec TM ", &lvid->lvid_tstamp);
1773 if (SWAP_32(lvid->lvid_int_type) == 0) {
1774 (void) fprintf(fout,
1775 "int_typ : Open\n");
1776 } else if (SWAP_32(lvid->lvid_int_type) == 1) {
1777 (void) fprintf(fout, "int_typ : Closed\n");
1778 } else {
1779 (void) fprintf(fout, "int_typ : Unknown\n");
1781 print_ext_ad(fout, "Nie ", &lvid->lvid_nie);
1782 count = SWAP_32(lvid->lvid_npart);
1783 (void) fprintf(fout,
1784 "Uniq : %llx npart : %x liu : %x\n",
1785 SWAP_64(lvid->lvid_lvcu.lvhd_uniqid),
1786 count, SWAP_32(lvid->lvid_liu));
1787 for (i = 0; i < count; i++) {
1788 (void) fprintf(fout,
1789 "Part : %x Free : %x Size : %x\n",
1790 i, SWAP_32(lvid->lvid_fst[i]),
1791 SWAP_32(lvid->lvid_fst[count + i]));
1794 addr = (caddr_t)lvid->lvid_fst;
1795 /* LINTED */
1796 liu = (struct lvid_iu *)(addr + 2 * count * 4);
1797 print_regid(fout, "Impl Id :", &liu->lvidiu_regid, REG_UDF_II);
1798 (void) fprintf(fout,
1799 "nfiles : %x ndirs : %x miread : %x"
1800 " miwrite : %x mawrite : %x\n",
1801 SWAP_32(liu->lvidiu_nfiles), SWAP_32(liu->lvidiu_ndirs),
1802 SWAP_16(liu->lvidiu_mread), SWAP_16(liu->lvidiu_mwrite),
1803 SWAP_16(liu->lvidiu_maxwr));
1807 /* ------------ Routines to print basic structures Part 4 ---------------- */
1809 void
1810 print_fsd(FILE *fout, ud_handle_t h, struct file_set_desc *fsd)
1812 (void) fprintf(fout,
1813 "\n\t\t\tFile Set Descriptor\n");
1815 print_tag(fout, &fsd->fsd_tag);
1816 print_tstamp(fout, "Rec TM ", &fsd->fsd_time);
1817 (void) fprintf(fout,
1818 "ilvl : %x milvl : %x csl : %x"
1819 " mcsl : %x fsn : %x fsdn : %x\n",
1820 SWAP_16(fsd->fsd_ilevel), SWAP_16(fsd->fsd_mi_level),
1821 SWAP_32(fsd->fsd_cs_list), SWAP_32(fsd->fsd_mcs_list),
1822 SWAP_32(fsd->fsd_fs_no), SWAP_32(fsd->fsd_fsd_no));
1823 print_charspec(fout, "ID CS ", &fsd->fsd_lvidcs);
1824 print_dstring(fout, "lvi : ", fsd->fsd_lvidcs.cs_type,
1825 fsd->fsd_lvid, 128);
1826 print_charspec(fout, "ID CS ", &fsd->fsd_fscs);
1827 print_dstring(fout, "fsi : ", fsd->fsd_lvidcs.cs_type,
1828 fsd->fsd_fsi, 32);
1829 print_dstring(fout, "cfi : ", fsd->fsd_lvidcs.cs_type,
1830 fsd->fsd_cfi, 32);
1831 print_dstring(fout, "afi : ", fsd->fsd_lvidcs.cs_type,
1832 fsd->fsd_afi, 32);
1833 print_long_ad(fout, "Ricb ", &fsd->fsd_root_icb);
1834 print_regid(fout, "DI ", &fsd->fsd_did, REG_DOM_ID);
1835 print_long_ad(fout, "Next Fsd ", &fsd->fsd_next);
1836 if (h->udfs.ecma_version == UD_ECMA_VER3) {
1837 print_long_ad(fout, "System Stream Directory ICB ",
1838 &fsd->fsd_next);
1842 void
1843 print_phdr(FILE *fout, struct phdr_desc *ph)
1845 print_short_ad(fout, "ust ", &ph->phdr_ust);
1846 print_short_ad(fout, "usb ", &ph->phdr_usb);
1847 print_short_ad(fout, "int ", &ph->phdr_it);
1848 print_short_ad(fout, "fst ", &ph->phdr_fst);
1849 print_short_ad(fout, "fsh ", &ph->phdr_fsb);
1852 void
1853 print_fid(FILE *fout, struct file_id *fid)
1855 int32_t i;
1856 uint8_t *addr;
1858 (void) fprintf(fout,
1859 "File Identifier Descriptor\n");
1860 print_tag(fout, &fid->fid_tag);
1861 (void) fprintf(fout, "fvn : %x fc : %x length : %x ",
1862 fid->fid_ver, fid->fid_flags, fid->fid_idlen);
1863 print_long_ad(fout, "ICB", &fid->fid_icb);
1864 addr = &fid->fid_spec[SWAP_16(fid->fid_iulen)];
1865 (void) fprintf(fout, "iulen : %x comp : %x name : ",
1866 SWAP_16(fid->fid_iulen), *addr);
1867 addr++;
1868 for (i = 0; i < fid->fid_idlen; i++) {
1869 (void) fprintf(fout, "%c", *addr++);
1871 (void) fprintf(fout, "\n");
1874 void
1875 print_aed(FILE *fout, struct alloc_ext_desc *aed)
1877 (void) fprintf(fout,
1878 "Allocation Extent Descriptor\n");
1879 print_tag(fout, &aed->aed_tag);
1880 (void) fprintf(fout, "prev ael loc : %x laed : %x\n",
1881 SWAP_32(aed->aed_rev_ael), SWAP_32(aed->aed_len_aed));
1884 static char *ftype[] = {
1885 "NON", "USE", "PIE", "IE",
1886 "DIR", "REG", "BDEV", "CDEV",
1887 "EATT", "FIFO", "SOCK", "TERM",
1888 "SYML", "SDIR"
1891 void
1892 print_icb_tag(FILE *fout, struct icb_tag *itag)
1894 (void) fprintf(fout,
1895 "prnde : %x strat : %x param : %x max_ent %x\n",
1896 SWAP_32(itag->itag_prnde), SWAP_16(itag->itag_strategy),
1897 SWAP_16(itag->itag_param), SWAP_16(itag->itag_max_ent));
1898 (void) fprintf(fout,
1899 "ftype : %s prn : %x loc : %x flags : %x\n",
1900 (itag->itag_ftype >= 14) ? ftype[0] : ftype[itag->itag_ftype],
1901 SWAP_16(itag->itag_lb_prn),
1902 SWAP_32(itag->itag_lb_loc), SWAP_16(itag->itag_flags));
1906 void
1907 print_ie(FILE *fout, struct indirect_entry *ie)
1909 (void) fprintf(fout,
1910 "Indirect Entry\n");
1911 print_tag(fout, &ie->ie_tag);
1912 print_icb_tag(fout, &ie->ie_icb_tag);
1913 print_long_ad(fout, "ICB", &ie->ie_indirecticb);
1916 void
1917 print_td(FILE *fout, struct term_desc *td)
1919 (void) fprintf(fout,
1920 "Terminating Descriptor\n");
1921 print_tag(fout, &td->td_tag);
1924 void
1925 print_fe(FILE *fout, struct file_entry *fe)
1927 (void) fprintf(fout,
1928 "File Entry\n");
1929 print_tag(fout, &fe->fe_tag);
1930 print_icb_tag(fout, &fe->fe_icb_tag);
1931 (void) fprintf(fout,
1932 "uid : %x gid : %x perms : %x nlnk : %x\n",
1933 SWAP_32(fe->fe_uid), SWAP_32(fe->fe_gid),
1934 SWAP_32(fe->fe_perms), SWAP_16(fe->fe_lcount));
1935 (void) fprintf(fout,
1936 "rec_for : %x rec_dis : %x rec_len : %x "
1937 "sz : %llx blks : %llx\n",
1938 fe->fe_rec_for, fe->fe_rec_dis, SWAP_32(fe->fe_rec_len),
1939 SWAP_64(fe->fe_info_len), SWAP_64(fe->fe_lbr));
1940 print_tstamp(fout, "ctime ", &fe->fe_acc_time);
1941 print_tstamp(fout, "mtime ", &fe->fe_mod_time);
1942 print_tstamp(fout, "atime ", &fe->fe_attr_time);
1943 (void) fprintf(fout,
1944 "ckpoint : %x ", SWAP_32(fe->fe_ckpoint));
1945 print_long_ad(fout, "ICB", &fe->fe_ea_icb);
1946 print_regid(fout, "impl", &fe->fe_impl_id, REG_UDF_II);
1947 (void) fprintf(fout,
1948 "uniq_id : %llx len_ear : %x len_adesc %x\n",
1949 SWAP_64(fe->fe_uniq_id), SWAP_32(fe->fe_len_ear),
1950 SWAP_32(fe->fe_len_adesc));
1953 void
1954 print_pmaps(FILE *fout, uint8_t *addr, int32_t count)
1956 struct pmap_hdr *hdr;
1957 struct pmap_typ1 *map1;
1958 struct pmap_typ2 *map2;
1960 while (count--) {
1961 hdr = (struct pmap_hdr *)addr;
1962 switch (hdr->maph_type) {
1963 case 1 :
1964 /* LINTED */
1965 map1 = (struct pmap_typ1 *)hdr;
1966 (void) fprintf(fout, "Map type 1 ");
1967 (void) fprintf(fout, "VSN %x prn %x\n",
1968 SWAP_16(map1->map1_vsn),
1969 SWAP_16(map1->map1_pn));
1970 break;
1971 case 2 :
1972 /* LINTED */
1973 map2 = (struct pmap_typ2 *)hdr;
1974 (void) fprintf(fout, "Map type 2 ");
1975 (void) fprintf(fout, "VSN %x prn %x\n",
1976 SWAP_16(map2->map2_vsn),
1977 SWAP_16(map2->map2_pn));
1978 print_regid(fout, "Partition Type Identifier",
1979 &map2->map2_pti, REG_UDF_ID);
1980 break;
1981 default :
1982 (void) fprintf(fout, "unknown map type\n");
1984 addr += hdr->maph_length;
1990 void
1991 print_short_ad(FILE *fout, char *name, struct short_ad *sad)
1993 (void) fprintf(fout,
1994 "%s loc : %x len : %x\n", name,
1995 SWAP_32(sad->sad_ext_loc), SWAP_32(sad->sad_ext_len));
1998 void
1999 print_long_ad(FILE *fout, char *name, struct long_ad *lad)
2001 (void) fprintf(fout,
2002 "%s prn : %x loc : %x len : %x\n", name,
2003 SWAP_16(lad->lad_ext_prn), SWAP_32(lad->lad_ext_loc),
2004 SWAP_32(lad->lad_ext_len));