1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
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"
44
45 extern char *getfullrawname(char *);
46
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);
53
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);
60
61
62 int
ud_init(int fd,ud_handle_t * hp)63 ud_init(int fd, ud_handle_t *hp)
64 {
65 struct ud_handle *h;
66
67 if ((h = calloc(1, sizeof (struct ud_handle))) == NULL) {
68 return (ENOMEM);
69 }
70 h->fd = fd;
71 *hp = h;
72 return (0);
73 }
74
75 void
ud_fini(ud_handle_t h)76 ud_fini(ud_handle_t h)
77 {
78 free(h);
79 }
80
81 /* ARGSUSED */
82 int32_t
ud_open_dev(ud_handle_t h,char * special,uint32_t flags)83 ud_open_dev(ud_handle_t h, char *special, uint32_t flags)
84 {
85 char *temp;
86 struct stat i_stat, r_stat;
87
88 (void) bzero(&i_stat, sizeof (struct stat));
89 (void) bzero(&r_stat, sizeof (struct stat));
90
91 temp = special;
92 /*
93 * Get the stat structure
94 */
95 if (stat(special, &i_stat) == 0) {
96 if ((i_stat.st_mode & S_IFMT) == S_IFBLK) {
97
98 /*
99 * Block device try to convert to raw device
100 */
101
102 temp = getfullrawname(special);
103
104 /*
105 * Stat the converted device name and verify
106 * both the raw and block device belong to
107 * the same device
108 */
109 if (stat(temp, &r_stat) < 0) {
110 temp = special;
111 } else {
112 if (((r_stat.st_mode & S_IFMT) == S_IFBLK) ||
113 (r_stat.st_rdev != i_stat.st_rdev)) {
114 temp = special;
115 }
116 }
117 }
118 }
119
120 /*
121 * Now finally open the device
122 */
123 h->fd = open(temp, flags);
124
125 return (h->fd);
126 }
127
128 /* ARGSUSED */
129 void
ud_close_dev(ud_handle_t h)130 ud_close_dev(ud_handle_t h)
131 {
132 /*
133 * Too simple Just close it
134 */
135 (void) close(h->fd);
136 }
137
138 int32_t
ud_read_dev(ud_handle_t h,uint64_t offset,uint8_t * buf,uint32_t count)139 ud_read_dev(ud_handle_t h, uint64_t offset, uint8_t *buf, uint32_t count)
140 {
141 /*
142 * Seek to the given offset
143 */
144 if (lseek(h->fd, offset, SEEK_SET) == -1) {
145 return (1);
146 }
147
148 /*
149 * Read the required number of bytes
150 */
151 if (read(h->fd, buf, count) != count) {
152 return (1);
153 }
154 return (0);
155 }
156
157 int32_t
ud_write_dev(ud_handle_t h,uint64_t offset,uint8_t * buf,uint32_t count)158 ud_write_dev(ud_handle_t h, uint64_t offset, uint8_t *buf, uint32_t count)
159 {
160 /*
161 * Seek to the given offset
162 */
163 if (lseek(h->fd, offset, SEEK_SET) == -1) {
164 return (1);
165 }
166
167 /*
168 * Read the appropriate number of bytes
169 */
170 if (write(h->fd, buf, count) != count) {
171 return (1);
172 }
173 return (0);
174 }
175
176 /* ----- BEGIN Read and translate the on disk VDS to IN CORE format -------- */
177
178 int32_t
ud_fill_udfs_info(ud_handle_t h)179 ud_fill_udfs_info(ud_handle_t h)
180 {
181 struct anch_vol_desc_ptr *avdp = NULL;
182 uint32_t offset = 0;
183
184 if (ioctl(h->fd, CDROMREADOFFSET, &offset) == -1) {
185 offset = 0;
186 }
187
188 h->udfs.flags = INVALID_UDFS;
189
190 h->udfs.ecma_version = ud_get_ecma_ver(h, offset);
191 if (h->udfs.ecma_version == UD_ECMA_UNKN) {
192 return (1);
193 }
194
195 h->udfs.lbsize = ud_get_fs_bsize(h, offset, &h->udfs.avdp_loc);
196 if (h->udfs.lbsize == 0) {
197 return (2);
198 }
199
200 h->udfs.avdp_len = lb_roundup(512, h->udfs.lbsize);
201
202
203 if ((avdp = (struct anch_vol_desc_ptr *)
204 malloc(h->udfs.lbsize)) == NULL) {
205 return (3);
206 }
207 if (ud_read_dev(h, h->udfs.avdp_loc * h->udfs.lbsize,
208 (uint8_t *)avdp, h->udfs.lbsize) != 0) {
209 free(avdp);
210 return (4);
211 }
212 if (ud_verify_tag(h, &avdp->avd_tag, UD_ANCH_VOL_DESC,
213 h->udfs.avdp_loc, 1, 0) != 0) {
214 free(avdp);
215 return (5);
216 }
217
218 h->udfs.mvds_loc = SWAP_32(avdp->avd_main_vdse.ext_loc);
219 h->udfs.mvds_len = SWAP_32(avdp->avd_main_vdse.ext_len);
220
221 h->udfs.rvds_loc = SWAP_32(avdp->avd_res_vdse.ext_loc);
222 h->udfs.rvds_len = SWAP_32(avdp->avd_res_vdse.ext_len);
223
224 free(avdp);
225
226 /*
227 * get information from mvds and rvds
228 */
229 if (ud_parse_fill_vds(h, &h->udfs.mvds,
230 h->udfs.mvds_loc, h->udfs.mvds_len) == 0) {
231 h->udfs.flags |= VALID_MVDS;
232 }
233 if (ud_parse_fill_vds(h, &h->udfs.rvds,
234 h->udfs.rvds_loc, h->udfs.rvds_len) == 0) {
235 h->udfs.flags |= VALID_RVDS;
236 }
237
238 if ((h->udfs.flags & (VALID_MVDS | VALID_RVDS)) == 0) {
239 return (6);
240 }
241
242 /*
243 * If we are here we have
244 * a valid Volume Descriptor Seqence
245 * Read and understand lvd
246 */
247 if (h->udfs.flags & VALID_MVDS) {
248 if (ud_read_and_translate_lvd(h, h->udfs.mvds.lvd_loc,
249 h->udfs.mvds.lvd_len) != 0) {
250 return (7);
251 }
252 } else {
253 if (ud_read_and_translate_lvd(h, h->udfs.rvds.lvd_loc,
254 h->udfs.rvds.lvd_len) != 0) {
255 return (8);
256 }
257 }
258
259 h->udfs.flags |= VALID_UDFS;
260
261 return (0);
262 }
263
264 static int32_t
ud_get_ecma_ver(ud_handle_t h,uint32_t offset)265 ud_get_ecma_ver(ud_handle_t h, uint32_t offset)
266 {
267 uint8_t *buf;
268 uint64_t off;
269 uint64_t end_off;
270 struct nsr_desc *ndsc;
271 uint32_t ecma_ver = UD_ECMA_UNKN;
272
273 /*
274 * Allocate a buffer of size UD_VOL_REC_BSZ
275 */
276 if ((buf = (uint8_t *)malloc(UD_VOL_REC_BSZ)) == NULL) {
277
278 /*
279 * Uh could not even allocate this much
280 */
281 goto end;
282 }
283
284 /*
285 * Start from 32k and keep reading 2k blocks we
286 * should be able to find NSR if we have one by 256 * 2k bytes
287 */
288 off = offset * 2048 + UD_VOL_REC_START;
289 end_off = offset * 2048 + UD_VOL_REC_END;
290 for (; off < end_off; off += UD_VOL_REC_BSZ) {
291
292 if (ud_read_dev(h, off, buf, UD_VOL_REC_BSZ) == 0) {
293
294 ndsc = (struct nsr_desc *)buf;
295 /*
296 * Is this either NSR02 or NSR03
297 */
298 if ((ndsc->nsr_str_type == 0) &&
299 (ndsc->nsr_ver == 1) &&
300 (ndsc->nsr_id[0] == 'N') &&
301 (ndsc->nsr_id[1] == 'S') &&
302 (ndsc->nsr_id[2] == 'R') &&
303 (ndsc->nsr_id[3] == '0') &&
304 ((ndsc->nsr_id[4] == '2') ||
305 (ndsc->nsr_id[4] == '3'))) {
306
307 (void) strncpy((char *)h->udfs.ecma_id,
308 (char *)ndsc->nsr_id, 5);
309
310 switch (ndsc->nsr_id[4]) {
311 case '2' :
312
313 /*
314 * ECMA 167/2
315 */
316 ecma_ver = UD_ECMA_VER2;
317 goto end;
318 case '3' :
319
320 /*
321 * ECMA 167/3
322 */
323 ecma_ver = UD_ECMA_VER3;
324 goto end;
325 }
326 }
327 }
328 }
329
330 end:
331 /*
332 * Cleanup
333 */
334 free(buf);
335 return (ecma_ver);
336 }
337
338 static uint32_t last_block_index[] = {0, 0, 256, 2, 2 + 256,
339 150, 150 + 256, 152, 152 + 256};
340
341 static int32_t
ud_get_fs_bsize(ud_handle_t h,uint32_t offset,uint32_t * avd_loc)342 ud_get_fs_bsize(ud_handle_t h, uint32_t offset, uint32_t *avd_loc)
343 {
344 uint64_t off;
345 int32_t index, bsize, shift, end_index;
346 uint32_t num_blocks, sub_blk;
347 uint8_t *buf = NULL;
348 struct anch_vol_desc_ptr *avdp;
349
350 if ((buf = (uint8_t *)malloc(MAXBSIZE)) == NULL) {
351 return (0);
352 }
353
354 /*
355 * If we could figure out the last block
356 * search at 256, N, N - 256 blocks
357 * otherwise just check at 256
358 */
359 if (ud_get_num_blks(h, &num_blocks) != 0) {
360 end_index = 1;
361 num_blocks = 0;
362 } else {
363 end_index = sizeof (last_block_index) / 4;
364 }
365
366 for (index = 0; index < end_index; index++) {
367 sub_blk = last_block_index[index];
368
369 /*
370 * Start guessing from DEV_BSIZE to MAXBSIZE
371 */
372 for (bsize = DEV_BSIZE, shift = 0;
373 bsize <= MAXBSIZE; bsize <<= 1, shift++) {
374
375 if (index == 0) {
376
377 /*
378 * Check if we atleast have 256 of bsize
379 * blocks on the device
380 */
381 if ((end_index == 0) ||
382 (num_blocks > (256 << shift))) {
383 *avd_loc = 256;
384 if (bsize <= 2048) {
385 *avd_loc +=
386 offset * 2048 / bsize;
387 } else {
388 *avd_loc +=
389 offset / (bsize / 2048);
390 }
391 } else {
392 continue;
393 }
394 } else {
395 /*
396 * Calculate the bsize avd block
397 */
398 if ((num_blocks) &&
399 (num_blocks > (sub_blk << shift))) {
400 *avd_loc = (num_blocks >> shift) -
401 sub_blk;
402 } else {
403 continue;
404 }
405 }
406
407 off = (uint64_t)*avd_loc * bsize;
408
409 /*
410 * Read bsize bytes at off
411 */
412 if (ud_read_dev(h, off, buf, bsize) != 0) {
413 continue;
414 }
415
416 /*
417 * Check if we have a Anchor Volume Descriptor here
418 */
419
420 /* LINTED */
421 avdp = (struct anch_vol_desc_ptr *)buf;
422 if (ud_verify_tag(h, &avdp->avd_tag,
423 UD_ANCH_VOL_DESC, *avd_loc, 1, 0) != 0) {
424 continue;
425 }
426 goto end;
427 }
428 }
429
430 end:
431 if (bsize > MAXBSIZE) {
432 bsize = 0;
433 *avd_loc = 0;
434 }
435 free(buf);
436 return (bsize);
437 }
438
439 static int32_t
ud_parse_fill_vds(ud_handle_t h,struct vds * v,uint32_t vds_loc,uint32_t vds_len)440 ud_parse_fill_vds(ud_handle_t h, struct vds *v,
441 uint32_t vds_loc, uint32_t vds_len)
442 {
443 uint8_t *addr, *taddr, *eaddr;
444 uint16_t id;
445 int32_t i;
446 uint64_t off;
447 struct tag *tag;
448 struct pri_vol_desc *pvd;
449 struct log_vol_desc *lvd;
450 struct vol_desc_ptr *vds;
451 struct unall_spc_desc *usd;
452
453 begin:
454 if ((addr = (uint8_t *)malloc(vds_len)) == NULL) {
455 return (1);
456 }
457
458 off = vds_loc * h->udfs.lbsize;
459 if (ud_read_dev(h, off, addr, vds_len) != 0) {
460 goto end;
461 }
462
463 for (taddr = addr, eaddr = addr + h->udfs.mvds_len; taddr < eaddr;
464 taddr += h->udfs.lbsize, vds_loc ++) {
465
466 /* LINTED */
467 tag = (struct tag *)taddr;
468 id = SWAP_16(tag->tag_id);
469 /*
470 * If you cannot verify the tag just skip it
471 * This is not a fatal error
472 */
473 if (ud_verify_tag(h, tag, id, vds_loc, 1, 0) != 0) {
474 continue;
475 }
476 switch (id) {
477 case UD_PRI_VOL_DESC :
478
479 /*
480 * Primary Volume Descriptor
481 */
482 /* LINTED */
483 pvd = (struct pri_vol_desc *)taddr;
484 if ((v->pvd_len == 0) ||
485 (SWAP_32(pvd->pvd_vdsn) > v->pvd_vdsn)) {
486 v->pvd_vdsn = SWAP_32(pvd->pvd_vdsn);
487 v->pvd_loc = vds_loc;
488 v->pvd_len = h->udfs.lbsize;
489 }
490 break;
491 case UD_VOL_DESC_PTR :
492
493 /*
494 * Curent sequence is continued from
495 * the location pointed by vdp
496 */
497 /* LINTED */
498 vds = (struct vol_desc_ptr *)taddr;
499
500 if (SWAP_32(vds->vdp_nvdse.ext_len) != 0) {
501 vds_loc = SWAP_32(vds->vdp_nvdse.ext_loc);
502 vds_len = SWAP_32(vds->vdp_nvdse.ext_len);
503 free(addr);
504 goto begin;
505 }
506 break;
507 case UD_IMPL_USE_DESC :
508
509 /*
510 * Implementation Use Volume Descriptor
511 */
512 v->iud_loc = vds_loc;
513 v->iud_len = lb_roundup(512, h->udfs.lbsize);
514 break;
515 case UD_PART_DESC :
516 {
517 struct ud_part *p;
518 struct phdr_desc *ph;
519 struct part_desc *pd;
520
521 /*
522 * Partition Descriptor
523 */
524 /* LINTED */
525 pd = (struct part_desc *)taddr;
526
527 for (i = 0; i < h->n_parts; i++) {
528 p = &h->part[i];
529
530 if ((SWAP_16(pd->pd_pnum) ==
531 p->udp_number) &&
532 (SWAP_32(pd->pd_vdsn) >
533 p->udp_seqno)) {
534 break;
535 }
536 }
537
538 v->part_loc[i] = vds_loc;
539 v->part_len[i] =
540 lb_roundup(512, h->udfs.lbsize);
541
542 p = &h->part[i];
543 p->udp_number = SWAP_16(pd->pd_pnum);
544 p->udp_seqno = SWAP_32(pd->pd_vdsn);
545 p->udp_access = SWAP_32(pd->pd_acc_type);
546 p->udp_start = SWAP_32(pd->pd_part_start);
547 p->udp_length = SWAP_32(pd->pd_part_length);
548
549 /* LINTED */
550 ph = (struct phdr_desc *)pd->pd_pc_use;
551 if (ph->phdr_ust.sad_ext_len) {
552 p->udp_flags = UDP_SPACETBLS;
553 p->udp_unall_loc = SWAP_32(ph->phdr_ust.sad_ext_loc);
554 p->udp_unall_len = SWAP_32(ph->phdr_ust.sad_ext_len);
555 p->udp_freed_loc = SWAP_32(ph->phdr_fst.sad_ext_loc);
556 p->udp_freed_len = SWAP_32(ph->phdr_fst.sad_ext_len);
557 } else {
558 p->udp_flags = UDP_BITMAPS;
559 p->udp_unall_loc = SWAP_32(ph->phdr_usb.sad_ext_loc);
560 p->udp_unall_len = SWAP_32(ph->phdr_usb.sad_ext_len);
561 p->udp_freed_loc = SWAP_32(ph->phdr_fsb.sad_ext_loc);
562 p->udp_freed_len = SWAP_32(ph->phdr_fsb.sad_ext_len);
563 }
564
565 if (i == h->n_parts) {
566 h->n_parts ++;
567 }
568 }
569 break;
570 case UD_LOG_VOL_DESC :
571
572 /*
573 * Logical Volume Descriptor
574 */
575 /* LINTED */
576 lvd = (struct log_vol_desc *)taddr;
577 if ((v->lvd_len == 0) ||
578 (SWAP_32(lvd->lvd_vdsn) > v->lvd_vdsn)) {
579 v->lvd_vdsn = SWAP_32(lvd->lvd_vdsn);
580 v->lvd_loc = vds_loc;
581 v->lvd_len = ((uint32_t)
582 &((struct log_vol_desc *)0)->lvd_pmaps);
583 v->lvd_len =
584 lb_roundup(v->lvd_len, h->udfs.lbsize);
585 }
586 break;
587 case UD_UNALL_SPA_DESC :
588
589 /*
590 * Unallocated Space Descriptor
591 */
592 /* LINTED */
593 usd = (struct unall_spc_desc *)taddr;
594 v->usd_loc = vds_loc;
595 v->usd_len = ((uint32_t)
596 &((unall_spc_desc_t *)0)->ua_al_dsc) +
597 SWAP_32(usd->ua_nad) *
598 sizeof (struct extent_ad);
599 v->usd_len = lb_roundup(v->usd_len, h->udfs.lbsize);
600 break;
601 case UD_TERM_DESC :
602 /*
603 * Success fully completed
604 */
605 goto end;
606 default :
607 /*
608 * If you donot undetstand any tag just skip
609 * it. This is not a fatal error
610 */
611 break;
612 }
613 }
614
615 end:
616 free(addr);
617 if ((v->pvd_len == 0) ||
618 (v->part_len[0] == 0) ||
619 (v->lvd_len == 0)) {
620 return (1);
621 }
622
623 return (0);
624 }
625
626 static int32_t
ud_read_and_translate_lvd(ud_handle_t h,uint32_t lvd_loc,uint32_t lvd_len)627 ud_read_and_translate_lvd(ud_handle_t h, uint32_t lvd_loc, uint32_t lvd_len)
628 {
629 caddr_t addr;
630 uint16_t fsd_prn;
631 uint32_t fsd_loc, fsd_len;
632 uint32_t lvds_loc, lvds_len;
633 uint64_t off;
634 struct log_vol_desc *lvd = NULL;
635
636 int32_t max_maps, i, mp_sz, index;
637 struct ud_map *m;
638 struct pmap_hdr *ph;
639 struct pmap_typ1 *typ1;
640 struct pmap_typ2 *typ2;
641
642 if (lvd_len == 0) {
643 return (1);
644 }
645
646 if ((lvd = (struct log_vol_desc *)
647 malloc(lvd_len)) == NULL) {
648 return (1);
649 }
650
651 off = lvd_loc * h->udfs.lbsize;
652 if (ud_read_dev(h, off, (uint8_t *)lvd, lvd_len) != 0) {
653 free(lvd);
654 return (1);
655 }
656
657 if (ud_verify_tag(h, &lvd->lvd_tag, UD_LOG_VOL_DESC,
658 lvd_loc, 1, 0) != 0) {
659 free(lvd);
660 return (1);
661 }
662
663 /*
664 * Take care of maps
665 */
666 max_maps = SWAP_32(lvd->lvd_num_pmaps);
667 ph = (struct pmap_hdr *)lvd->lvd_pmaps;
668 for (h->n_maps = index = 0; index < max_maps; index++) {
669 m = &h->maps[h->n_maps];
670 switch (ph->maph_type) {
671 case MAP_TYPE1 :
672
673 /* LINTED */
674 typ1 = (struct pmap_typ1 *)ph;
675
676 m->udm_flags = UDM_MAP_NORM;
677 m->udm_vsn = SWAP_16(typ1->map1_vsn);
678 m->udm_pn = SWAP_16(typ1->map1_pn);
679 h->n_maps++;
680 break;
681
682 case MAP_TYPE2 :
683
684 /* LINTED */
685 typ2 = (struct pmap_typ2 *)ph;
686
687 if (strncmp(typ2->map2_pti.reg_id,
688 UDF_VIRT_PART, 23) == 0) {
689
690 m->udm_flags = UDM_MAP_VPM;
691 m->udm_vsn = SWAP_16(typ2->map2_vsn);
692 m->udm_pn = SWAP_16(typ2->map2_pn);
693 } else if (strncmp(typ2->map2_pti.reg_id,
694 UDF_SPAR_PART, 23) == 0) {
695
696 if ((SWAP_16(typ2->map2_pl) != 32) ||
697 (typ2->map2_nst < 1) ||
698 (typ2->map2_nst > 4)) {
699 break;
700 }
701 m->udm_flags = UDM_MAP_SPM;
702 m->udm_vsn = SWAP_16(typ2->map2_vsn);
703 m->udm_pn = SWAP_16(typ2->map2_pn);
704
705 m->udm_plen = SWAP_16(typ2->map2_pl);
706 m->udm_nspm = typ2->map2_nst;
707 m->udm_spsz = SWAP_32(typ2->map2_sest);
708
709 mp_sz = lb_roundup(m->udm_spsz, h->udfs.lbsize);
710
711 if ((addr = malloc(mp_sz * m->udm_nspm)) ==
712 NULL) {
713 break;
714 }
715
716 for (i = 0; i < m->udm_nspm; i++) {
717 m->udm_loc[i] =
718 SWAP_32(typ2->map2_st[index]);
719 m->udm_spaddr[i] = addr + i * mp_sz;
720
721 off = m->udm_loc[i] * h->udfs.lbsize;
722 if (ud_read_dev(h, off,
723 (uint8_t *)m->udm_spaddr[i],
724 mp_sz) != 0) {
725 m->udm_spaddr[i] = NULL;
726 continue;
727 }
728 }
729 }
730 h->n_maps++;
731 default :
732 break;
733 }
734 ph = (struct pmap_hdr *)(((uint8_t *)h) + ph->maph_length);
735 }
736
737 lvds_loc = SWAP_32(lvd->lvd_int_seq_ext.ext_loc);
738 lvds_len = SWAP_32(lvd->lvd_int_seq_ext.ext_len);
739
740 fsd_prn = SWAP_16(lvd->lvd_lvcu.lad_ext_prn);
741 fsd_loc = SWAP_32(lvd->lvd_lvcu.lad_ext_loc);
742 fsd_len = SWAP_32(lvd->lvd_lvcu.lad_ext_len);
743
744 free(lvd);
745
746 /*
747 * Get the latest LVID
748 */
749 if (ud_get_latest_lvid(h, lvds_loc, lvds_len) != 0) {
750 return (1);
751 }
752
753 if (ud_get_latest_fsd(h, fsd_prn, fsd_loc, fsd_len) != 0) {
754 return (1);
755 }
756
757 return (0);
758 }
759
760 static int32_t
ud_get_latest_lvid(ud_handle_t h,uint32_t lvds_loc,uint32_t lvds_len)761 ud_get_latest_lvid(ud_handle_t h, uint32_t lvds_loc, uint32_t lvds_len)
762 {
763 uint8_t *addr, *taddr, *eaddr;
764 uint16_t id;
765 uint64_t off;
766 struct tag *tag;
767 struct log_vol_int_desc *lvid;
768
769 begin:
770 if ((addr = (uint8_t *)malloc(lvds_len)) == NULL) {
771 return (1);
772 }
773
774 off = lvds_loc * h->udfs.lbsize;
775 if (ud_read_dev(h, off, addr, lvds_len) != 0) {
776 goto end;
777 }
778
779 for (taddr = addr, eaddr = addr + h->udfs.mvds_len; taddr < eaddr;
780 taddr += h->udfs.lbsize, lvds_loc ++) {
781
782 /* LINTED */
783 tag = (struct tag *)taddr;
784 id = SWAP_16(tag->tag_id);
785 /*
786 * If you cannot verify the tag just skip it
787 * This is not a fatal error
788 */
789 if (ud_verify_tag(h, tag, id, lvds_loc, 1, 0) != 0) {
790 continue;
791 }
792 switch (id) {
793 case UD_LOG_VOL_INT :
794
795 /*
796 * Logical Volume Integrity Descriptor
797 */
798 /* LINTED */
799 lvid = (struct log_vol_int_desc *)taddr;
800 h->udfs.lvid_loc = lvds_loc;
801 h->udfs.lvid_len = ((uint32_t)
802 &((struct log_vol_int_desc *)0)->lvid_fst) +
803 SWAP_32(lvid->lvid_npart) * 8 +
804 SWAP_32(lvid->lvid_liu);
805 h->udfs.lvid_len = lb_roundup(h->udfs.lvid_len,
806 h->udfs.lbsize);
807
808 /*
809 * It seems we have a next integrity
810 * sequence
811 */
812 if (SWAP_32(lvid->lvid_nie.ext_len) != 0) {
813 free(addr);
814 lvds_loc = SWAP_32(lvid->lvid_nie.ext_loc);
815 lvds_len = SWAP_32(lvid->lvid_nie.ext_len);
816 goto begin;
817 }
818 goto end;
819 case UD_TERM_DESC :
820
821 /*
822 * Success fully completed
823 */
824 goto end;
825 default :
826 /*
827 * If you donot undetstand any tag just skip
828 * it. This is not a fatal error
829 */
830 break;
831 }
832 }
833 end:
834 free(addr);
835 if (h->udfs.lvid_len == 0) {
836 return (1);
837 }
838 return (0);
839 }
840
841 static int32_t
ud_get_latest_fsd(ud_handle_t h,uint16_t fsd_prn,uint32_t fsd_loc,uint32_t fsd_len)842 ud_get_latest_fsd(ud_handle_t h, uint16_t fsd_prn,
843 uint32_t fsd_loc, uint32_t fsd_len)
844 {
845 uint8_t *addr, *taddr, *eaddr;
846 uint16_t id;
847 uint64_t off;
848 uint32_t fsds_loc, fsds_len;
849 struct tag *tag;
850 struct file_set_desc *fsd;
851 uint32_t old_fsn = 0;
852
853 begin:
854 h->udfs.fsds_prn = fsd_prn;
855 h->udfs.fsds_loc = fsd_loc;
856 h->udfs.fsds_len = fsd_len;
857
858 fsds_loc = ud_xlate_to_daddr(h, fsd_prn, fsd_loc);
859 fsds_len = lb_roundup(fsd_len, h->udfs.lbsize);
860
861 if ((addr = (uint8_t *)malloc(fsds_len)) == NULL) {
862 return (1);
863 }
864
865 off = fsds_loc * h->udfs.lbsize;
866 if (ud_read_dev(h, off, addr, fsds_len) != 0) {
867 goto end;
868 }
869
870 for (taddr = addr, eaddr = addr + h->udfs.mvds_len; taddr < eaddr;
871 taddr += h->udfs.lbsize, fsds_loc ++) {
872
873 /* LINTED */
874 tag = (struct tag *)taddr;
875 id = SWAP_16(tag->tag_id);
876 /*
877 * If you cannot verify the tag just skip it
878 * This is not a fatal error
879 */
880 if (ud_verify_tag(h, tag, id, fsds_loc, 1, 0) != 0) {
881 continue;
882 }
883 switch (id) {
884 case UD_FILE_SET_DESC :
885 /* LINTED */
886 fsd = (struct file_set_desc *)taddr;
887 if ((h->udfs.fsd_len == 0) ||
888 (SWAP_32(fsd->fsd_fs_no) > old_fsn)) {
889 old_fsn = SWAP_32(fsd->fsd_fs_no);
890 h->udfs.fsd_loc = fsds_loc;
891 h->udfs.fsd_len = lb_roundup(512,
892 h->udfs.lbsize);
893 h->udfs.ricb_prn =
894 SWAP_16(fsd->fsd_root_icb.lad_ext_prn);
895 h->udfs.ricb_loc =
896 SWAP_32(fsd->fsd_root_icb.lad_ext_loc);
897 h->udfs.ricb_len =
898 SWAP_32(fsd->fsd_root_icb.lad_ext_len);
899 }
900 if (SWAP_32(fsd->fsd_next.lad_ext_len) != 0) {
901 fsd_prn = SWAP_16(fsd->fsd_next.lad_ext_prn);
902 fsd_loc = SWAP_32(fsd->fsd_next.lad_ext_loc);
903 fsd_len = SWAP_32(fsd->fsd_next.lad_ext_len);
904 goto begin;
905 }
906 break;
907 case UD_TERM_DESC :
908
909 /*
910 * Success fully completed
911 */
912 goto end;
913 default :
914 /*
915 * If you donot undetstand any tag just skip
916 * it. This is not a fatal error
917 */
918 break;
919 }
920 }
921
922 end:
923 free(addr);
924 if (h->udfs.fsd_len == 0) {
925 return (1);
926 }
927 return (0);
928 }
929
930 int32_t
ud_get_num_blks(ud_handle_t h,uint32_t * blkno)931 ud_get_num_blks(ud_handle_t h, uint32_t *blkno)
932 {
933 struct vtoc vtoc;
934 struct dk_cinfo dki_info;
935 int32_t error;
936
937 /*
938 * Get VTOC from driver
939 */
940 if ((error = ioctl(h->fd, DKIOCGVTOC, (intptr_t)&vtoc)) != 0) {
941 return (error);
942 }
943
944 /*
945 * Verify if is proper
946 */
947 if (vtoc.v_sanity != VTOC_SANE) {
948 return (EINVAL);
949 }
950
951 /*
952 * Get dk_cinfo from driver
953 */
954 if ((error = ioctl(h->fd, DKIOCINFO, (intptr_t)&dki_info)) != 0) {
955 return (error);
956 }
957
958 if (dki_info.dki_partition >= V_NUMPAR) {
959 return (EINVAL);
960 }
961
962 /*
963 * Return the size of the partition
964 */
965 *blkno = vtoc.v_part[dki_info.dki_partition].p_size;
966
967 return (0);
968 }
969
970 uint32_t
ud_xlate_to_daddr(ud_handle_t h,uint16_t prn,uint32_t blkno)971 ud_xlate_to_daddr(ud_handle_t h, uint16_t prn, uint32_t blkno)
972 {
973 int32_t i;
974 struct ud_map *m;
975 struct ud_part *p;
976
977
978 if (prn < h->n_maps) {
979 m = &h->maps[prn];
980 for (i = 0; i < h->n_parts; i++) {
981 p = &h->part[i];
982 if (m->udm_pn == p->udp_number) {
983 return (p->udp_start + blkno);
984 }
985 }
986 }
987 return (0);
988 }
989
990 /* ------ END Read and translate the on disk VDS to IN CORE format -------- */
991
992 int32_t
ud_verify_tag(ud_handle_t h,struct tag * tag,uint16_t id,uint32_t blockno,int32_t do_crc,int32_t print_msg)993 ud_verify_tag(ud_handle_t h, struct tag *tag, uint16_t id,
994 uint32_t blockno, int32_t do_crc, int32_t print_msg)
995 {
996 int32_t i;
997 uint8_t *addr, cksum = 0;
998 uint16_t crc;
999
1000
1001 /*
1002 * Verify Tag Identifier
1003 */
1004 if (tag->tag_id != SWAP_16(id)) {
1005 if (print_msg != 0) {
1006 (void) fprintf(stderr,
1007 gettext("tag does not verify tag %x req %x\n"),
1008 SWAP_16(tag->tag_id), id);
1009 }
1010 return (1);
1011 }
1012
1013 /*
1014 * Verify Tag Descriptor Version
1015 */
1016 if (SWAP_16(tag->tag_desc_ver) != h->udfs.ecma_version) {
1017 if (print_msg != 0) {
1018 (void) fprintf(stderr,
1019 gettext("tag version does not match with "
1020 "NSR descriptor version TAG %x NSR %x\n"),
1021 SWAP_16(tag->tag_desc_ver),
1022 h->udfs.ecma_version);
1023 }
1024 return (1);
1025 }
1026
1027 /*
1028 * Caliculate Tag Checksum
1029 */
1030 addr = (uint8_t *)tag;
1031 for (i = 0; i <= 15; i++) {
1032 if (i != 4) {
1033 cksum += addr[i];
1034 }
1035 }
1036
1037 /*
1038 * Verify Tag Checksum
1039 */
1040 if (cksum != tag->tag_cksum) {
1041 if (print_msg != 0) {
1042 (void) fprintf(stderr,
1043 gettext("Checksum Does not Verify TAG"
1044 " %x CALC %x\n"), tag->tag_cksum, cksum);
1045 }
1046 return (1);
1047 }
1048
1049
1050 /*
1051 * Do we want to do crc
1052 */
1053 if (do_crc) {
1054 if (tag->tag_crc_len) {
1055
1056 /*
1057 * Caliculate CRC for the descriptor
1058 */
1059 crc = ud_crc(addr + 0x10, SWAP_16(tag->tag_crc_len));
1060
1061 /*
1062 * Verify CRC
1063 */
1064 if (crc != SWAP_16(tag->tag_crc)) {
1065 if (print_msg != 0) {
1066 (void) fprintf(stderr,
1067 gettext("CRC Does not verify"
1068 " TAG %x CALC %x %x\n"),
1069 SWAP_16(tag->tag_crc),
1070 crc, addr);
1071 }
1072 }
1073 }
1074
1075 /*
1076 * Verify Tag Location
1077 */
1078 if (SWAP_32(blockno) != tag->tag_loc) {
1079 if (print_msg != 0) {
1080 (void) fprintf(stderr,
1081 gettext("Tag Location Does not verify"
1082 " blockno %x tag_blockno %x\n"),
1083 blockno, SWAP_32(tag->tag_loc));
1084 }
1085 }
1086 }
1087
1088 return (0);
1089 }
1090
1091
1092 /* ARGSUSED1 */
1093 void
ud_make_tag(ud_handle_t h,struct tag * tag,uint16_t tag_id,uint32_t blkno,uint16_t crc_len)1094 ud_make_tag(ud_handle_t h, struct tag *tag, uint16_t tag_id,
1095 uint32_t blkno, uint16_t crc_len)
1096 {
1097 int32_t i;
1098 uint16_t crc;
1099 uint8_t *addr, cksum = 0;
1100
1101 tag->tag_id = SWAP_16(tag_id);
1102 tag->tag_desc_ver = SWAP_16(h->udfs.ecma_version);
1103 tag->tag_cksum = 0;
1104 tag->tag_res = 0;
1105
1106 /*
1107 * Calicualte and assign CRC, CRC_LEN
1108 */
1109 addr = (uint8_t *)tag;
1110 crc = ud_crc(addr + 0x10, crc_len);
1111 tag->tag_crc = SWAP_16(crc);
1112 tag->tag_crc_len = SWAP_16(crc_len);
1113 tag->tag_loc = SWAP_32(blkno);
1114
1115 /*
1116 * Caliculate Checksum
1117 */
1118 for (i = 0; i <= 15; i++) {
1119 cksum += addr[i];
1120 }
1121
1122 /*
1123 * Assign Checksum
1124 */
1125 tag->tag_cksum = cksum;
1126 }
1127
1128 /* **************** udf specific subroutines *********************** */
1129
1130 static uint16_t ud_crc_table[256] = {
1131 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
1132 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
1133 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
1134 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
1135 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
1136 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
1137 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
1138 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
1139 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
1140 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
1141 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
1142 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
1143 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
1144 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
1145 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
1146 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
1147 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
1148 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
1149 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
1150 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
1151 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
1152 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
1153 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
1154 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
1155 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
1156 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
1157 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
1158 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
1159 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
1160 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
1161 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
1162 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
1163 };
1164
1165 static uint16_t
ud_crc(uint8_t * addr,int32_t len)1166 ud_crc(uint8_t *addr, int32_t len)
1167 {
1168 uint16_t crc = 0;
1169
1170 while (len-- > 0) {
1171 crc = ud_crc_table[(crc >> 8 ^ *addr++) & 0xff] ^ (crc<<8);
1172 }
1173
1174 return (crc);
1175 }
1176
1177 #define MAXNAMLEN 0x200
1178
1179
1180 #define POUND 0x0023
1181 #define DOT 0x002E
1182 #define SLASH 0x002F
1183 #define UNDERBAR 0x005F
1184
1185
1186 static uint16_t htoc[16] = {'0', '1', '2', '3',
1187 '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
1188 /*
1189 * unicode is the string of 16-bot characters
1190 * length is the number of 16-bit characters
1191 */
1192 static int32_t
UdfTxName(uint16_t * unicode,int32_t count)1193 UdfTxName(uint16_t *unicode, int32_t count)
1194 {
1195 int32_t i, j, k, lic, make_crc, dot_loc;
1196 uint16_t crc;
1197
1198 if ((unicode[0] == DOT) &&
1199 ((count == 1) || ((count == 2) && (unicode[1] == DOT)))) {
1200 crc = DOT;
1201 if (count == 2) {
1202 crc += DOT;
1203 }
1204 unicode[0] = UNDERBAR;
1205 unicode[1] = POUND;
1206 unicode[2] = htoc[(uint16_t)(crc & 0xf000) >> 12];
1207 unicode[3] = htoc[(uint16_t)(crc & 0xf00) >> 8];
1208 unicode[4] = htoc[(uint16_t)(crc & 0xf0) >> 4];
1209 unicode[5] = htoc[crc & 0xf];
1210 return (6);
1211 }
1212 crc = 0;
1213 j = make_crc = 0;
1214 lic = dot_loc = -1;
1215 for (i = 0; i < count; i++) {
1216 if (make_crc) {
1217 crc += unicode[i];
1218 }
1219 if (unicode[i] == DOT) {
1220 dot_loc = j;
1221 }
1222 if ((unicode[i] == SLASH) ||
1223 (unicode[i] == 0)) {
1224 if (make_crc == 0) {
1225 for (k = 0; k <= i; k++) {
1226 crc += unicode[k];
1227 }
1228 make_crc = 1;
1229 }
1230 if (lic != (i - 1)) {
1231 unicode[j++] = UNDERBAR;
1232 }
1233 lic = i;
1234 } else {
1235 unicode[j++] = unicode[i];
1236 }
1237 }
1238
1239 if (make_crc) {
1240 if (dot_loc != -1) {
1241 if ((j + 5) > MAXNAMLEN) {
1242 if ((j - dot_loc + 5) > MAXNAMLEN) {
1243 j = MAXNAMLEN - 5 + dot_loc;
1244 for (k = MAXNAMLEN;
1245 j >= dot_loc; k --, j--) {
1246 unicode[k] = unicode[j];
1247 }
1248 k = 0;
1249 } else {
1250 for (k = MAXNAMLEN;
1251 j >= dot_loc; k--, j--) {
1252 unicode[k] = unicode[j];
1253 }
1254 k -= 4;
1255 }
1256 j = MAXNAMLEN;
1257 } else {
1258 for (k = j; k >= dot_loc; k--) {
1259 unicode[k + 5] = unicode[k];
1260 }
1261 k = dot_loc;
1262 j += 5;
1263 }
1264 } else {
1265 if ((j + 5) > MAXNAMLEN) {
1266 j = MAXNAMLEN;
1267 k = MAXNAMLEN - 5;
1268 } else {
1269 k = j;
1270 j += 5;
1271 }
1272 }
1273 unicode[k++] = POUND;
1274 unicode[k++] = htoc[(uint16_t)(crc & 0xf000) >> 12];
1275 unicode[k++] = htoc[(uint16_t)(crc & 0xf00) >> 8];
1276 unicode[k++] = htoc[(uint16_t)(crc & 0xf0) >> 4];
1277 unicode[k++] = htoc[crc & 0xf];
1278 }
1279 return (j);
1280 }
1281
1282 /*
1283 * Assumes the output buffer is large
1284 * enough to hold the uncompressed
1285 * code
1286 */
1287 static int32_t
UncompressUnicode(int32_t numberOfBytes,uint8_t * UDFCompressed,uint16_t * unicode)1288 UncompressUnicode(
1289 int32_t numberOfBytes, /* (Input) number of bytes read from media. */
1290 uint8_t *UDFCompressed, /* (Input) bytes read from media. */
1291 uint16_t *unicode) /* (Output) uncompressed unicode characters. */
1292 {
1293 int32_t compID;
1294 int32_t returnValue, unicodeIndex, byteIndex;
1295
1296
1297 /*
1298 * Use UDFCompressed to store current byte being read.
1299 */
1300 compID = UDFCompressed[0];
1301
1302 /* First check for valid compID. */
1303 if (compID != 8 && compID != 16) {
1304 returnValue = -1;
1305 } else {
1306 unicodeIndex = 0;
1307 byteIndex = 1;
1308
1309 /* Loop through all the bytes. */
1310 while (byteIndex < numberOfBytes) {
1311 if (compID == 16) {
1312 /*
1313 * Move the first byte to the
1314 * high bits of the unicode char.
1315 */
1316 unicode[unicodeIndex] =
1317 UDFCompressed[byteIndex++] << 8;
1318 } else {
1319 unicode[unicodeIndex] = 0;
1320 }
1321 if (byteIndex < numberOfBytes) {
1322 /*
1323 * Then the next byte to the low bits.
1324 */
1325 unicode[unicodeIndex] |=
1326 UDFCompressed[byteIndex++];
1327 }
1328 unicodeIndex++;
1329 }
1330 returnValue = unicodeIndex;
1331 }
1332 return (returnValue);
1333 }
1334
1335
1336
1337
1338
1339 static int32_t
ud_compressunicode(int32_t numberOfChars,int32_t compID,uint16_t * unicode,uint8_t * UDFCompressed)1340 ud_compressunicode(
1341 int32_t numberOfChars, /* (Input) number of unicode characters. */
1342 int32_t compID, /* (Input) compression ID to be used. */
1343 uint16_t *unicode, /* (Input) unicode characters to compress. */
1344 uint8_t *UDFCompressed) /* (Output) compressed string, as bytes. */
1345 {
1346 int32_t byteIndex;
1347
1348 if (compID != 8 && compID != 16) {
1349 /*
1350 * Unsupported compression ID !
1351 */
1352 byteIndex = -1;
1353 } else {
1354 /*
1355 * Place compression code in first byte.
1356 */
1357 UDFCompressed[0] = (uint8_t)compID;
1358 (void) strncpy((caddr_t)&UDFCompressed[1],
1359 (caddr_t)unicode, numberOfChars);
1360 byteIndex = numberOfChars + 1;
1361 }
1362 return (byteIndex);
1363 }
1364
1365
1366 static int32_t
ud_convert2utf8(uint8_t * ibuf,uint8_t * obuf,int32_t length)1367 ud_convert2utf8(uint8_t *ibuf, uint8_t *obuf, int32_t length)
1368 {
1369 int i, size;
1370 uint16_t *buf;
1371
1372 /* LINTED */
1373 buf = (uint16_t *)obuf;
1374
1375 size = UncompressUnicode(length, ibuf, buf);
1376
1377 size = UdfTxName(buf, size);
1378
1379 for (i = 0; i < size; i++) {
1380 obuf[i] = (uint8_t)buf[i];
1381 }
1382 obuf[i] = '\0';
1383
1384 return (size);
1385 }
1386
1387 static int32_t
ud_convert2utf16(uint8_t * ibuf,uint8_t * obuf,int32_t length)1388 ud_convert2utf16(uint8_t *ibuf, uint8_t *obuf, int32_t length)
1389 {
1390 int32_t comp_len;
1391 uint16_t *ptr;
1392
1393 /* LINTED */
1394 ptr = (uint16_t *)ibuf;
1395 comp_len = ud_compressunicode(length, 8, ptr, obuf);
1396
1397 return (comp_len);
1398 }
1399
1400 /*
1401 * Assumption code set is zero in udfs
1402 */
1403 void
ud_convert2local(int8_t * ibuf,int8_t * obuf,int32_t length)1404 ud_convert2local(int8_t *ibuf, int8_t *obuf, int32_t length)
1405 {
1406 wchar_t buf4c[128];
1407 int32_t i, comp, index;
1408
1409 /*
1410 * Special uncompress code
1411 * written to accomodate solaris wchar_t
1412 */
1413 comp = ibuf[0];
1414 for (i = 0, index = 1; i < length; i++) {
1415 if (comp == 16) {
1416 buf4c[i] = ibuf[index++] << 8;
1417 } else {
1418 buf4c[i] = 0;
1419 }
1420 if (index < length) {
1421 buf4c[i] |= ibuf[index++];
1422 }
1423 }
1424 (void) wcstombs((char *)obuf, buf4c, 128);
1425 }
1426
1427
1428 /* ------------ Routines to print basic structures Part 1 ---------------- */
1429
1430
1431
1432 void
print_charspec(FILE * fout,char * name,struct charspec * cspec)1433 print_charspec(FILE *fout, char *name, struct charspec *cspec)
1434 {
1435 int i = 0;
1436
1437 (void) fprintf(fout,
1438 "%s : %x - \"", name, cspec->cs_type);
1439 for (i = 0; i < 63; i++) {
1440 (void) fprintf(fout,
1441 "%c", cspec->cs_info[i]);
1442 }
1443 (void) fprintf(fout, "\n");
1444 }
1445
1446 /* ARGSUSED */
1447 void
print_dstring(FILE * fout,char * name,uint16_t cset,char * bufc,uint8_t length)1448 print_dstring(FILE *fout, char *name, uint16_t cset, char *bufc, uint8_t length)
1449 {
1450 int8_t bufmb[1024];
1451
1452 ud_convert2local(bufc, bufmb, length);
1453
1454 (void) fprintf(fout,
1455 "%s %s\n", name, bufmb);
1456 }
1457
1458 void
set_dstring(dstring_t * dp,char * cp,int32_t len)1459 set_dstring(dstring_t *dp, char *cp, int32_t len)
1460 {
1461 int32_t length;
1462
1463 bzero(dp, len);
1464 length = strlen(cp);
1465 if (length > len - 1) {
1466 length = len - 1;
1467 }
1468 (void) strncpy(dp, cp, length);
1469 dp[len - 1] = length;
1470 }
1471
1472 void
print_tstamp(FILE * fout,char * name,tstamp_t * ts)1473 print_tstamp(FILE *fout, char *name, tstamp_t *ts)
1474 {
1475 (void) fprintf(fout, "%s tz : %d yr : %d mo : %d da : %d "
1476 "Time : %d : %d : %d : %d : %d : %d\n", name,
1477 SWAP_16(ts->ts_tzone), SWAP_16(ts->ts_year), ts->ts_month,
1478 ts->ts_day, ts->ts_hour, ts->ts_min, ts->ts_sec, ts->ts_csec,
1479 ts->ts_husec, ts->ts_usec);
1480 }
1481
1482
1483
1484 void
make_regid(ud_handle_t h,struct regid * reg,char * id,int32_t type)1485 make_regid(ud_handle_t h, struct regid *reg, char *id, int32_t type)
1486 {
1487 reg->reg_flags = 0;
1488 (void) strncpy(reg->reg_id, id, 23);
1489
1490 if (type == REG_DOM_ID) {
1491 struct dom_id_suffix *dis;
1492
1493 /* LINTED */
1494 dis = (struct dom_id_suffix *)reg->reg_ids;
1495 dis->dis_udf_revison = SWAP_16(h->udfs.ma_write);
1496 dis->dis_domain_flags = 0;
1497
1498 } else if (type == REG_UDF_ID) {
1499 struct udf_id_suffix *uis;
1500
1501 /* LINTED */
1502 uis = (struct udf_id_suffix *)reg->reg_ids;
1503 uis->uis_udf_revision = SWAP_16(h->udfs.ma_write);
1504 uis->uis_os_class = OS_CLASS_UNIX;
1505 uis->uis_os_identifier = OS_IDENTIFIER_SOLARIS;
1506 } else if (type == REG_UDF_II) {
1507 struct impl_id_suffix *iis;
1508
1509 iis = (struct impl_id_suffix *)reg->reg_ids;
1510 iis->iis_os_class = OS_CLASS_UNIX;
1511 iis->iis_os_identifier = OS_IDENTIFIER_SOLARIS;
1512 }
1513 }
1514
1515 void
print_regid(FILE * fout,char * name,struct regid * reg,int32_t type)1516 print_regid(FILE *fout, char *name, struct regid *reg, int32_t type)
1517 {
1518 (void) fprintf(fout, "%s : 0x%x : \"%s\" :",
1519 name, reg->reg_flags, reg->reg_id);
1520
1521 if (type == REG_DOM_ID) {
1522 struct dom_id_suffix *dis;
1523
1524 /* LINTED */
1525 dis = (struct dom_id_suffix *)reg->reg_ids;
1526 (void) fprintf(fout, " 0x%x : %s : %s\n",
1527 SWAP_16(dis->dis_udf_revison),
1528 (dis->dis_domain_flags & PROTECT_SOFT_WRITE) ?
1529 "HW Protect" : "No HW Write Protect",
1530 (dis->dis_domain_flags & PROTECT_HARD_WRITE) ?
1531 "SW Protect" : "No SW Protect");
1532 } else if (type == REG_UDF_ID) {
1533 struct udf_id_suffix *uis;
1534
1535 /* LINTED */
1536 uis = (struct udf_id_suffix *)reg->reg_ids;
1537 (void) fprintf(fout,
1538 " 0x%x : OS Class 0x%x : OS Identifier 0x%x\n",
1539 SWAP_16(uis->uis_udf_revision),
1540 uis->uis_os_class, uis->uis_os_identifier);
1541 } else {
1542 struct impl_id_suffix *iis;
1543
1544 iis = (struct impl_id_suffix *)reg->reg_ids;
1545 (void) fprintf(fout,
1546 " OS Class 0x%x : OS Identifier 0x%x\n",
1547 iis->iis_os_class, iis->iis_os_identifier);
1548 }
1549 }
1550
1551 #ifdef OLD
1552 void
print_regid(FILE * fout,char * name,struct regid * reg)1553 print_regid(FILE *fout, char *name, struct regid *reg)
1554 {
1555 (void) fprintf(fout, "%s : 0x%x : \"%s\" :",
1556 name, reg->reg_flags, reg->reg_id);
1557
1558 if (strncmp(reg->reg_id, "*OSTA UDF Compliant", 19) == 0) {
1559 (void) fprintf(fout, " 0x%x : %s : %s\n",
1560 reg->reg_ids[0] | (reg->reg_ids[1] << 8),
1561 (reg->reg_ids[2] & 1) ?
1562 "HW Protect" : "No HW Write Protect",
1563 (reg->reg_ids[2] & 2) ?
1564 "SW Protect" : "No SW Protect");
1565 } else if ((strncmp(reg->reg_id, "*UDF Virtual Partition", 22) == 0) ||
1566 (strncmp(reg->reg_id, "*UDF Sparable Partition", 23) == 0) ||
1567 (strncmp(reg->reg_id, "*UDF Virtual Alloc Tbl", 22) == 0) ||
1568 (strncmp(reg->reg_id, "*UDF Sparing Table", 18) == 0)) {
1569 (void) fprintf(fout,
1570 " 0x%x : OS Class 0x%x : OS Identifier 0x%x\n",
1571 reg->reg_ids[0] | (reg->reg_ids[1] << 8),
1572 reg->reg_ids[2], reg->reg_ids[3]);
1573 } else {
1574 (void) fprintf(fout,
1575 " OS Class 0x%x : OS Identifier 0x%x\n",
1576 reg->reg_ids[0], reg->reg_ids[1]);
1577 }
1578 }
1579 #endif
1580
1581
1582 /* ------------ Routines to print basic structures Part 2 ---------------- */
1583 /*
1584 * Part 2
1585 * This part is OS specific and is currently
1586 * not supported
1587 */
1588
1589 /* ------------ Routines to print basic structures Part 3 ---------------- */
1590
1591 void
print_ext_ad(FILE * fout,char * name,struct extent_ad * ead)1592 print_ext_ad(FILE *fout, char *name, struct extent_ad *ead)
1593 {
1594 (void) fprintf(fout,
1595 "%s EAD Len %x Loc %x\n",
1596 name, SWAP_32(ead->ext_len), SWAP_32(ead->ext_loc));
1597 }
1598
1599 void
print_tag(FILE * fout,struct tag * tag)1600 print_tag(FILE *fout, struct tag *tag)
1601 {
1602 (void) fprintf(fout,
1603 "tag_id : %x ver : %x cksum : %x "
1604 "sno : %x crc : %x crc_len : %x loc : %x\n",
1605 SWAP_16(tag->tag_id), SWAP_16(tag->tag_desc_ver),
1606 tag->tag_cksum, SWAP_16(tag->tag_sno),
1607 SWAP_16(tag->tag_crc), SWAP_16(tag->tag_crc_len),
1608 SWAP_32(tag->tag_loc));
1609 }
1610
1611
1612 void
print_pvd(FILE * fout,struct pri_vol_desc * pvd)1613 print_pvd(FILE *fout, struct pri_vol_desc *pvd)
1614 {
1615 (void) fprintf(fout,
1616 "\n\t\t\tPrimary Volume Descriptor\n");
1617 print_tag(fout, &pvd->pvd_tag);
1618 (void) fprintf(fout, "vdsn : %x vdn : %x\n",
1619 SWAP_32(pvd->pvd_vdsn), SWAP_32(pvd->pvd_pvdn));
1620 print_dstring(fout, "volid : ", pvd->pvd_desc_cs.cs_type,
1621 pvd->pvd_vol_id, 32);
1622 (void) fprintf(fout,
1623 "vsn : %x mvsn : %x il : %x mil :"
1624 " %x csl : %x mcsl %x\n",
1625 SWAP_16(pvd->pvd_vsn), SWAP_16(pvd->pvd_mvsn),
1626 SWAP_16(pvd->pvd_il), SWAP_16(pvd->pvd_mil),
1627 SWAP_32(pvd->pvd_csl), SWAP_32(pvd->pvd_mcsl));
1628 print_dstring(fout, "vsid :", pvd->pvd_desc_cs.cs_type,
1629 pvd->pvd_vsi, 128);
1630 print_charspec(fout, "desc_cs", &pvd->pvd_desc_cs);
1631 print_charspec(fout, "exp_cs", &pvd->pvd_exp_cs);
1632 print_ext_ad(fout, "val ", &pvd->pvd_vol_abs);
1633 print_ext_ad(fout, "vcnl ", &pvd->pvd_vcn);
1634 print_regid(fout, "ai", &pvd->pvd_appl_id, REG_UDF_II);
1635 print_regid(fout, "ii", &pvd->pvd_ii, REG_UDF_II);
1636 (void) fprintf(fout, "pvdsl : %x flags : %x\n",
1637 SWAP_32(pvd->pvd_pvdsl),
1638 SWAP_16(pvd->pvd_flags));
1639 }
1640
1641 void
print_avd(FILE * fout,struct anch_vol_desc_ptr * avdp)1642 print_avd(FILE *fout, struct anch_vol_desc_ptr *avdp)
1643 {
1644 (void) fprintf(fout,
1645 "\n\t\t\tAnchor Volume Descriptor\n");
1646 print_tag(fout, &avdp->avd_tag);
1647 print_ext_ad(fout, "Main Volume Descriptor Sequence : ",
1648 &avdp->avd_main_vdse);
1649 print_ext_ad(fout, "Reserve Volume Descriptor Sequence : ",
1650 &avdp->avd_res_vdse);
1651 }
1652
1653 void
print_vdp(FILE * fout,struct vol_desc_ptr * vdp)1654 print_vdp(FILE *fout, struct vol_desc_ptr *vdp)
1655 {
1656 (void) fprintf(fout,
1657 "\n\t\t\tVolume Descriptor Pointer\n");
1658 print_tag(fout, &vdp->vdp_tag);
1659 (void) fprintf(fout, "vdsn : %x ",
1660 SWAP_32(vdp->vdp_vdsn));
1661 print_ext_ad(fout, "vdse ", &vdp->vdp_nvdse);
1662 }
1663
1664 void
print_iuvd(FILE * fout,struct iuvd_desc * iuvd)1665 print_iuvd(FILE *fout, struct iuvd_desc *iuvd)
1666 {
1667 (void) fprintf(fout,
1668 "\n\t\t\tImplementation Use Volume Descriptor\n");
1669 print_tag(fout, &iuvd->iuvd_tag);
1670 (void) fprintf(fout,
1671 "vdsn : %x ", SWAP_32(iuvd->iuvd_vdsn));
1672 print_regid(fout, "Impl Id : ", &iuvd->iuvd_ii, REG_UDF_ID);
1673 print_charspec(fout, "cset ", &iuvd->iuvd_cset);
1674 print_dstring(fout, "lvi : ", iuvd->iuvd_cset.cs_type,
1675 iuvd->iuvd_lvi, 128);
1676 print_dstring(fout, "ifo1 : ", iuvd->iuvd_cset.cs_type,
1677 iuvd->iuvd_ifo1, 36);
1678 print_dstring(fout, "ifo2 : ", iuvd->iuvd_cset.cs_type,
1679 iuvd->iuvd_ifo2, 36);
1680 print_dstring(fout, "ifo3 : ", iuvd->iuvd_cset.cs_type,
1681 iuvd->iuvd_ifo3, 36);
1682
1683 print_regid(fout, "iid ", &iuvd->iuvd_iid, REG_UDF_II);
1684 }
1685
1686 void
print_part(FILE * fout,struct part_desc * pd)1687 print_part(FILE *fout, struct part_desc *pd)
1688 {
1689 (void) fprintf(fout,
1690 "\n\t\t\tPartition Descriptor\n");
1691 print_tag(fout, &pd->pd_tag);
1692 (void) fprintf(fout,
1693 "vdsn : %x flags : %x num : %x ",
1694 SWAP_32(pd->pd_vdsn),
1695 SWAP_16(pd->pd_pflags),
1696 SWAP_16(pd->pd_pnum));
1697 print_regid(fout, "contents ", &pd->pd_pcontents, REG_UDF_II);
1698 /* LINTED */
1699 print_phdr(fout, (struct phdr_desc *)(&pd->pd_pc_use));
1700 (void) fprintf(fout,
1701 "acc : %x start : %x length : %x ",
1702 SWAP_32(pd->pd_acc_type),
1703 SWAP_32(pd->pd_part_start),
1704 SWAP_32(pd->pd_part_length));
1705 print_regid(fout, "Impl Id : ", &pd->pd_ii, REG_UDF_II);
1706 }
1707
1708 void
print_lvd(FILE * fout,struct log_vol_desc * lvd)1709 print_lvd(FILE *fout, struct log_vol_desc *lvd)
1710 {
1711 (void) fprintf(fout,
1712 "\n\t\t\tLogical Volume Descriptor\n");
1713 print_tag(fout, &lvd->lvd_tag);
1714 (void) fprintf(fout,
1715 "vdsn : %x ", SWAP_32(lvd->lvd_vdsn));
1716 print_charspec(fout, "Desc Char Set ", &lvd->lvd_desc_cs);
1717 print_dstring(fout, "lvid : ", lvd->lvd_desc_cs.cs_type,
1718 lvd->lvd_lvid, 28);
1719 (void) fprintf(fout,
1720 "lbsize : %x ",
1721 SWAP_32(lvd->lvd_log_bsize));
1722 print_regid(fout, "Dom Id", &lvd->lvd_dom_id, REG_DOM_ID);
1723 print_long_ad(fout, "lvcu", &lvd->lvd_lvcu);
1724 (void) fprintf(fout,
1725 "mtlen : %x nmaps : %x ",
1726 SWAP_32(lvd->lvd_mtbl_len),
1727 SWAP_32(lvd->lvd_num_pmaps));
1728 print_regid(fout, "Impl Id : ", &lvd->lvd_ii, REG_UDF_II);
1729 print_ext_ad(fout, "Int Seq", &lvd->lvd_int_seq_ext);
1730 print_pmaps(fout, lvd->lvd_pmaps, SWAP_32(lvd->lvd_num_pmaps));
1731 }
1732
1733 void
print_usd(FILE * fout,struct unall_spc_desc * ua)1734 print_usd(FILE *fout, struct unall_spc_desc *ua)
1735 {
1736 int32_t i, count;
1737
1738 (void) fprintf(fout,
1739 "\n\t\t\tUnallocated Space Descriptor\n");
1740 print_tag(fout, &ua->ua_tag);
1741 count = SWAP_32(ua->ua_nad);
1742 (void) fprintf(fout,
1743 "vdsn : %x nad : %x\n",
1744 SWAP_32(ua->ua_vdsn), count);
1745 for (i = 0; i < count; i++) {
1746 (void) fprintf(fout,
1747 "loc : %x len : %x\n",
1748 SWAP_32(ua->ua_al_dsc[i * 2]),
1749 SWAP_32(ua->ua_al_dsc[i * 2 + 1]));
1750 }
1751 }
1752
1753 void
print_lvid(FILE * fout,struct log_vol_int_desc * lvid)1754 print_lvid(FILE *fout, struct log_vol_int_desc *lvid)
1755 {
1756 int32_t i, count;
1757 caddr_t addr;
1758 struct lvid_iu *liu;
1759
1760 (void) fprintf(fout,
1761 "\n\t\t\tLogical Volume Integrity Descriptor\n");
1762 print_tag(fout, &lvid->lvid_tag);
1763 print_tstamp(fout, "Rec TM ", &lvid->lvid_tstamp);
1764 if (SWAP_32(lvid->lvid_int_type) == 0) {
1765 (void) fprintf(fout,
1766 "int_typ : Open\n");
1767 } else if (SWAP_32(lvid->lvid_int_type) == 1) {
1768 (void) fprintf(fout, "int_typ : Closed\n");
1769 } else {
1770 (void) fprintf(fout, "int_typ : Unknown\n");
1771 }
1772 print_ext_ad(fout, "Nie ", &lvid->lvid_nie);
1773 count = SWAP_32(lvid->lvid_npart);
1774 (void) fprintf(fout,
1775 "Uniq : %llx npart : %x liu : %x\n",
1776 SWAP_64(lvid->lvid_lvcu.lvhd_uniqid),
1777 count, SWAP_32(lvid->lvid_liu));
1778 for (i = 0; i < count; i++) {
1779 (void) fprintf(fout,
1780 "Part : %x Free : %x Size : %x\n",
1781 i, SWAP_32(lvid->lvid_fst[i]),
1782 SWAP_32(lvid->lvid_fst[count + i]));
1783 }
1784
1785 addr = (caddr_t)lvid->lvid_fst;
1786 /* LINTED */
1787 liu = (struct lvid_iu *)(addr + 2 * count * 4);
1788 print_regid(fout, "Impl Id :", &liu->lvidiu_regid, REG_UDF_II);
1789 (void) fprintf(fout,
1790 "nfiles : %x ndirs : %x miread : %x"
1791 " miwrite : %x mawrite : %x\n",
1792 SWAP_32(liu->lvidiu_nfiles), SWAP_32(liu->lvidiu_ndirs),
1793 SWAP_16(liu->lvidiu_mread), SWAP_16(liu->lvidiu_mwrite),
1794 SWAP_16(liu->lvidiu_maxwr));
1795 }
1796
1797
1798 /* ------------ Routines to print basic structures Part 4 ---------------- */
1799
1800 void
print_fsd(FILE * fout,ud_handle_t h,struct file_set_desc * fsd)1801 print_fsd(FILE *fout, ud_handle_t h, struct file_set_desc *fsd)
1802 {
1803 (void) fprintf(fout,
1804 "\n\t\t\tFile Set Descriptor\n");
1805
1806 print_tag(fout, &fsd->fsd_tag);
1807 print_tstamp(fout, "Rec TM ", &fsd->fsd_time);
1808 (void) fprintf(fout,
1809 "ilvl : %x milvl : %x csl : %x"
1810 " mcsl : %x fsn : %x fsdn : %x\n",
1811 SWAP_16(fsd->fsd_ilevel), SWAP_16(fsd->fsd_mi_level),
1812 SWAP_32(fsd->fsd_cs_list), SWAP_32(fsd->fsd_mcs_list),
1813 SWAP_32(fsd->fsd_fs_no), SWAP_32(fsd->fsd_fsd_no));
1814 print_charspec(fout, "ID CS ", &fsd->fsd_lvidcs);
1815 print_dstring(fout, "lvi : ", fsd->fsd_lvidcs.cs_type,
1816 fsd->fsd_lvid, 128);
1817 print_charspec(fout, "ID CS ", &fsd->fsd_fscs);
1818 print_dstring(fout, "fsi : ", fsd->fsd_lvidcs.cs_type,
1819 fsd->fsd_fsi, 32);
1820 print_dstring(fout, "cfi : ", fsd->fsd_lvidcs.cs_type,
1821 fsd->fsd_cfi, 32);
1822 print_dstring(fout, "afi : ", fsd->fsd_lvidcs.cs_type,
1823 fsd->fsd_afi, 32);
1824 print_long_ad(fout, "Ricb ", &fsd->fsd_root_icb);
1825 print_regid(fout, "DI ", &fsd->fsd_did, REG_DOM_ID);
1826 print_long_ad(fout, "Next Fsd ", &fsd->fsd_next);
1827 if (h->udfs.ecma_version == UD_ECMA_VER3) {
1828 print_long_ad(fout, "System Stream Directory ICB ",
1829 &fsd->fsd_next);
1830 }
1831 }
1832
1833 void
print_phdr(FILE * fout,struct phdr_desc * ph)1834 print_phdr(FILE *fout, struct phdr_desc *ph)
1835 {
1836 print_short_ad(fout, "ust ", &ph->phdr_ust);
1837 print_short_ad(fout, "usb ", &ph->phdr_usb);
1838 print_short_ad(fout, "int ", &ph->phdr_it);
1839 print_short_ad(fout, "fst ", &ph->phdr_fst);
1840 print_short_ad(fout, "fsh ", &ph->phdr_fsb);
1841 }
1842
1843 void
print_fid(FILE * fout,struct file_id * fid)1844 print_fid(FILE *fout, struct file_id *fid)
1845 {
1846 int32_t i;
1847 uint8_t *addr;
1848
1849 (void) fprintf(fout,
1850 "File Identifier Descriptor\n");
1851 print_tag(fout, &fid->fid_tag);
1852 (void) fprintf(fout, "fvn : %x fc : %x length : %x ",
1853 fid->fid_ver, fid->fid_flags, fid->fid_idlen);
1854 print_long_ad(fout, "ICB", &fid->fid_icb);
1855 addr = &fid->fid_spec[SWAP_16(fid->fid_iulen)];
1856 (void) fprintf(fout, "iulen : %x comp : %x name : ",
1857 SWAP_16(fid->fid_iulen), *addr);
1858 addr++;
1859 for (i = 0; i < fid->fid_idlen; i++) {
1860 (void) fprintf(fout, "%c", *addr++);
1861 }
1862 (void) fprintf(fout, "\n");
1863 }
1864
1865 void
print_aed(FILE * fout,struct alloc_ext_desc * aed)1866 print_aed(FILE *fout, struct alloc_ext_desc *aed)
1867 {
1868 (void) fprintf(fout,
1869 "Allocation Extent Descriptor\n");
1870 print_tag(fout, &aed->aed_tag);
1871 (void) fprintf(fout, "prev ael loc : %x laed : %x\n",
1872 SWAP_32(aed->aed_rev_ael), SWAP_32(aed->aed_len_aed));
1873 }
1874
1875 static char *ftype[] = {
1876 "NON", "USE", "PIE", "IE",
1877 "DIR", "REG", "BDEV", "CDEV",
1878 "EATT", "FIFO", "SOCK", "TERM",
1879 "SYML", "SDIR"
1880 };
1881
1882 void
print_icb_tag(FILE * fout,struct icb_tag * itag)1883 print_icb_tag(FILE *fout, struct icb_tag *itag)
1884 {
1885 (void) fprintf(fout,
1886 "prnde : %x strat : %x param : %x max_ent %x\n",
1887 SWAP_32(itag->itag_prnde), SWAP_16(itag->itag_strategy),
1888 SWAP_16(itag->itag_param), SWAP_16(itag->itag_max_ent));
1889 (void) fprintf(fout,
1890 "ftype : %s prn : %x loc : %x flags : %x\n",
1891 (itag->itag_ftype >= 14) ? ftype[0] : ftype[itag->itag_ftype],
1892 SWAP_16(itag->itag_lb_prn),
1893 SWAP_32(itag->itag_lb_loc), SWAP_16(itag->itag_flags));
1894 }
1895
1896
1897 void
print_ie(FILE * fout,struct indirect_entry * ie)1898 print_ie(FILE *fout, struct indirect_entry *ie)
1899 {
1900 (void) fprintf(fout,
1901 "Indirect Entry\n");
1902 print_tag(fout, &ie->ie_tag);
1903 print_icb_tag(fout, &ie->ie_icb_tag);
1904 print_long_ad(fout, "ICB", &ie->ie_indirecticb);
1905 }
1906
1907 void
print_td(FILE * fout,struct term_desc * td)1908 print_td(FILE *fout, struct term_desc *td)
1909 {
1910 (void) fprintf(fout,
1911 "Terminating Descriptor\n");
1912 print_tag(fout, &td->td_tag);
1913 }
1914
1915 void
print_fe(FILE * fout,struct file_entry * fe)1916 print_fe(FILE *fout, struct file_entry *fe)
1917 {
1918 (void) fprintf(fout,
1919 "File Entry\n");
1920 print_tag(fout, &fe->fe_tag);
1921 print_icb_tag(fout, &fe->fe_icb_tag);
1922 (void) fprintf(fout,
1923 "uid : %x gid : %x perms : %x nlnk : %x\n",
1924 SWAP_32(fe->fe_uid), SWAP_32(fe->fe_gid),
1925 SWAP_32(fe->fe_perms), SWAP_16(fe->fe_lcount));
1926 (void) fprintf(fout,
1927 "rec_for : %x rec_dis : %x rec_len : %x "
1928 "sz : %llx blks : %llx\n",
1929 fe->fe_rec_for, fe->fe_rec_dis, SWAP_32(fe->fe_rec_len),
1930 SWAP_64(fe->fe_info_len), SWAP_64(fe->fe_lbr));
1931 print_tstamp(fout, "ctime ", &fe->fe_acc_time);
1932 print_tstamp(fout, "mtime ", &fe->fe_mod_time);
1933 print_tstamp(fout, "atime ", &fe->fe_attr_time);
1934 (void) fprintf(fout,
1935 "ckpoint : %x ", SWAP_32(fe->fe_ckpoint));
1936 print_long_ad(fout, "ICB", &fe->fe_ea_icb);
1937 print_regid(fout, "impl", &fe->fe_impl_id, REG_UDF_II);
1938 (void) fprintf(fout,
1939 "uniq_id : %llx len_ear : %x len_adesc %x\n",
1940 SWAP_64(fe->fe_uniq_id), SWAP_32(fe->fe_len_ear),
1941 SWAP_32(fe->fe_len_adesc));
1942 }
1943
1944 void
print_pmaps(FILE * fout,uint8_t * addr,int32_t count)1945 print_pmaps(FILE *fout, uint8_t *addr, int32_t count)
1946 {
1947 struct pmap_hdr *hdr;
1948 struct pmap_typ1 *map1;
1949 struct pmap_typ2 *map2;
1950
1951 while (count--) {
1952 hdr = (struct pmap_hdr *)addr;
1953 switch (hdr->maph_type) {
1954 case 1 :
1955 /* LINTED */
1956 map1 = (struct pmap_typ1 *)hdr;
1957 (void) fprintf(fout, "Map type 1 ");
1958 (void) fprintf(fout, "VSN %x prn %x\n",
1959 SWAP_16(map1->map1_vsn),
1960 SWAP_16(map1->map1_pn));
1961 break;
1962 case 2 :
1963 /* LINTED */
1964 map2 = (struct pmap_typ2 *)hdr;
1965 (void) fprintf(fout, "Map type 2 ");
1966 (void) fprintf(fout, "VSN %x prn %x\n",
1967 SWAP_16(map2->map2_vsn),
1968 SWAP_16(map2->map2_pn));
1969 print_regid(fout, "Partition Type Identifier",
1970 &map2->map2_pti, REG_UDF_ID);
1971 break;
1972 default :
1973 (void) fprintf(fout, "unknown map type\n");
1974 }
1975 addr += hdr->maph_length;
1976 }
1977 }
1978
1979
1980
1981 void
print_short_ad(FILE * fout,char * name,struct short_ad * sad)1982 print_short_ad(FILE *fout, char *name, struct short_ad *sad)
1983 {
1984 (void) fprintf(fout,
1985 "%s loc : %x len : %x\n", name,
1986 SWAP_32(sad->sad_ext_loc), SWAP_32(sad->sad_ext_len));
1987 }
1988
1989 void
print_long_ad(FILE * fout,char * name,struct long_ad * lad)1990 print_long_ad(FILE *fout, char *name, struct long_ad *lad)
1991 {
1992 (void) fprintf(fout,
1993 "%s prn : %x loc : %x len : %x\n", name,
1994 SWAP_16(lad->lad_ext_prn), SWAP_32(lad->lad_ext_loc),
1995 SWAP_32(lad->lad_ext_len));
1996 }
1997