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