1 /* $NetBSD: udf_core.c,v 1.13 2022/05/28 21:14:56 andvar Exp $ */ 2 3 /* 4 * Copyright (c) 2006, 2008, 2021, 2022 Reinoud Zandijk 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 */ 28 #if HAVE_NBTOOL_CONFIG_H 29 #include "nbtool_config.h" 30 #endif 31 32 #include <sys/cdefs.h> 33 __RCSID("$NetBSD: udf_core.c,v 1.13 2022/05/28 21:14:56 andvar Exp $"); 34 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <stddef.h> 38 #include <string.h> 39 #include <strings.h> 40 #include <unistd.h> 41 #include <errno.h> 42 #include <time.h> 43 #include <assert.h> 44 #include <err.h> 45 #include <fcntl.h> 46 #include <util.h> 47 #include <sys/types.h> 48 #include <sys/param.h> 49 #include <sys/ioctl.h> 50 #include <sys/queue.h> 51 #include "newfs_udf.h" 52 #include "unicode.h" 53 #include "udf_core.h" 54 55 56 /* disk partition support */ 57 #if !HAVE_NBTOOL_CONFIG_H 58 #include "../fsck/partutil.h" 59 #include "../fsck/partutil.c" 60 #endif 61 62 63 /* queue for temporary storage of sectors to be written out */ 64 struct wrpacket { 65 uint64_t start_sectornr; 66 uint8_t *packet_data; 67 uint64_t present; 68 TAILQ_ENTRY(wrpacket) next; 69 }; 70 71 72 /* global variables describing disc and format requests */ 73 struct udf_create_context context; 74 struct udf_disclayout layout; 75 76 77 int dev_fd_rdonly; /* device: open readonly! */ 78 int dev_fd; /* device: file descriptor */ 79 struct stat dev_fd_stat; /* device: last stat info */ 80 char *dev_name; /* device: name */ 81 int emul_mmc_profile; /* for files */ 82 int emul_packetsize; /* for discs and files */ 83 int emul_sectorsize; /* for files */ 84 off_t emul_size; /* for files */ 85 86 struct mmc_discinfo mmc_discinfo; /* device: disc info */ 87 union dscrptr *terminator_dscr; /* generic terminator descriptor*/ 88 89 90 /* write queue and track blocking skew */ 91 TAILQ_HEAD(wrpacket_list, wrpacket) write_queue; 92 int write_queuelen; 93 int write_queue_suspend; 94 uint32_t wrtrack_skew; /* offset for writing sector0 */ 95 96 static void udf_init_writequeue(int write_strategy); 97 static int udf_writeout_writequeue(bool complete); 98 99 /* 100 * NOTE that there is some overlap between this code and the udf kernel fs. 101 * This is intentionally though it might better be factored out one day. 102 */ 103 104 void 105 udf_init_create_context(void) 106 { 107 /* clear */ 108 memset(&context, 0, sizeof(struct udf_create_context)); 109 110 /* fill with defaults currently known */ 111 context.dscrver = 3; 112 context.min_udf = 0x0102; 113 context.max_udf = 0x0250; 114 context.serialnum = 1; /* default */ 115 116 context.gmtoff = 0; 117 context.meta_perc = UDF_META_PERC; 118 context.check_surface = 0; 119 context.create_new_session = 0; 120 121 context.sector_size = 512; /* minimum for UDF */ 122 context.media_accesstype = UDF_ACCESSTYPE_NOT_SPECIFIED; 123 context.format_flags = FORMAT_INVALID; 124 context.write_strategy = UDF_WRITE_PACKET; 125 126 context.logvol_name = NULL; 127 context.primary_name = NULL; 128 context.volset_name = NULL; 129 context.fileset_name = NULL; 130 131 /* most basic identification */ 132 context.app_name = "*NetBSD"; 133 context.app_version_main = 0; 134 context.app_version_sub = 0; 135 context.impl_name = "*NetBSD"; 136 137 context.vds_seq = 0; /* first one starts with zero */ 138 139 /* Minimum value of 16 : UDF 3.2.1.1, 3.3.3.4. */ 140 context.unique_id = 0x10; 141 142 context.num_files = 0; 143 context.num_directories = 0; 144 145 context.data_part = 0; 146 context.metadata_part = 0; 147 } 148 149 150 /* version can be specified as 0xabc or a.bc */ 151 static int 152 parse_udfversion(const char *pos, uint32_t *version) { 153 int hex = 0; 154 char c1, c2, c3, c4; 155 156 *version = 0; 157 if (*pos == '0') { 158 pos++; 159 /* expect hex format */ 160 hex = 1; 161 if (*pos++ != 'x') 162 return 1; 163 } 164 165 c1 = *pos++; 166 if (c1 < '0' || c1 > '9') 167 return 1; 168 c1 -= '0'; 169 170 c2 = *pos++; 171 if (!hex) { 172 if (c2 != '.') 173 return 1; 174 c2 = *pos++; 175 } 176 if (c2 < '0' || c2 > '9') 177 return 1; 178 c2 -= '0'; 179 180 c3 = *pos++; 181 if (c3 < '0' || c3 > '9') 182 return 1; 183 c3 -= '0'; 184 185 c4 = *pos++; 186 if (c4 != 0) 187 return 1; 188 189 *version = c1 * 0x100 + c2 * 0x10 + c3; 190 return 0; 191 } 192 193 194 /* 195 * Parse a given string for an udf version. 196 * May exit. 197 */ 198 int 199 a_udf_version(const char *s, const char *id_type) 200 { 201 uint32_t version; 202 203 if (parse_udfversion(s, &version)) 204 errx(1, "unknown %s version %s; specify as hex or float", id_type, s); 205 switch (version) { 206 case 0x102: 207 case 0x150: 208 case 0x200: 209 case 0x201: 210 case 0x250: 211 break; 212 case 0x260: 213 /* we don't support this one */ 214 errx(1, "UDF version 0x260 is not supported"); 215 break; 216 default: 217 errx(1, "unknown %s version %s, choose from " 218 "0x102, 0x150, 0x200, 0x201, 0x250", 219 id_type, s); 220 } 221 return version; 222 } 223 224 225 static uint32_t 226 udf_space_bitmap_len(uint32_t part_size) 227 { 228 return sizeof(struct space_bitmap_desc)-1 + 229 part_size/8; 230 } 231 232 233 uint32_t 234 udf_bytes_to_sectors(uint64_t bytes) 235 { 236 uint32_t sector_size = context.sector_size; 237 return (bytes + sector_size -1) / sector_size; 238 } 239 240 241 void 242 udf_dump_layout(void) { 243 #ifdef DEBUG 244 int format_flags = context.format_flags; 245 int sector_size = context.sector_size; 246 247 printf("Summary so far\n"); 248 printf("\tiso9660_vrs\t\t%d\n", layout.iso9660_vrs); 249 printf("\tanchor0\t\t\t%d\n", layout.anchors[0]); 250 printf("\tanchor1\t\t\t%d\n", layout.anchors[1]); 251 printf("\tanchor2\t\t\t%d\n", layout.anchors[2]); 252 printf("\tvds1_size\t\t%d\n", layout.vds1_size); 253 printf("\tvds2_size\t\t%d\n", layout.vds2_size); 254 printf("\tvds1\t\t\t%d\n", layout.vds1); 255 printf("\tvds2\t\t\t%d\n", layout.vds2); 256 printf("\tlvis_size\t\t%d\n", layout.lvis_size); 257 printf("\tlvis\t\t\t%d\n", layout.lvis); 258 if (format_flags & FORMAT_SPAREABLE) { 259 printf("\tspareable size\t\t%d\n", layout.spareable_area_size); 260 printf("\tspareable\t\t%d\n", layout.spareable_area); 261 } 262 printf("\tpartition start lba\t%d\n", layout.part_start_lba); 263 printf("\tpartition size\t\t%ld KiB, %ld MiB\n", 264 ((uint64_t) layout.part_size_lba * sector_size) / 1024, 265 ((uint64_t) layout.part_size_lba * sector_size) / (1024*1024)); 266 if ((format_flags & FORMAT_SEQUENTIAL) == 0) { 267 printf("\tpart bitmap start\t%d\n", layout.unalloc_space); 268 printf("\t\tfor %d lba\n", layout.alloc_bitmap_dscr_size); 269 } 270 if (format_flags & FORMAT_META) { 271 printf("\tmeta blockingnr\t\t%d\n", layout.meta_blockingnr); 272 printf("\tmeta alignment\t\t%d\n", layout.meta_alignment); 273 printf("\tmeta size\t\t%ld KiB, %ld MiB\n", 274 ((uint64_t) layout.meta_part_size_lba * sector_size) / 1024, 275 ((uint64_t) layout.meta_part_size_lba * sector_size) / (1024*1024)); 276 printf("\tmeta file\t\t%d\n", layout.meta_file); 277 printf("\tmeta mirror\t\t%d\n", layout.meta_mirror); 278 printf("\tmeta bitmap\t\t%d\n", layout.meta_bitmap); 279 printf("\tmeta bitmap start\t%d\n", layout.meta_bitmap_space); 280 printf("\t\tfor %d lba\n", layout.meta_bitmap_dscr_size); 281 printf("\tmeta space start\t%d\n", layout.meta_part_start_lba); 282 printf("\t\tfor %d lba\n", layout.meta_part_size_lba); 283 } 284 printf("\n"); 285 #endif 286 } 287 288 289 int 290 udf_calculate_disc_layout(int min_udf, 291 uint32_t first_lba, uint32_t last_lba, 292 uint32_t sector_size, uint32_t blockingnr) 293 { 294 uint64_t kbsize, bytes; 295 uint32_t spareable_blockingnr; 296 uint32_t align_blockingnr; 297 uint32_t pos, mpos; 298 int format_flags = context.format_flags; 299 300 /* clear */ 301 memset(&layout, 0, sizeof(layout)); 302 303 /* fill with parameters */ 304 layout.wrtrack_skew = wrtrack_skew; 305 layout.first_lba = first_lba; 306 layout.last_lba = last_lba; 307 layout.blockingnr = blockingnr; 308 layout.spareable_blocks = udf_spareable_blocks(); 309 310 /* start disc layouting */ 311 312 /* 313 * location of iso9660 vrs is defined as first sector AFTER 32kb, 314 * minimum `sector size' 2048 315 */ 316 layout.iso9660_vrs = ((32*1024 + sector_size - 1) / sector_size) 317 + first_lba; 318 319 /* anchor starts at specified offset in sectors */ 320 layout.anchors[0] = first_lba + 256; 321 if (format_flags & FORMAT_TRACK512) 322 layout.anchors[0] = first_lba + 512; 323 layout.anchors[1] = last_lba - 256; 324 layout.anchors[2] = last_lba; 325 326 /* update workable space */ 327 first_lba = layout.anchors[0] + blockingnr; 328 last_lba = layout.anchors[1] - 1; 329 330 /* XXX rest of anchor packet can be added to unallocated space descr */ 331 332 /* reserve space for VRS and VRS copy and associated tables */ 333 layout.vds1_size = MAX(16, blockingnr); /* UDF 2.2.3.1+2 */ 334 layout.vds1 = first_lba; 335 first_lba += layout.vds1_size; /* next packet */ 336 337 layout.vds2_size = layout.vds1_size; 338 if (format_flags & FORMAT_SEQUENTIAL) { 339 /* for sequential, append them ASAP */ 340 layout.vds2 = first_lba; 341 first_lba += layout.vds2_size; 342 } else { 343 layout.vds2 = layout.anchors[1] +1 - layout.vds2_size; 344 last_lba = layout.vds2 - 1; 345 } 346 347 /* 348 * Reserve space for logvol integrity sequence, at least 8192 bytes 349 * for overwritable and rewritable media UDF 2.2.4.6, ECMA 3/10.6.12. 350 */ 351 layout.lvis_size = MAX(8192.0/sector_size, 2 * blockingnr); 352 if (layout.lvis_size * sector_size < 8192) 353 layout.lvis_size++; 354 if (format_flags & FORMAT_VAT) 355 layout.lvis_size = 2; 356 if (format_flags & FORMAT_WORM) 357 layout.lvis_size = 64 * blockingnr; 358 359 /* TODO skip bad blocks in LVID sequence */ 360 layout.lvis = first_lba; 361 first_lba += layout.lvis_size; 362 363 /* initial guess of UDF partition size */ 364 layout.part_start_lba = first_lba; 365 layout.part_size_lba = last_lba - layout.part_start_lba; 366 367 /* all non sequential media needs an unallocated space bitmap */ 368 layout.alloc_bitmap_dscr_size = 0; 369 if ((format_flags & (FORMAT_SEQUENTIAL | FORMAT_READONLY)) == 0) { 370 bytes = udf_space_bitmap_len(layout.part_size_lba); 371 layout.alloc_bitmap_dscr_size = udf_bytes_to_sectors(bytes); 372 373 /* XXX freed space map when applicable */ 374 } 375 376 spareable_blockingnr = udf_spareable_blockingnr(); 377 align_blockingnr = blockingnr; 378 379 if (format_flags & (FORMAT_SPAREABLE | FORMAT_META)) 380 align_blockingnr = spareable_blockingnr; 381 382 layout.align_blockingnr = align_blockingnr; 383 layout.spareable_blockingnr = spareable_blockingnr; 384 385 /* 386 * Align partition LBA space to blocking granularity. Not strictly 387 * necessary for non spareables but safer for the VRS data since it is 388 * updated sporadically 389 */ 390 391 #ifdef DEBUG 392 printf("Lost %lu slack sectors at start\n", UDF_ROUNDUP( 393 first_lba, align_blockingnr) - 394 first_lba); 395 printf("Lost %lu slack sectors at end\n", 396 last_lba - UDF_ROUNDDOWN( 397 last_lba, align_blockingnr)); 398 #endif 399 400 first_lba = UDF_ROUNDUP(first_lba, align_blockingnr); 401 last_lba = UDF_ROUNDDOWN(last_lba, align_blockingnr); 402 403 if ((format_flags & FORMAT_SPAREABLE) == 0) 404 layout.spareable_blocks = 0; 405 406 if (format_flags & FORMAT_SPAREABLE) { 407 layout.spareable_area_size = 408 layout.spareable_blocks * spareable_blockingnr; 409 410 /* a sparing table descriptor is a whole blockingnr sectors */ 411 layout.sparing_table_dscr_lbas = spareable_blockingnr; 412 413 /* place the descriptors at the start and end of the area */ 414 layout.spt_1 = first_lba; 415 first_lba += layout.sparing_table_dscr_lbas; 416 417 layout.spt_2 = last_lba - layout.sparing_table_dscr_lbas; 418 last_lba -= layout.sparing_table_dscr_lbas; 419 420 /* allocate spareable section */ 421 layout.spareable_area = first_lba; 422 first_lba += layout.spareable_area_size; 423 } 424 425 /* update guess of UDF partition size */ 426 layout.part_start_lba = first_lba; 427 layout.part_size_lba = last_lba - layout.part_start_lba; 428 429 /* determine partition selection for data and metadata */ 430 context.data_part = 0; 431 context.metadata_part = context.data_part; 432 if ((format_flags & FORMAT_VAT) || (format_flags & FORMAT_META)) 433 context.metadata_part = context.data_part + 1; 434 context.fids_part = context.metadata_part; 435 if (format_flags & FORMAT_VAT) 436 context.fids_part = context.data_part; 437 438 /* 439 * Pick fixed logical space sector numbers for main FSD, rootdir and 440 * unallocated space. The reason for this pre-allocation is that they 441 * are referenced in the volume descriptor sequence and hence can't be 442 * allocated later. 443 */ 444 pos = 0; 445 layout.unalloc_space = pos; 446 pos += layout.alloc_bitmap_dscr_size; 447 448 /* claim metadata descriptors and partition space [UDF 2.2.10] */ 449 if (format_flags & FORMAT_META) { 450 /* note: all in backing partition space */ 451 layout.meta_file = pos++; 452 layout.meta_bitmap = 0xffffffff; 453 if (!(context.format_flags & FORMAT_READONLY)) 454 layout.meta_bitmap = pos++; 455 layout.meta_mirror = layout.part_size_lba-1; 456 layout.meta_alignment = MAX(blockingnr, spareable_blockingnr); 457 layout.meta_blockingnr = MAX(layout.meta_alignment, 32); 458 459 /* calculate our partition length and store in sectors */ 460 layout.meta_part_size_lba = layout.part_size_lba * 461 ((float) context.meta_perc / 100.0); 462 layout.meta_part_size_lba = MAX(layout.meta_part_size_lba, 32); 463 layout.meta_part_size_lba = 464 UDF_ROUNDDOWN(layout.meta_part_size_lba, layout.meta_blockingnr); 465 466 if (!(context.format_flags & FORMAT_READONLY)) { 467 /* metadata partition free space bitmap */ 468 bytes = udf_space_bitmap_len(layout.meta_part_size_lba); 469 layout.meta_bitmap_dscr_size = udf_bytes_to_sectors(bytes); 470 471 layout.meta_bitmap_space = pos; 472 pos += layout.meta_bitmap_dscr_size; 473 } 474 475 layout.meta_part_start_lba = UDF_ROUNDUP(pos, layout.meta_alignment); 476 pos = layout.meta_part_start_lba + layout.meta_part_size_lba; 477 } 478 479 if (context.metadata_part == context.data_part) { 480 mpos = pos; 481 layout.fsd = mpos; mpos += 1; 482 layout.rootdir = mpos; 483 pos = mpos; 484 } else { 485 mpos = 0; 486 layout.fsd = mpos; mpos += 1; 487 layout.rootdir = mpos; 488 } 489 490 /* pos and mpos now refer to the rootdir block */ 491 context.alloc_pos[context.data_part] = pos; 492 context.alloc_pos[context.metadata_part] = mpos; 493 494 udf_dump_layout(); 495 496 kbsize = (uint64_t) last_lba * sector_size; 497 printf("Total space on this medium approx. " 498 "%"PRIu64" KiB, %"PRIu64" MiB\n", 499 kbsize/1024, kbsize/(1024*1024)); 500 kbsize = (uint64_t)(layout.part_size_lba - layout.alloc_bitmap_dscr_size 501 - layout.meta_bitmap_dscr_size) * sector_size; 502 printf("Recordable free space on this volume approx. " 503 "%"PRIu64" KiB, %"PRIu64" MiB\n\n", 504 kbsize/1024, kbsize/(1024*1024)); 505 506 return 0; 507 } 508 509 510 /* 511 * Check if the blob starts with a good UDF tag. Tags are protected by a 512 * checksum over the header, except one byte at position 4 that is the 513 * checksum itself. 514 */ 515 int 516 udf_check_tag(void *blob) 517 { 518 struct desc_tag *tag = blob; 519 uint8_t *pos, sum, cnt; 520 521 /* check TAG header checksum */ 522 pos = (uint8_t *) tag; 523 sum = 0; 524 525 for(cnt = 0; cnt < 16; cnt++) { 526 if (cnt != 4) 527 sum += *pos; 528 pos++; 529 } 530 if (sum != tag->cksum) { 531 /* bad tag header checksum; this is not a valid tag */ 532 return EINVAL; 533 } 534 535 return 0; 536 } 537 538 539 /* 540 * check tag payload will check descriptor CRC as specified. 541 * If the descriptor is too long, it will return EIO otherwise EINVAL. 542 */ 543 int 544 udf_check_tag_payload(void *blob, uint32_t max_length) 545 { 546 struct desc_tag *tag = blob; 547 uint16_t crc, crc_len; 548 549 crc_len = udf_rw16(tag->desc_crc_len); 550 551 /* check payload CRC if applicable */ 552 if (crc_len == 0) 553 return 0; 554 555 if (crc_len > max_length) 556 return EIO; 557 558 crc = udf_cksum(((uint8_t *) tag) + UDF_DESC_TAG_LENGTH, crc_len); 559 if (crc != udf_rw16(tag->desc_crc)) { 560 /* bad payload CRC; this is a broken tag */ 561 return EINVAL; 562 } 563 564 return 0; 565 } 566 567 568 int 569 udf_check_tag_and_location(void *blob, uint32_t location) 570 { 571 struct desc_tag *tag = blob; 572 573 if (udf_check_tag(blob)) 574 return 1; 575 if (udf_rw32(tag->tag_loc) != location) 576 return 1; 577 return 0; 578 } 579 580 581 int 582 udf_validate_tag_sum(union dscrptr *dscr) 583 { 584 struct desc_tag *tag = &dscr->tag; 585 uint8_t *pos, sum, cnt; 586 587 /* calculate TAG header checksum */ 588 pos = (uint8_t *) tag; 589 sum = 0; 590 591 for (cnt = 0; cnt < 16; cnt++) { 592 if (cnt != 4) sum += *pos; 593 pos++; 594 }; 595 tag->cksum = sum; /* 8 bit */ 596 597 return 0; 598 } 599 600 601 /* assumes sector number of descriptor to be already present */ 602 int 603 udf_validate_tag_and_crc_sums(union dscrptr *dscr) 604 { 605 struct desc_tag *tag = &dscr->tag; 606 uint16_t crc; 607 608 /* check payload CRC if applicable */ 609 if (udf_rw16(tag->desc_crc_len) > 0) { 610 crc = udf_cksum(((uint8_t *) tag) + UDF_DESC_TAG_LENGTH, 611 udf_rw16(tag->desc_crc_len)); 612 tag->desc_crc = udf_rw16(crc); 613 }; 614 615 /* calculate TAG header checksum */ 616 return udf_validate_tag_sum(dscr); 617 } 618 619 620 void 621 udf_inittag(struct desc_tag *tag, int tagid, uint32_t loc) 622 { 623 tag->id = udf_rw16(tagid); 624 tag->descriptor_ver = udf_rw16(context.dscrver); 625 tag->cksum = 0; 626 tag->reserved = 0; 627 tag->serial_num = udf_rw16(context.serialnum); 628 tag->tag_loc = udf_rw32(loc); 629 } 630 631 632 int 633 udf_create_anchor(int num) 634 { 635 struct anchor_vdp *avdp; 636 uint32_t vds1_extent_len = layout.vds1_size * context.sector_size; 637 uint32_t vds2_extent_len = layout.vds2_size * context.sector_size; 638 639 avdp = context.anchors[num]; 640 if (!avdp) 641 if ((avdp = calloc(1, context.sector_size)) == NULL) 642 return ENOMEM; 643 644 udf_inittag(&avdp->tag, TAGID_ANCHOR, layout.anchors[num]); 645 646 avdp->main_vds_ex.loc = udf_rw32(layout.vds1); 647 avdp->main_vds_ex.len = udf_rw32(vds1_extent_len); 648 649 avdp->reserve_vds_ex.loc = udf_rw32(layout.vds2); 650 avdp->reserve_vds_ex.len = udf_rw32(vds2_extent_len); 651 652 /* CRC length for an anchor is 512 - tag length; defined in Ecma 167 */ 653 avdp->tag.desc_crc_len = udf_rw16(512-UDF_DESC_TAG_LENGTH); 654 655 context.anchors[num] = avdp; 656 return 0; 657 } 658 659 660 void 661 udf_create_terminator(union dscrptr *dscr, uint32_t loc) 662 { 663 memset(dscr, 0, context.sector_size); 664 udf_inittag(&dscr->tag, TAGID_TERM, loc); 665 666 /* CRC length for an anchor is 512 - tag length; defined in Ecma 167 */ 667 dscr->tag.desc_crc_len = udf_rw16(512-UDF_DESC_TAG_LENGTH); 668 } 669 670 671 void 672 udf_osta_charset(struct charspec *charspec) 673 { 674 memset(charspec, 0, sizeof(*charspec)); 675 charspec->type = 0; 676 strcpy((char *) charspec->inf, "OSTA Compressed Unicode"); 677 } 678 679 680 /* ---- shared from kernel's udf_subr.c, slightly modified ---- */ 681 void 682 udf_to_unix_name(char *result, int result_len, char *id, int len, 683 struct charspec *chsp) 684 { 685 uint16_t *raw_name, *unix_name; 686 uint16_t *inchp, ch; 687 char *outchp; 688 const char *osta_id = "OSTA Compressed Unicode"; 689 int ucode_chars, nice_uchars, is_osta_typ0, nout; 690 691 raw_name = malloc(2048 * sizeof(uint16_t)); 692 assert(raw_name); 693 694 unix_name = raw_name + 1024; /* split space in half */ 695 assert(sizeof(char) == sizeof(uint8_t)); 696 outchp = result; 697 698 is_osta_typ0 = (chsp->type == 0); 699 is_osta_typ0 &= (strcmp((char *) chsp->inf, osta_id) == 0); 700 if (is_osta_typ0) { 701 /* TODO clean up */ 702 *raw_name = *unix_name = 0; 703 ucode_chars = udf_UncompressUnicode(len, (uint8_t *) id, raw_name); 704 ucode_chars = MIN(ucode_chars, UnicodeLength((unicode_t *) raw_name)); 705 nice_uchars = UDFTransName(unix_name, raw_name, ucode_chars); 706 /* output UTF8 */ 707 for (inchp = unix_name; nice_uchars>0; inchp++, nice_uchars--) { 708 ch = *inchp; 709 nout = wput_utf8(outchp, result_len, ch); 710 outchp += nout; result_len -= nout; 711 if (!ch) break; 712 } 713 *outchp++ = 0; 714 } else { 715 /* assume 8bit char length byte latin-1 */ 716 assert(*id == 8); 717 assert(strlen((char *) (id+1)) <= NAME_MAX); 718 memcpy((char *) result, (char *) (id+1), strlen((char *) (id+1))); 719 } 720 free(raw_name); 721 } 722 723 724 void 725 unix_to_udf_name(char *result, uint8_t *result_len, char const *name, int name_len, 726 struct charspec *chsp) 727 { 728 uint16_t *raw_name; 729 uint16_t *outchp; 730 const char *inchp; 731 const char *osta_id = "OSTA Compressed Unicode"; 732 int udf_chars, is_osta_typ0, bits; 733 size_t cnt; 734 735 /* allocate temporary unicode-16 buffer */ 736 raw_name = malloc(1024); 737 assert(raw_name); 738 739 /* convert utf8 to unicode-16 */ 740 *raw_name = 0; 741 inchp = name; 742 outchp = raw_name; 743 bits = 8; 744 for (cnt = name_len, udf_chars = 0; cnt;) { 745 *outchp = wget_utf8(&inchp, &cnt); 746 if (*outchp > 0xff) 747 bits=16; 748 outchp++; 749 udf_chars++; 750 } 751 /* null terminate just in case */ 752 *outchp++ = 0; 753 754 is_osta_typ0 = (chsp->type == 0); 755 is_osta_typ0 &= (strcmp((char *) chsp->inf, osta_id) == 0); 756 if (is_osta_typ0) { 757 udf_chars = udf_CompressUnicode(udf_chars, bits, 758 (unicode_t *) raw_name, 759 (byte *) result); 760 } else { 761 printf("unix to udf name: no CHSP0 ?\n"); 762 /* XXX assume 8bit char length byte latin-1 */ 763 *result++ = 8; udf_chars = 1; 764 strncpy(result, name + 1, name_len); 765 udf_chars += name_len; 766 } 767 *result_len = udf_chars; 768 free(raw_name); 769 } 770 771 772 /* first call udf_set_regid and then the suffix */ 773 void 774 udf_set_regid(struct regid *regid, char const *name) 775 { 776 memset(regid, 0, sizeof(*regid)); 777 regid->flags = 0; /* not dirty and not protected */ 778 strcpy((char *) regid->id, name); 779 } 780 781 782 void 783 udf_add_domain_regid(struct regid *regid) 784 { 785 uint16_t *ver; 786 787 ver = (uint16_t *) regid->id_suffix; 788 *ver = udf_rw16(context.min_udf); 789 } 790 791 792 void 793 udf_add_udf_regid(struct regid *regid) 794 { 795 uint16_t *ver; 796 797 ver = (uint16_t *) regid->id_suffix; 798 *ver = udf_rw16(context.min_udf); 799 800 regid->id_suffix[2] = 4; /* unix */ 801 regid->id_suffix[3] = 8; /* NetBSD */ 802 } 803 804 805 void 806 udf_add_impl_regid(struct regid *regid) 807 { 808 regid->id_suffix[0] = 4; /* unix */ 809 regid->id_suffix[1] = 8; /* NetBSD */ 810 } 811 812 813 void 814 udf_add_app_regid(struct regid *regid) 815 { 816 regid->id_suffix[0] = context.app_version_main; 817 regid->id_suffix[1] = context.app_version_sub; 818 } 819 820 821 /* 822 * Timestamp to timespec conversion code is taken with small modifications 823 * from FreeBSD /sys/fs/udf by Scott Long <scottl@freebsd.org> 824 */ 825 826 static int mon_lens[2][12] = { 827 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 828 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 829 }; 830 831 832 static int 833 udf_isaleapyear(int year) 834 { 835 int i; 836 837 i = (year % 4) ? 0 : 1; 838 i &= (year % 100) ? 1 : 0; 839 i |= (year % 400) ? 0 : 1; 840 841 return i; 842 } 843 844 845 void 846 udf_timestamp_to_timespec(struct timestamp *timestamp, struct timespec *timespec) 847 { 848 uint32_t usecs, secs, nsecs; 849 uint16_t tz; 850 int i, lpyear, daysinyear, year; 851 852 timespec->tv_sec = secs = 0; 853 timespec->tv_nsec = nsecs = 0; 854 855 /* 856 * DirectCD seems to like using bogus year values. 857 * Distrust time->month especially, since it will be used for an array 858 * index. 859 */ 860 year = udf_rw16(timestamp->year); 861 if ((year < 1970) || (timestamp->month > 12)) { 862 return; 863 } 864 865 /* Calculate the time and day */ 866 usecs = timestamp->usec + 100*timestamp->hund_usec + 10000*timestamp->centisec; 867 nsecs = usecs * 1000; 868 secs = timestamp->second; 869 secs += timestamp->minute * 60; 870 secs += timestamp->hour * 3600; 871 secs += (timestamp->day-1) * 3600 * 24; /* day : 1-31 */ 872 873 /* Calclulate the month */ 874 lpyear = udf_isaleapyear(year); 875 for (i = 1; i < timestamp->month; i++) 876 secs += mon_lens[lpyear][i-1] * 3600 * 24; /* month: 1-12 */ 877 878 for (i = 1970; i < year; i++) { 879 daysinyear = udf_isaleapyear(i) + 365 ; 880 secs += daysinyear * 3600 * 24; 881 } 882 883 /* 884 * Calculate the time zone. The timezone is 12 bit signed 2's 885 * compliment, so we gotta do some extra magic to handle it right. 886 */ 887 tz = udf_rw16(timestamp->type_tz); 888 tz &= 0x0fff; /* only lower 12 bits are significant */ 889 if (tz & 0x0800) /* sign extention */ 890 tz |= 0xf000; 891 892 /* TODO check timezone conversion */ 893 #if 1 894 /* check if we are specified a timezone to convert */ 895 if (udf_rw16(timestamp->type_tz) & 0x1000) 896 if ((int16_t) tz != -2047) 897 secs -= (int16_t) tz * 60; 898 #endif 899 timespec->tv_sec = secs; 900 timespec->tv_nsec = nsecs; 901 } 902 903 904 /* 905 * Fill in timestamp structure based on clock_gettime(). Time is reported back 906 * as a time_t accompanied with a nano second field. 907 * 908 * The husec, usec and csec could be relaxed in type. 909 */ 910 void 911 udf_timespec_to_timestamp(struct timespec *timespec, struct timestamp *timestamp) 912 { 913 struct tm tm; 914 uint64_t husec, usec, csec; 915 916 memset(timestamp, 0, sizeof(*timestamp)); 917 gmtime_r(×pec->tv_sec, &tm); 918 919 /* 920 * Time type and time zone : see ECMA 1/7.3, UDF 2., 2.1.4.1, 3.1.1. 921 * 922 * Lower 12 bits are two complement signed timezone offset if bit 12 923 * (method 1) is clear. Otherwise if bit 12 is set, specify timezone 924 * offset to -2047 i.e. unsigned `zero' 925 */ 926 927 /* set method 1 for CUT/GMT */ 928 timestamp->type_tz = udf_rw16((1<<12) + 0); 929 timestamp->year = udf_rw16(tm.tm_year + 1900); 930 timestamp->month = tm.tm_mon + 1; /* `tm' uses 0..11 for months */ 931 timestamp->day = tm.tm_mday; 932 timestamp->hour = tm.tm_hour; 933 timestamp->minute = tm.tm_min; 934 timestamp->second = tm.tm_sec; 935 936 usec = (timespec->tv_nsec + 500) / 1000; /* round */ 937 husec = usec / 100; 938 usec -= husec * 100; /* only 0-99 in usec */ 939 csec = husec / 100; /* only 0-99 in csec */ 940 husec -= csec * 100; /* only 0-99 in husec */ 941 942 /* in rare cases there is overflow in csec */ 943 csec = MIN(99, csec); 944 husec = MIN(99, husec); 945 usec = MIN(99, usec); 946 947 timestamp->centisec = csec; 948 timestamp->hund_usec = husec; 949 timestamp->usec = usec; 950 } 951 952 953 static void 954 udf_set_timestamp(struct timestamp *timestamp, time_t value) 955 { 956 struct timespec t; 957 958 memset(&t, 0, sizeof(struct timespec)); 959 t.tv_sec = value; 960 t.tv_nsec = 0; 961 udf_timespec_to_timestamp(&t, timestamp); 962 } 963 964 965 static uint32_t 966 unix_mode_to_udf_perm(mode_t mode) 967 { 968 uint32_t perm; 969 970 perm = ((mode & S_IRWXO) ); 971 perm |= ((mode & S_IRWXG) << 2); 972 perm |= ((mode & S_IRWXU) << 4); 973 perm |= ((mode & S_IWOTH) << 3); 974 perm |= ((mode & S_IWGRP) << 5); 975 perm |= ((mode & S_IWUSR) << 7); 976 977 return perm; 978 } 979 980 /* end of copied code */ 981 982 983 void 984 udf_encode_osta_id(char *osta_id, uint16_t len, char *text) 985 { 986 struct charspec osta_charspec; 987 uint8_t result_len; 988 989 memset(osta_id, 0, len); 990 if (!text || (strlen(text) == 0)) return; 991 992 udf_osta_charset(&osta_charspec); 993 unix_to_udf_name(osta_id, &result_len, text, strlen(text), 994 &osta_charspec); 995 996 /* Ecma 167/7.2.13 states that length is recorded in the last byte */ 997 osta_id[len-1] = strlen(text)+1; 998 } 999 1000 1001 void 1002 udf_set_timestamp_now(struct timestamp *timestamp) 1003 { 1004 struct timespec now; 1005 1006 #ifdef CLOCK_REALTIME 1007 (void)clock_gettime(CLOCK_REALTIME, &now); 1008 #else 1009 struct timeval time_of_day; 1010 1011 (void)gettimeofday(&time_of_day, NULL); 1012 now.tv_sec = time_of_day.tv_sec; 1013 now.tv_nsec = time_of_day.tv_usec * 1000; 1014 #endif 1015 udf_timespec_to_timestamp(&now, timestamp); 1016 } 1017 1018 1019 int 1020 udf_create_primaryd(void) 1021 { 1022 struct pri_vol_desc *pri; 1023 uint16_t crclen; 1024 1025 pri = calloc(1, context.sector_size); 1026 if (pri == NULL) 1027 return ENOMEM; 1028 1029 memset(pri, 0, context.sector_size); 1030 udf_inittag(&pri->tag, TAGID_PRI_VOL, /* loc */ 0); 1031 pri->seq_num = udf_rw32(context.vds_seq); context.vds_seq++; 1032 1033 pri->pvd_num = udf_rw32(0); /* default serial */ 1034 udf_encode_osta_id(pri->vol_id, 32, context.primary_name); 1035 1036 /* set defaults for single disc volumes as UDF prescribes */ 1037 pri->vds_num = udf_rw16(1); 1038 pri->max_vol_seq = udf_rw16(1); 1039 pri->ichg_lvl = udf_rw16(2); 1040 pri->max_ichg_lvl = udf_rw16(3); 1041 pri->flags = udf_rw16(0); 1042 1043 pri->charset_list = udf_rw32(1); /* only CS0 */ 1044 pri->max_charset_list = udf_rw32(1); /* only CS0 */ 1045 1046 udf_encode_osta_id(pri->volset_id, 128, context.volset_name); 1047 udf_osta_charset(&pri->desc_charset); 1048 udf_osta_charset(&pri->explanatory_charset); 1049 1050 udf_set_regid(&pri->app_id, context.app_name); 1051 udf_add_app_regid(&pri->app_id); 1052 1053 udf_set_regid(&pri->imp_id, context.impl_name); 1054 udf_add_impl_regid(&pri->imp_id); 1055 1056 udf_set_timestamp_now(&pri->time); 1057 1058 crclen = sizeof(struct pri_vol_desc) - UDF_DESC_TAG_LENGTH; 1059 pri->tag.desc_crc_len = udf_rw16(crclen); 1060 1061 context.primary_vol = pri; 1062 1063 return 0; 1064 } 1065 1066 1067 /* 1068 * BUGALERT: some rogue implementations use random physical partition 1069 * numbers to break other implementations so lookup the number. 1070 */ 1071 1072 uint16_t 1073 udf_find_raw_phys(uint16_t raw_phys_part) 1074 { 1075 struct part_desc *part; 1076 uint16_t phys_part; 1077 1078 for (phys_part = 0; phys_part < UDF_PARTITIONS; phys_part++) { 1079 part = context.partitions[phys_part]; 1080 if (part == NULL) 1081 break; 1082 if (udf_rw16(part->part_num) == raw_phys_part) 1083 break; 1084 } 1085 return phys_part; 1086 } 1087 1088 1089 /* XXX no support for unallocated or freed space tables yet (!) */ 1090 int 1091 udf_create_partitiond(int part_num) 1092 { 1093 struct part_desc *pd; 1094 struct part_hdr_desc *phd; 1095 uint32_t sector_size, bitmap_bytes; 1096 uint16_t crclen; 1097 int part_accesstype = context.media_accesstype; 1098 1099 sector_size = context.sector_size; 1100 bitmap_bytes = layout.alloc_bitmap_dscr_size * sector_size; 1101 1102 if (context.partitions[part_num]) 1103 errx(1, "internal error, partition %d already defined in %s", 1104 part_num, __func__); 1105 1106 pd = calloc(1, context.sector_size); 1107 if (pd == NULL) 1108 return ENOMEM; 1109 phd = &pd->_impl_use.part_hdr; 1110 1111 udf_inittag(&pd->tag, TAGID_PARTITION, /* loc */ 0); 1112 pd->seq_num = udf_rw32(context.vds_seq); context.vds_seq++; 1113 1114 pd->flags = udf_rw16(1); /* allocated */ 1115 pd->part_num = udf_rw16(part_num); /* only one physical partition */ 1116 1117 if (context.dscrver == 2) { 1118 udf_set_regid(&pd->contents, "+NSR02"); 1119 } else { 1120 udf_set_regid(&pd->contents, "+NSR03"); 1121 } 1122 udf_add_app_regid(&pd->contents); 1123 1124 phd->unalloc_space_bitmap.len = udf_rw32(bitmap_bytes); 1125 phd->unalloc_space_bitmap.lb_num = udf_rw32(layout.unalloc_space); 1126 1127 if (layout.freed_space) { 1128 phd->freed_space_bitmap.len = udf_rw32(bitmap_bytes); 1129 phd->freed_space_bitmap.lb_num = udf_rw32(layout.freed_space); 1130 } 1131 1132 pd->access_type = udf_rw32(part_accesstype); 1133 pd->start_loc = udf_rw32(layout.part_start_lba); 1134 pd->part_len = udf_rw32(layout.part_size_lba); 1135 1136 udf_set_regid(&pd->imp_id, context.impl_name); 1137 udf_add_impl_regid(&pd->imp_id); 1138 1139 crclen = sizeof(struct part_desc) - UDF_DESC_TAG_LENGTH; 1140 pd->tag.desc_crc_len = udf_rw16(crclen); 1141 1142 context.partitions[part_num] = pd; 1143 1144 return 0; 1145 } 1146 1147 1148 int 1149 udf_create_unalloc_spaced(void) 1150 { 1151 struct unalloc_sp_desc *usd; 1152 uint16_t crclen; 1153 1154 usd = calloc(1, context.sector_size); 1155 if (usd == NULL) 1156 return ENOMEM; 1157 1158 udf_inittag(&usd->tag, TAGID_UNALLOC_SPACE, /* loc */ 0); 1159 usd->seq_num = udf_rw32(context.vds_seq); context.vds_seq++; 1160 1161 /* no default entries */ 1162 usd->alloc_desc_num = udf_rw32(0); /* no entries */ 1163 1164 crclen = sizeof(struct unalloc_sp_desc) - sizeof(struct extent_ad); 1165 crclen -= UDF_DESC_TAG_LENGTH; 1166 usd->tag.desc_crc_len = udf_rw16(crclen); 1167 1168 context.unallocated = usd; 1169 1170 return 0; 1171 } 1172 1173 1174 static int 1175 udf_create_base_logical_dscr(void) 1176 { 1177 struct logvol_desc *lvd; 1178 uint32_t sector_size; 1179 uint16_t crclen; 1180 1181 sector_size = context.sector_size; 1182 1183 lvd = calloc(1, sector_size); 1184 if (lvd == NULL) 1185 return ENOMEM; 1186 1187 udf_inittag(&lvd->tag, TAGID_LOGVOL, /* loc */ 0); 1188 lvd->seq_num = udf_rw32(context.vds_seq); context.vds_seq++; 1189 1190 udf_osta_charset(&lvd->desc_charset); 1191 udf_encode_osta_id(lvd->logvol_id, 128, context.logvol_name); 1192 lvd->lb_size = udf_rw32(sector_size); 1193 1194 udf_set_regid(&lvd->domain_id, "*OSTA UDF Compliant"); 1195 udf_add_domain_regid(&lvd->domain_id); 1196 1197 /* no partition mappings/entries yet */ 1198 lvd->mt_l = udf_rw32(0); 1199 lvd->n_pm = udf_rw32(0); 1200 1201 udf_set_regid(&lvd->imp_id, context.impl_name); 1202 udf_add_impl_regid(&lvd->imp_id); 1203 1204 lvd->integrity_seq_loc.loc = udf_rw32(layout.lvis); 1205 lvd->integrity_seq_loc.len = udf_rw32(layout.lvis_size * sector_size); 1206 1207 /* just one fsd for now */ 1208 lvd->lv_fsd_loc.len = udf_rw32(sector_size); 1209 lvd->lv_fsd_loc.loc.part_num = udf_rw16(context.metadata_part); 1210 lvd->lv_fsd_loc.loc.lb_num = udf_rw32(layout.fsd); 1211 1212 crclen = sizeof(struct logvol_desc) - 1 - UDF_DESC_TAG_LENGTH; 1213 lvd->tag.desc_crc_len = udf_rw16(crclen); 1214 1215 context.logical_vol = lvd; 1216 context.vtop_tp[UDF_VTOP_RAWPART] = UDF_VTOP_TYPE_RAW; 1217 1218 return 0; 1219 } 1220 1221 1222 static void 1223 udf_add_logvol_part_physical(uint16_t phys_part) 1224 { 1225 struct logvol_desc *logvol = context.logical_vol; 1226 union udf_pmap *pmap; 1227 uint8_t *pmap_pos; 1228 uint16_t crclen; 1229 uint32_t pmap1_size, log_part; 1230 1231 log_part = udf_rw32(logvol->n_pm); 1232 pmap_pos = logvol->maps + udf_rw32(logvol->mt_l); 1233 pmap1_size = sizeof(struct part_map_1); 1234 1235 pmap = (union udf_pmap *) pmap_pos; 1236 pmap->pm1.type = 1; 1237 pmap->pm1.len = sizeof(struct part_map_1); 1238 pmap->pm1.vol_seq_num = udf_rw16(1); /* no multi-volume */ 1239 pmap->pm1.part_num = udf_rw16(phys_part); 1240 1241 context.vtop [log_part] = phys_part; 1242 context.vtop_tp [log_part] = UDF_VTOP_TYPE_PHYS; 1243 context.part_size[log_part] = layout.part_size_lba; 1244 context.part_free[log_part] = layout.part_size_lba; 1245 1246 /* increment number of partitions and length */ 1247 logvol->n_pm = udf_rw32(log_part + 1); 1248 logvol->mt_l = udf_rw32(udf_rw32(logvol->mt_l) + pmap1_size); 1249 1250 crclen = udf_rw16(logvol->tag.desc_crc_len) + pmap1_size; 1251 logvol->tag.desc_crc_len = udf_rw16(crclen); 1252 } 1253 1254 1255 static void 1256 udf_add_logvol_part_virtual(uint16_t phys_part) 1257 { 1258 union udf_pmap *pmap; 1259 struct logvol_desc *logvol = context.logical_vol; 1260 uint8_t *pmap_pos; 1261 uint16_t crclen; 1262 uint32_t pmapv_size, log_part; 1263 1264 log_part = udf_rw32(logvol->n_pm); 1265 pmap_pos = logvol->maps + udf_rw32(logvol->mt_l); 1266 pmapv_size = sizeof(struct part_map_2); 1267 1268 pmap = (union udf_pmap *) pmap_pos; 1269 pmap->pmv.type = 2; 1270 pmap->pmv.len = pmapv_size; 1271 1272 udf_set_regid(&pmap->pmv.id, "*UDF Virtual Partition"); 1273 udf_add_udf_regid(&pmap->pmv.id); 1274 1275 pmap->pmv.vol_seq_num = udf_rw16(1); /* no multi-volume */ 1276 pmap->pmv.part_num = udf_rw16(phys_part); 1277 1278 context.vtop [log_part] = phys_part; 1279 context.vtop_tp [log_part] = UDF_VTOP_TYPE_VIRT; 1280 context.part_size[log_part] = 0xffffffff; 1281 context.part_free[log_part] = 0xffffffff; 1282 1283 /* increment number of partitions and length */ 1284 logvol->n_pm = udf_rw32(log_part + 1); 1285 logvol->mt_l = udf_rw32(udf_rw32(logvol->mt_l) + pmapv_size); 1286 1287 crclen = udf_rw16(logvol->tag.desc_crc_len) + pmapv_size; 1288 logvol->tag.desc_crc_len = udf_rw16(crclen); 1289 } 1290 1291 1292 /* sparing table size is in bytes */ 1293 static void 1294 udf_add_logvol_part_spareable(uint16_t phys_part) 1295 { 1296 union udf_pmap *pmap; 1297 struct logvol_desc *logvol = context.logical_vol; 1298 uint32_t *st_pos, spareable_bytes, pmaps_size; 1299 uint8_t *pmap_pos, num; 1300 uint16_t crclen; 1301 uint32_t log_part; 1302 1303 log_part = udf_rw32(logvol->n_pm); 1304 pmap_pos = logvol->maps + udf_rw32(logvol->mt_l); 1305 pmaps_size = sizeof(struct part_map_2); 1306 spareable_bytes = layout.spareable_area_size * context.sector_size; 1307 1308 pmap = (union udf_pmap *) pmap_pos; 1309 pmap->pms.type = 2; 1310 pmap->pms.len = pmaps_size; 1311 1312 udf_set_regid(&pmap->pmv.id, "*UDF Sparable Partition"); 1313 udf_add_udf_regid(&pmap->pmv.id); 1314 1315 pmap->pms.vol_seq_num = udf_rw16(1); /* no multi-volume */ 1316 pmap->pms.part_num = udf_rw16(phys_part); 1317 1318 pmap->pms.packet_len = udf_rw16(layout.spareable_blockingnr); 1319 pmap->pms.st_size = udf_rw32(spareable_bytes); 1320 1321 /* enter spare tables */ 1322 st_pos = &pmap->pms.st_loc[0]; 1323 *st_pos++ = udf_rw32(layout.spt_1); 1324 *st_pos++ = udf_rw32(layout.spt_2); 1325 1326 num = 2; 1327 if (layout.spt_2 == 0) num--; 1328 if (layout.spt_1 == 0) num--; 1329 pmap->pms.n_st = num; /* 8 bit */ 1330 1331 context.vtop [log_part] = phys_part; 1332 context.vtop_tp [log_part] = UDF_VTOP_TYPE_SPAREABLE; 1333 context.part_size[log_part] = layout.part_size_lba; 1334 context.part_free[log_part] = layout.part_size_lba; 1335 1336 /* increment number of partitions and length */ 1337 logvol->n_pm = udf_rw32(log_part + 1); 1338 logvol->mt_l = udf_rw32(udf_rw32(logvol->mt_l) + pmaps_size); 1339 1340 crclen = udf_rw16(logvol->tag.desc_crc_len) + pmaps_size; 1341 logvol->tag.desc_crc_len = udf_rw16(crclen); 1342 } 1343 1344 1345 int 1346 udf_create_sparing_tabled(void) 1347 { 1348 struct udf_sparing_table *spt; 1349 struct spare_map_entry *sme; 1350 uint32_t loc, cnt; 1351 uint32_t crclen; /* XXX: should be 16; need to detect overflow */ 1352 1353 spt = calloc(context.sector_size, layout.sparing_table_dscr_lbas); 1354 if (spt == NULL) 1355 return ENOMEM; 1356 1357 /* a sparing table descriptor is a whole spareable_blockingnr sectors */ 1358 udf_inittag(&spt->tag, TAGID_SPARING_TABLE, /* loc */ 0); 1359 1360 udf_set_regid(&spt->id, "*UDF Sparing Table"); 1361 udf_add_udf_regid(&spt->id); 1362 1363 spt->rt_l = udf_rw16(layout.spareable_blocks); 1364 spt->seq_num = udf_rw32(0); /* first generation */ 1365 1366 for (cnt = 0; cnt < layout.spareable_blocks; cnt++) { 1367 sme = &spt->entries[cnt]; 1368 loc = layout.spareable_area + cnt * layout.spareable_blockingnr; 1369 sme->org = udf_rw32(0xffffffff); /* open for reloc */ 1370 sme->map = udf_rw32(loc); 1371 } 1372 1373 /* calculate crc len for actual size */ 1374 crclen = sizeof(struct udf_sparing_table) - UDF_DESC_TAG_LENGTH; 1375 crclen += (layout.spareable_blocks-1) * sizeof(struct spare_map_entry); 1376 1377 assert(crclen <= UINT16_MAX); 1378 spt->tag.desc_crc_len = udf_rw16((uint16_t)crclen); 1379 1380 context.sparing_table = spt; 1381 1382 return 0; 1383 } 1384 1385 1386 static void 1387 udf_add_logvol_part_meta(uint16_t phys_part) 1388 { 1389 union udf_pmap *pmap; 1390 struct logvol_desc *logvol = context.logical_vol; 1391 uint8_t *pmap_pos; 1392 uint32_t pmapv_size, log_part; 1393 uint16_t crclen; 1394 1395 log_part = udf_rw32(logvol->n_pm); 1396 pmap_pos = logvol->maps + udf_rw32(logvol->mt_l); 1397 pmapv_size = sizeof(struct part_map_2); 1398 1399 pmap = (union udf_pmap *) pmap_pos; 1400 pmap->pmm.type = 2; 1401 pmap->pmm.len = pmapv_size; 1402 1403 udf_set_regid(&pmap->pmm.id, "*UDF Metadata Partition"); 1404 udf_add_udf_regid(&pmap->pmm.id); 1405 1406 pmap->pmm.vol_seq_num = udf_rw16(1); /* no multi-volume */ 1407 pmap->pmm.part_num = udf_rw16(phys_part); 1408 1409 /* fill in meta data file(s) and alloc/alignment unit sizes */ 1410 pmap->pmm.meta_file_lbn = udf_rw32(layout.meta_file); 1411 pmap->pmm.meta_mirror_file_lbn = udf_rw32(layout.meta_mirror); 1412 pmap->pmm.meta_bitmap_file_lbn = udf_rw32(layout.meta_bitmap); 1413 pmap->pmm.alloc_unit_size = udf_rw32(layout.meta_blockingnr); 1414 pmap->pmm.alignment_unit_size = udf_rw16(layout.meta_alignment); 1415 pmap->pmm.flags = 0; /* METADATA_DUPLICATED */ 1416 1417 context.vtop [log_part] = phys_part; 1418 context.vtop_tp [log_part] = UDF_VTOP_TYPE_META; 1419 context.part_size[log_part] = layout.meta_part_size_lba; 1420 context.part_free[log_part] = layout.meta_part_size_lba; 1421 1422 /* increment number of partitions and length */ 1423 logvol->n_pm = udf_rw32(log_part + 1); 1424 logvol->mt_l = udf_rw32(udf_rw32(logvol->mt_l) + pmapv_size); 1425 1426 crclen = udf_rw16(logvol->tag.desc_crc_len) + pmapv_size; 1427 logvol->tag.desc_crc_len = udf_rw16(crclen); 1428 } 1429 1430 1431 int 1432 udf_create_logical_dscr(void) 1433 { 1434 int error; 1435 1436 if ((error = udf_create_base_logical_dscr())) 1437 return error; 1438 1439 /* we pass data_part for there might be a read-only part one day */ 1440 if (context.format_flags & FORMAT_SPAREABLE) { 1441 /* spareable partition mapping has no physical mapping */ 1442 udf_add_logvol_part_spareable(context.data_part); 1443 } else { 1444 udf_add_logvol_part_physical(context.data_part); 1445 } 1446 1447 if (context.format_flags & FORMAT_VAT) { 1448 /* add VAT virtual mapping; reflects on datapart */ 1449 udf_add_logvol_part_virtual(context.data_part); 1450 } 1451 if (context.format_flags & FORMAT_META) { 1452 /* add META data mapping; reflects on datapart */ 1453 udf_add_logvol_part_meta(context.data_part); 1454 } 1455 1456 return 0; 1457 } 1458 1459 1460 int 1461 udf_create_impvold(char *field1, char *field2, char *field3) 1462 { 1463 struct impvol_desc *ivd; 1464 struct udf_lv_info *lvi; 1465 uint16_t crclen; 1466 1467 ivd = calloc(1, context.sector_size); 1468 if (ivd == NULL) 1469 return ENOMEM; 1470 lvi = &ivd->_impl_use.lv_info; 1471 1472 udf_inittag(&ivd->tag, TAGID_IMP_VOL, /* loc */ 0); 1473 ivd->seq_num = udf_rw32(context.vds_seq); context.vds_seq++; 1474 1475 udf_set_regid(&ivd->impl_id, "*UDF LV Info"); 1476 udf_add_udf_regid(&ivd->impl_id); 1477 1478 /* fill in UDF specific part */ 1479 udf_osta_charset(&lvi->lvi_charset); 1480 udf_encode_osta_id(lvi->logvol_id, 128, context.logvol_name); 1481 1482 udf_encode_osta_id(lvi->lvinfo1, 36, field1); 1483 udf_encode_osta_id(lvi->lvinfo2, 36, field2); 1484 udf_encode_osta_id(lvi->lvinfo3, 36, field3); 1485 1486 udf_set_regid(&lvi->impl_id, context.impl_name); 1487 udf_add_impl_regid(&lvi->impl_id); 1488 1489 crclen = sizeof(struct impvol_desc) - UDF_DESC_TAG_LENGTH; 1490 ivd->tag.desc_crc_len = udf_rw16(crclen); 1491 1492 context.implementation = ivd; 1493 1494 return 0; 1495 } 1496 1497 1498 /* XXX might need to be sanitised a bit */ 1499 void 1500 udf_update_lvintd(int type) 1501 { 1502 struct logvol_int_desc *lvid; 1503 struct udf_logvol_info *lvinfo; 1504 struct logvol_desc *logvol; 1505 uint32_t *pos; 1506 uint32_t cnt, num_partmappings; 1507 uint32_t crclen; /* XXX: should be 16; need to detect overflow */ 1508 1509 lvid = context.logvol_integrity; 1510 logvol = context.logical_vol; 1511 assert(lvid); 1512 assert(logvol); 1513 1514 lvid->integrity_type = udf_rw32(type); 1515 udf_set_timestamp_now(&lvid->time); 1516 1517 /* initialise lvinfo just in case its not set yet */ 1518 num_partmappings = udf_rw32(logvol->n_pm); 1519 assert(num_partmappings > 0); 1520 1521 lvinfo = (struct udf_logvol_info *) 1522 (lvid->tables + num_partmappings * 2); 1523 context.logvol_info = lvinfo; 1524 1525 udf_set_regid(&lvinfo->impl_id, context.impl_name); 1526 udf_add_impl_regid(&lvinfo->impl_id); 1527 1528 if (type == UDF_INTEGRITY_CLOSED) { 1529 lvinfo->num_files = udf_rw32(context.num_files); 1530 lvinfo->num_directories = udf_rw32(context.num_directories); 1531 1532 lvid->lvint_next_unique_id = udf_rw64(context.unique_id); 1533 } 1534 1535 /* sane enough? */ 1536 if (udf_rw16(lvinfo->min_udf_readver) < context.min_udf) 1537 lvinfo->min_udf_readver = udf_rw16(context.min_udf); 1538 if (udf_rw16(lvinfo->min_udf_writever) < context.min_udf) 1539 lvinfo->min_udf_writever = udf_rw16(context.min_udf); 1540 if (udf_rw16(lvinfo->max_udf_writever) < context.max_udf) 1541 lvinfo->max_udf_writever = udf_rw16(context.max_udf); 1542 1543 lvid->num_part = udf_rw32(num_partmappings); 1544 1545 pos = &lvid->tables[0]; 1546 for (cnt = 0; cnt < num_partmappings; cnt++) { 1547 *pos++ = udf_rw32(context.part_free[cnt]); 1548 } 1549 for (cnt = 0; cnt < num_partmappings; cnt++) { 1550 *pos++ = udf_rw32(context.part_size[cnt]); 1551 } 1552 1553 crclen = sizeof(struct logvol_int_desc) -4 -UDF_DESC_TAG_LENGTH + 1554 udf_rw32(lvid->l_iu); 1555 crclen += num_partmappings * 2 * 4; 1556 1557 assert(crclen <= UINT16_MAX); 1558 if (lvid->tag.desc_crc_len == 0) 1559 lvid->tag.desc_crc_len = udf_rw16(crclen); 1560 1561 context.logvol_info = lvinfo; 1562 } 1563 1564 1565 int 1566 udf_create_lvintd(int type) 1567 { 1568 struct logvol_int_desc *lvid; 1569 int l_iu; 1570 1571 lvid = calloc(1, context.sector_size); 1572 if (lvid == NULL) 1573 return ENOMEM; 1574 1575 udf_inittag(&lvid->tag, TAGID_LOGVOL_INTEGRITY, /* loc */ 0); 1576 context.logvol_integrity = lvid; 1577 1578 /* only set for standard UDF info, no extra impl. use needed */ 1579 l_iu = sizeof(struct udf_logvol_info); 1580 lvid->l_iu = udf_rw32(l_iu); 1581 1582 udf_update_lvintd(type); 1583 1584 return 0; 1585 } 1586 1587 1588 int 1589 udf_create_fsd(void) 1590 { 1591 struct fileset_desc *fsd; 1592 uint16_t crclen; 1593 1594 fsd = calloc(1, context.sector_size); 1595 if (fsd == NULL) 1596 return ENOMEM; 1597 1598 udf_inittag(&fsd->tag, TAGID_FSD, /* loc */ 0); 1599 1600 udf_set_timestamp_now(&fsd->time); 1601 fsd->ichg_lvl = udf_rw16(3); /* UDF 2.3.2.1 */ 1602 fsd->max_ichg_lvl = udf_rw16(3); /* UDF 2.3.2.2 */ 1603 1604 fsd->charset_list = udf_rw32(1); /* only CS0 */ 1605 fsd->max_charset_list = udf_rw32(1); /* only CS0 */ 1606 1607 fsd->fileset_num = udf_rw32(0); /* only one fsd */ 1608 fsd->fileset_desc_num = udf_rw32(0); /* original */ 1609 1610 udf_osta_charset(&fsd->logvol_id_charset); 1611 udf_encode_osta_id(fsd->logvol_id, 128, context.logvol_name); 1612 1613 udf_osta_charset(&fsd->fileset_charset); 1614 udf_encode_osta_id(fsd->fileset_id, 32, context.fileset_name); 1615 1616 /* copyright file and abstract file names obmitted */ 1617 1618 fsd->rootdir_icb.len = udf_rw32(context.sector_size); 1619 fsd->rootdir_icb.loc.lb_num = udf_rw32(layout.rootdir); 1620 fsd->rootdir_icb.loc.part_num = udf_rw16(context.metadata_part); 1621 1622 udf_set_regid(&fsd->domain_id, "*OSTA UDF Compliant"); 1623 udf_add_domain_regid(&fsd->domain_id); 1624 1625 /* next_ex stays zero */ 1626 /* no system streamdirs yet */ 1627 1628 crclen = sizeof(struct fileset_desc) - UDF_DESC_TAG_LENGTH; 1629 fsd->tag.desc_crc_len = udf_rw16(crclen); 1630 1631 context.fileset_desc = fsd; 1632 1633 return 0; 1634 } 1635 1636 1637 int 1638 udf_create_space_bitmap(uint32_t dscr_size, uint32_t part_size_lba, 1639 struct space_bitmap_desc **sbdp) 1640 { 1641 struct space_bitmap_desc *sbd; 1642 uint32_t cnt; 1643 uint16_t crclen; 1644 1645 *sbdp = NULL; 1646 sbd = calloc(context.sector_size, dscr_size); 1647 if (sbd == NULL) 1648 return ENOMEM; 1649 1650 udf_inittag(&sbd->tag, TAGID_SPACE_BITMAP, /* loc */ 0); 1651 1652 sbd->num_bits = udf_rw32(part_size_lba); 1653 sbd->num_bytes = udf_rw32((part_size_lba + 7)/8); 1654 1655 /* fill space with 0xff to indicate free */ 1656 for (cnt = 0; cnt < udf_rw32(sbd->num_bytes); cnt++) 1657 sbd->data[cnt] = 0xff; 1658 1659 /* set crc to only cover the header (UDF 2.3.1.2, 2.3.8.1) */ 1660 crclen = sizeof(struct space_bitmap_desc) -1 - UDF_DESC_TAG_LENGTH; 1661 sbd->tag.desc_crc_len = udf_rw16(crclen); 1662 1663 *sbdp = sbd; 1664 return 0; 1665 } 1666 1667 /* --------------------------------------------------------------------- */ 1668 1669 int 1670 udf_register_bad_block(uint32_t location) 1671 { 1672 struct udf_sparing_table *spt; 1673 struct spare_map_entry *sme, *free_sme; 1674 uint32_t cnt; 1675 1676 spt = context.sparing_table; 1677 if (spt == NULL) 1678 errx(1, "internal error, adding bad block to " 1679 "non spareable in %s", __func__); 1680 1681 /* find us a free spare map entry */ 1682 free_sme = NULL; 1683 for (cnt = 0; cnt < layout.spareable_blocks; cnt++) { 1684 sme = &spt->entries[cnt]; 1685 /* if we are already in it, bail out */ 1686 if (udf_rw32(sme->org) == location) 1687 return 0; 1688 if (udf_rw32(sme->org) == 0xffffffff) { 1689 free_sme = sme; 1690 break; 1691 } 1692 } 1693 if (free_sme == NULL) { 1694 warnx("disc relocation blocks full; disc too damaged"); 1695 return EINVAL; 1696 } 1697 free_sme->org = udf_rw32(location); 1698 1699 return 0; 1700 } 1701 1702 1703 void 1704 udf_mark_allocated(uint32_t start_lb, int partnr, uint32_t blocks) 1705 { 1706 union dscrptr *dscr; 1707 uint8_t *bpos; 1708 uint32_t cnt, bit; 1709 1710 /* account for space used on underlying partition */ 1711 #ifdef DEBUG 1712 printf("mark allocated : partnr %d, start_lb %d for %d blocks\n", 1713 partnr, start_lb, blocks); 1714 #endif 1715 1716 switch (context.vtop_tp[partnr]) { 1717 case UDF_VTOP_TYPE_VIRT: 1718 /* nothing */ 1719 break; 1720 case UDF_VTOP_TYPE_PHYS: 1721 case UDF_VTOP_TYPE_SPAREABLE: 1722 case UDF_VTOP_TYPE_META: 1723 if (context.part_unalloc_bits[context.vtop[partnr]] == NULL) { 1724 context.part_free[partnr] = 0; 1725 break; 1726 } 1727 #ifdef DEBUG 1728 printf("marking %d+%d as used\n", start_lb, blocks); 1729 #endif 1730 dscr = (union dscrptr *) (context.part_unalloc_bits[partnr]); 1731 for (cnt = start_lb; cnt < start_lb + blocks; cnt++) { 1732 bpos = &dscr->sbd.data[cnt / 8]; 1733 bit = cnt % 8; 1734 /* only account for bits marked free */ 1735 if ((*bpos & (1 << bit))) 1736 context.part_free[partnr] -= 1; 1737 *bpos &= ~(1<< bit); 1738 } 1739 break; 1740 default: 1741 errx(1, "internal error: bad mapping type %d in %s", 1742 context.vtop_tp[partnr], __func__); 1743 } 1744 } 1745 1746 1747 void 1748 udf_advance_uniqueid(void) 1749 { 1750 /* Minimum value of 16 : UDF 3.2.1.1, 3.3.3.4. */ 1751 context.unique_id++; 1752 if (context.unique_id < 0x10) 1753 context.unique_id = 0x10; 1754 } 1755 1756 /* --------------------------------------------------------------------- */ 1757 1758 /* XXX implement the using of the results */ 1759 int 1760 udf_surface_check(void) 1761 { 1762 uint32_t loc, block_bytes; 1763 uint32_t sector_size, blockingnr, bpos; 1764 uint8_t *buffer; 1765 int error, num_errors; 1766 1767 if (mmc_discinfo.mmc_class == MMC_CLASS_DISC) 1768 return 0; 1769 1770 sector_size = context.sector_size; 1771 blockingnr = layout.blockingnr; 1772 1773 block_bytes = layout.blockingnr * sector_size; 1774 if ((buffer = malloc(block_bytes)) == NULL) 1775 return ENOMEM; 1776 1777 /* set all one to not kill Flash memory? */ 1778 for (bpos = 0; bpos < block_bytes; bpos++) 1779 buffer[bpos] = 0x00; 1780 1781 printf("\nChecking disc surface : phase 1 - writing\n"); 1782 num_errors = 0; 1783 loc = layout.first_lba; 1784 while (loc <= layout.last_lba) { 1785 /* write blockingnr sectors */ 1786 error = pwrite(dev_fd, buffer, block_bytes, 1787 (uint64_t) loc*sector_size); 1788 printf(" %08d + %d (%02d %%)\r", loc, blockingnr, 1789 (int)((100.0 * loc)/layout.last_lba)); 1790 fflush(stdout); 1791 if (error == -1) { 1792 /* block is bad */ 1793 printf("BAD block at %08d + %d \n", 1794 loc, layout.blockingnr); 1795 if ((error = udf_register_bad_block(loc))) { 1796 free(buffer); 1797 return error; 1798 } 1799 num_errors ++; 1800 } 1801 loc += layout.blockingnr; 1802 } 1803 1804 printf("\nChecking disc surface : phase 2 - reading\n"); 1805 num_errors = 0; 1806 loc = layout.first_lba; 1807 while (loc <= layout.last_lba) { 1808 /* read blockingnr sectors */ 1809 error = pread(dev_fd, buffer, block_bytes, loc*sector_size); 1810 printf(" %08d + %d (%02d %%)\r", loc, blockingnr, 1811 (int)((100.0 * loc)/layout.last_lba)); 1812 fflush(stdout); 1813 if (error == -1) { 1814 /* block is bad */ 1815 printf("BAD block at %08d + %d \n", 1816 loc, layout.blockingnr); 1817 if ((error = udf_register_bad_block(loc))) { 1818 free(buffer); 1819 return error; 1820 } 1821 num_errors ++; 1822 } 1823 loc += layout.blockingnr; 1824 } 1825 printf("Scan complete : %d bad blocks found\n", num_errors); 1826 free(buffer); 1827 1828 return 0; 1829 } 1830 1831 /* --------------------------------------------------------------------- */ 1832 1833 #define UDF_SYMLINKBUFLEN (64*1024) /* picked */ 1834 int 1835 udf_encode_symlink(uint8_t **pathbufp, uint32_t *pathlenp, char *target) 1836 { 1837 struct charspec osta_charspec; 1838 struct pathcomp pathcomp; 1839 char *pathbuf, *pathpos, *compnamepos; 1840 // char *mntonname; 1841 // int mntonnamelen; 1842 int pathlen, len, compnamelen; 1843 int error; 1844 1845 /* process `target' to an UDF structure */ 1846 pathbuf = malloc(UDF_SYMLINKBUFLEN); 1847 assert(pathbuf); 1848 1849 *pathbufp = NULL; 1850 *pathlenp = 0; 1851 1852 pathpos = pathbuf; 1853 pathlen = 0; 1854 udf_osta_charset(&osta_charspec); 1855 1856 if (*target == '/') { 1857 /* symlink starts from the root */ 1858 len = UDF_PATH_COMP_SIZE; 1859 memset(&pathcomp, 0, len); 1860 pathcomp.type = UDF_PATH_COMP_ROOT; 1861 1862 #if 0 1863 /* XXX how to check for in makefs? */ 1864 /* check if its mount-point relative! */ 1865 mntonname = udf_node->ump->vfs_mountp->mnt_stat.f_mntonname; 1866 mntonnamelen = strlen(mntonname); 1867 if (strlen(target) >= mntonnamelen) { 1868 if (strncmp(target, mntonname, mntonnamelen) == 0) { 1869 pathcomp.type = UDF_PATH_COMP_MOUNTROOT; 1870 target += mntonnamelen; 1871 } 1872 } else { 1873 target++; 1874 } 1875 #else 1876 target++; 1877 #endif 1878 1879 memcpy(pathpos, &pathcomp, len); 1880 pathpos += len; 1881 pathlen += len; 1882 } 1883 1884 error = 0; 1885 while (*target) { 1886 /* ignore multiple '/' */ 1887 while (*target == '/') { 1888 target++; 1889 } 1890 if (!*target) 1891 break; 1892 1893 /* extract component name */ 1894 compnamelen = 0; 1895 compnamepos = target; 1896 while ((*target) && (*target != '/')) { 1897 target++; 1898 compnamelen++; 1899 } 1900 1901 /* just trunc if too long ?? (security issue) */ 1902 if (compnamelen >= 127) { 1903 error = ENAMETOOLONG; 1904 break; 1905 } 1906 1907 /* convert unix name to UDF name */ 1908 len = sizeof(struct pathcomp); 1909 memset(&pathcomp, 0, len); 1910 pathcomp.type = UDF_PATH_COMP_NAME; 1911 len = UDF_PATH_COMP_SIZE; 1912 1913 if ((compnamelen == 2) && (strncmp(compnamepos, "..", 2) == 0)) 1914 pathcomp.type = UDF_PATH_COMP_PARENTDIR; 1915 if ((compnamelen == 1) && (*compnamepos == '.')) 1916 pathcomp.type = UDF_PATH_COMP_CURDIR; 1917 1918 if (pathcomp.type == UDF_PATH_COMP_NAME) { 1919 unix_to_udf_name( 1920 (char *) &pathcomp.ident, &pathcomp.l_ci, 1921 compnamepos, compnamelen, 1922 &osta_charspec); 1923 len = UDF_PATH_COMP_SIZE + pathcomp.l_ci; 1924 } 1925 1926 if (pathlen + len >= UDF_SYMLINKBUFLEN) { 1927 error = ENAMETOOLONG; 1928 break; 1929 } 1930 1931 memcpy(pathpos, &pathcomp, len); 1932 pathpos += len; 1933 pathlen += len; 1934 } 1935 1936 if (error) { 1937 /* apparently too big */ 1938 free(pathbuf); 1939 return error; 1940 } 1941 1942 /* return status of symlink contents writeout */ 1943 *pathbufp = (uint8_t *) pathbuf; 1944 *pathlenp = pathlen; 1945 1946 return 0; 1947 1948 } 1949 #undef UDF_SYMLINKBUFLEN 1950 1951 1952 /* 1953 * XXX note the different semantics from udfclient: for FIDs it still rounds 1954 * up to sectors. Use udf_fidsize() for a correct length. 1955 */ 1956 uint32_t 1957 udf_tagsize(union dscrptr *dscr, uint32_t lb_size) 1958 { 1959 uint32_t size, tag_id, num_lb, elmsz; 1960 1961 tag_id = udf_rw16(dscr->tag.id); 1962 1963 switch (tag_id) { 1964 case TAGID_LOGVOL : 1965 size = sizeof(struct logvol_desc) - 1; 1966 size += udf_rw32(dscr->lvd.mt_l); 1967 break; 1968 case TAGID_UNALLOC_SPACE : 1969 elmsz = sizeof(struct extent_ad); 1970 size = sizeof(struct unalloc_sp_desc) - elmsz; 1971 size += udf_rw32(dscr->usd.alloc_desc_num) * elmsz; 1972 break; 1973 case TAGID_FID : 1974 size = UDF_FID_SIZE + dscr->fid.l_fi + udf_rw16(dscr->fid.l_iu); 1975 size = (size + 3) & ~3; 1976 break; 1977 case TAGID_LOGVOL_INTEGRITY : 1978 size = sizeof(struct logvol_int_desc) - sizeof(uint32_t); 1979 size += udf_rw32(dscr->lvid.l_iu); 1980 size += (2 * udf_rw32(dscr->lvid.num_part) * sizeof(uint32_t)); 1981 break; 1982 case TAGID_SPACE_BITMAP : 1983 size = sizeof(struct space_bitmap_desc) - 1; 1984 size += udf_rw32(dscr->sbd.num_bytes); 1985 break; 1986 case TAGID_SPARING_TABLE : 1987 elmsz = sizeof(struct spare_map_entry); 1988 size = sizeof(struct udf_sparing_table) - elmsz; 1989 size += udf_rw16(dscr->spt.rt_l) * elmsz; 1990 break; 1991 case TAGID_FENTRY : 1992 size = sizeof(struct file_entry); 1993 size += udf_rw32(dscr->fe.l_ea) + udf_rw32(dscr->fe.l_ad)-1; 1994 break; 1995 case TAGID_EXTFENTRY : 1996 size = sizeof(struct extfile_entry); 1997 size += udf_rw32(dscr->efe.l_ea) + udf_rw32(dscr->efe.l_ad)-1; 1998 break; 1999 case TAGID_FSD : 2000 size = sizeof(struct fileset_desc); 2001 break; 2002 default : 2003 size = sizeof(union dscrptr); 2004 break; 2005 } 2006 2007 if ((size == 0) || (lb_size == 0)) 2008 return 0; 2009 2010 if (lb_size == 1) 2011 return size; 2012 2013 /* round up in sectors */ 2014 num_lb = (size + lb_size -1) / lb_size; 2015 return num_lb * lb_size; 2016 } 2017 2018 2019 int 2020 udf_fidsize(struct fileid_desc *fid) 2021 { 2022 uint32_t size; 2023 2024 if (udf_rw16(fid->tag.id) != TAGID_FID) 2025 errx(1, "internal error, bad tag in %s", __func__); 2026 2027 size = UDF_FID_SIZE + fid->l_fi + udf_rw16(fid->l_iu); 2028 size = (size + 3) & ~3; 2029 2030 return size; 2031 } 2032 2033 2034 int 2035 udf_create_parentfid(struct fileid_desc *fid, struct long_ad *parent) 2036 { 2037 /* the size of an empty FID is 38 but needs to be a multiple of 4 */ 2038 int fidsize = 40; 2039 2040 udf_inittag(&fid->tag, TAGID_FID, udf_rw32(parent->loc.lb_num)); 2041 fid->file_version_num = udf_rw16(1); /* UDF 2.3.4.1 */ 2042 fid->file_char = UDF_FILE_CHAR_DIR | UDF_FILE_CHAR_PAR; 2043 fid->icb = *parent; 2044 fid->icb.longad_uniqueid = parent->longad_uniqueid; 2045 fid->tag.desc_crc_len = udf_rw16(fidsize - UDF_DESC_TAG_LENGTH); 2046 2047 /* we have to do the fid here explicitly for simplicity */ 2048 udf_validate_tag_and_crc_sums((union dscrptr *) fid); 2049 2050 return fidsize; 2051 } 2052 2053 2054 void 2055 udf_create_fid(uint32_t diroff, struct fileid_desc *fid, char *name, 2056 int file_char, struct long_ad *ref) 2057 { 2058 struct charspec osta_charspec; 2059 uint32_t endfid; 2060 uint32_t fidsize, lb_rest; 2061 2062 memset(fid, 0, sizeof(*fid)); 2063 udf_inittag(&fid->tag, TAGID_FID, udf_rw32(ref->loc.lb_num)); 2064 fid->file_version_num = udf_rw16(1); /* UDF 2.3.4.1 */ 2065 fid->file_char = file_char; 2066 fid->l_iu = udf_rw16(0); 2067 fid->icb = *ref; 2068 fid->icb.longad_uniqueid = ref->longad_uniqueid; 2069 2070 udf_osta_charset(&osta_charspec); 2071 unix_to_udf_name((char *) fid->data, &fid->l_fi, name, strlen(name), 2072 &osta_charspec); 2073 2074 /* 2075 * OK, tricky part: we need to pad so the next descriptor header won't 2076 * cross the sector boundary 2077 */ 2078 endfid = diroff + udf_fidsize(fid); 2079 lb_rest = context.sector_size - (endfid % context.sector_size); 2080 if (lb_rest < sizeof(struct desc_tag)) { 2081 /* add at least 32 */ 2082 fid->l_iu = udf_rw16(32); 2083 udf_set_regid((struct regid *) fid->data, context.impl_name); 2084 udf_add_impl_regid((struct regid *) fid->data); 2085 2086 unix_to_udf_name((char *) fid->data + udf_rw16(fid->l_iu), 2087 &fid->l_fi, name, strlen(name), &osta_charspec); 2088 } 2089 2090 fidsize = udf_fidsize(fid); 2091 fid->tag.desc_crc_len = udf_rw16(fidsize - UDF_DESC_TAG_LENGTH); 2092 2093 /* make sure the header sums stays correct */ 2094 udf_validate_tag_and_crc_sums((union dscrptr *)fid); 2095 } 2096 2097 2098 static void 2099 udf_append_parentfid(union dscrptr *dscr, struct long_ad *parent_icb) 2100 { 2101 struct file_entry *fe; 2102 struct extfile_entry *efe; 2103 struct fileid_desc *fid; 2104 uint32_t l_ea; 2105 uint32_t fidsize, crclen; 2106 uint8_t *bpos, *data; 2107 2108 fe = NULL; 2109 efe = NULL; 2110 if (udf_rw16(dscr->tag.id) == TAGID_FENTRY) { 2111 fe = &dscr->fe; 2112 data = fe->data; 2113 l_ea = udf_rw32(fe->l_ea); 2114 } else if (udf_rw16(dscr->tag.id) == TAGID_EXTFENTRY) { 2115 efe = &dscr->efe; 2116 data = efe->data; 2117 l_ea = udf_rw32(efe->l_ea); 2118 } else { 2119 errx(1, "internal error, bad tag in %s", __func__); 2120 } 2121 2122 /* create '..' */ 2123 bpos = data + l_ea; 2124 fid = (struct fileid_desc *) bpos; 2125 fidsize = udf_create_parentfid(fid, parent_icb); 2126 2127 /* record fidlength information */ 2128 if (fe) { 2129 fe->inf_len = udf_rw64(fidsize); 2130 fe->l_ad = udf_rw32(fidsize); 2131 fe->logblks_rec = udf_rw64(0); /* intern */ 2132 crclen = sizeof(struct file_entry); 2133 } else { 2134 efe->inf_len = udf_rw64(fidsize); 2135 efe->obj_size = udf_rw64(fidsize); 2136 efe->l_ad = udf_rw32(fidsize); 2137 efe->logblks_rec = udf_rw64(0); /* intern */ 2138 crclen = sizeof(struct extfile_entry); 2139 } 2140 crclen -= 1 + UDF_DESC_TAG_LENGTH; 2141 crclen += l_ea + fidsize; 2142 dscr->tag.desc_crc_len = udf_rw16(crclen); 2143 2144 /* make sure the header sums stays correct */ 2145 udf_validate_tag_and_crc_sums(dscr); 2146 } 2147 2148 /* --------------------------------------------------------------------- */ 2149 2150 /* 2151 * Extended attribute support. UDF knows of 3 places for extended attributes: 2152 * 2153 * (a) inside the file's (e)fe in the length of the extended attribute area 2154 * before the allocation descriptors/filedata 2155 * 2156 * (b) in a file referenced by (e)fe->ext_attr_icb and 2157 * 2158 * (c) in the e(fe)'s associated stream directory that can hold various 2159 * sub-files. In the stream directory a few fixed named subfiles are reserved 2160 * for NT/Unix ACL's and OS/2 attributes. 2161 * 2162 * NOTE: Extended attributes are read randomly but always written 2163 * *atomically*. For ACL's this interface is probably different but not known 2164 * to me yet. 2165 * 2166 * Order of extended attributes in a space: 2167 * ECMA 167 EAs 2168 * Non block aligned Implementation Use EAs 2169 * Block aligned Implementation Use EAs 2170 * Application Use EAs 2171 */ 2172 2173 int 2174 udf_impl_extattr_check(struct impl_extattr_entry *implext) 2175 { 2176 uint16_t *spos; 2177 2178 if (strncmp((char *) implext->imp_id.id, "*UDF", 4) == 0) { 2179 /* checksum valid? */ 2180 spos = (uint16_t *) implext->data; 2181 if (udf_rw16(*spos) != udf_ea_cksum((uint8_t *) implext)) 2182 return EINVAL; 2183 } 2184 return 0; 2185 } 2186 2187 void 2188 udf_calc_impl_extattr_checksum(struct impl_extattr_entry *implext) 2189 { 2190 uint16_t *spos; 2191 2192 if (strncmp((char *) implext->imp_id.id, "*UDF", 4) == 0) { 2193 /* set checksum */ 2194 spos = (uint16_t *) implext->data; 2195 *spos = udf_rw16(udf_ea_cksum((uint8_t *) implext)); 2196 } 2197 } 2198 2199 2200 int 2201 udf_extattr_search_intern(union dscrptr *dscr, 2202 uint32_t sattr, char const *sattrname, 2203 uint32_t *offsetp, uint32_t *lengthp) 2204 { 2205 struct extattrhdr_desc *eahdr; 2206 struct extattr_entry *attrhdr; 2207 struct impl_extattr_entry *implext; 2208 uint32_t offset, a_l, sector_size; 2209 uint32_t l_ea; 2210 uint8_t *pos; 2211 int tag_id, error; 2212 2213 sector_size = context.sector_size; 2214 2215 /* get information from fe/efe */ 2216 tag_id = udf_rw16(dscr->tag.id); 2217 if (tag_id == TAGID_FENTRY) { 2218 l_ea = udf_rw32(dscr->fe.l_ea); 2219 eahdr = (struct extattrhdr_desc *) dscr->fe.data; 2220 } else { 2221 assert(tag_id == TAGID_EXTFENTRY); 2222 l_ea = udf_rw32(dscr->efe.l_ea); 2223 eahdr = (struct extattrhdr_desc *) dscr->efe.data; 2224 } 2225 2226 /* something recorded here? */ 2227 if (l_ea == 0) 2228 return ENOENT; 2229 2230 /* check extended attribute tag; what to do if it fails? */ 2231 error = udf_check_tag(eahdr); 2232 if (error) 2233 return EINVAL; 2234 if (udf_rw16(eahdr->tag.id) != TAGID_EXTATTR_HDR) 2235 return EINVAL; 2236 error = udf_check_tag_payload(eahdr, sizeof(struct extattrhdr_desc)); 2237 if (error) 2238 return EINVAL; 2239 2240 /* looking for Ecma-167 attributes? */ 2241 offset = sizeof(struct extattrhdr_desc); 2242 2243 /* looking for either implementation use or application use */ 2244 if (sattr == 2048) { /* [4/48.10.8] */ 2245 offset = udf_rw32(eahdr->impl_attr_loc); 2246 if (offset == UDF_IMPL_ATTR_LOC_NOT_PRESENT) 2247 return ENOENT; 2248 } 2249 if (sattr == 65536) { /* [4/48.10.9] */ 2250 offset = udf_rw32(eahdr->appl_attr_loc); 2251 if (offset == UDF_APPL_ATTR_LOC_NOT_PRESENT) 2252 return ENOENT; 2253 } 2254 2255 /* paranoia check offset and l_ea */ 2256 if (l_ea + offset >= sector_size - sizeof(struct extattr_entry)) 2257 return EINVAL; 2258 2259 /* find our extended attribute */ 2260 l_ea -= offset; 2261 pos = (uint8_t *) eahdr + offset; 2262 2263 while (l_ea >= sizeof(struct extattr_entry)) { 2264 attrhdr = (struct extattr_entry *) pos; 2265 implext = (struct impl_extattr_entry *) pos; 2266 2267 /* get complete attribute length and check for roque values */ 2268 a_l = udf_rw32(attrhdr->a_l); 2269 if ((a_l == 0) || (a_l > l_ea)) 2270 return EINVAL; 2271 2272 if (udf_rw32(attrhdr->type) != sattr) 2273 goto next_attribute; 2274 2275 /* we might have found it! */ 2276 if (udf_rw32(attrhdr->type) < 2048) { /* Ecma-167 attribute */ 2277 *offsetp = offset; 2278 *lengthp = a_l; 2279 return 0; /* success */ 2280 } 2281 2282 /* 2283 * Implementation use and application use extended attributes 2284 * have a name to identify. They share the same structure only 2285 * UDF implementation use extended attributes have a checksum 2286 * we need to check 2287 */ 2288 2289 if (strcmp((char *) implext->imp_id.id, sattrname) == 0) { 2290 /* we have found our appl/implementation attribute */ 2291 *offsetp = offset; 2292 *lengthp = a_l; 2293 return 0; /* success */ 2294 } 2295 2296 next_attribute: 2297 /* next attribute */ 2298 pos += a_l; 2299 l_ea -= a_l; 2300 offset += a_l; 2301 } 2302 /* not found */ 2303 return ENOENT; 2304 } 2305 2306 2307 static void 2308 udf_extattr_insert_internal(union dscrptr *dscr, struct extattr_entry *extattr) 2309 { 2310 struct file_entry *fe; 2311 struct extfile_entry *efe; 2312 struct extattrhdr_desc *extattrhdr; 2313 struct impl_extattr_entry *implext; 2314 uint32_t impl_attr_loc, appl_attr_loc, l_ea, l_ad, a_l; 2315 uint16_t *spos; 2316 uint8_t *bpos, *data; 2317 void *l_eap; 2318 2319 if (udf_rw16(dscr->tag.id) == TAGID_FENTRY) { 2320 fe = &dscr->fe; 2321 data = fe->data; 2322 l_eap = &fe->l_ea; 2323 l_ad = udf_rw32(fe->l_ad); 2324 } else if (udf_rw16(dscr->tag.id) == TAGID_EXTFENTRY) { 2325 efe = &dscr->efe; 2326 data = efe->data; 2327 l_eap = &efe->l_ea; 2328 l_ad = udf_rw32(efe->l_ad); 2329 } else { 2330 errx(1, "internal error, bad tag in %s", __func__); 2331 } 2332 2333 /* should have a header! */ 2334 extattrhdr = (struct extattrhdr_desc *) data; 2335 memcpy(&l_ea, l_eap, sizeof(l_ea)); 2336 l_ea = udf_rw32(l_ea); 2337 if (l_ea == 0) { 2338 uint32_t exthdr_len; 2339 assert(l_ad == 0); 2340 /* create empty extended attribute header */ 2341 l_ea = sizeof(struct extattrhdr_desc); 2342 exthdr_len = udf_rw32(l_ea); 2343 2344 udf_inittag(&extattrhdr->tag, TAGID_EXTATTR_HDR, /* loc */ 0); 2345 extattrhdr->impl_attr_loc = exthdr_len; 2346 extattrhdr->appl_attr_loc = exthdr_len; 2347 extattrhdr->tag.desc_crc_len = udf_rw16(8); 2348 2349 /* record extended attribute header length */ 2350 memcpy(l_eap, &exthdr_len, sizeof(exthdr_len)); 2351 } 2352 2353 /* extract locations */ 2354 impl_attr_loc = udf_rw32(extattrhdr->impl_attr_loc); 2355 appl_attr_loc = udf_rw32(extattrhdr->appl_attr_loc); 2356 if (impl_attr_loc == UDF_IMPL_ATTR_LOC_NOT_PRESENT) 2357 impl_attr_loc = l_ea; 2358 if (appl_attr_loc == UDF_IMPL_ATTR_LOC_NOT_PRESENT) 2359 appl_attr_loc = l_ea; 2360 2361 /* Ecma 167 EAs */ 2362 if (udf_rw32(extattr->type) < 2048) { 2363 assert(impl_attr_loc == l_ea); 2364 assert(appl_attr_loc == l_ea); 2365 } 2366 2367 /* implementation use extended attributes */ 2368 if (udf_rw32(extattr->type) == 2048) { 2369 assert(appl_attr_loc == l_ea); 2370 2371 /* calculate and write extended attribute header checksum */ 2372 implext = (struct impl_extattr_entry *) extattr; 2373 assert(udf_rw32(implext->iu_l) == 4); /* [UDF 3.3.4.5] */ 2374 spos = (uint16_t *) implext->data; 2375 *spos = udf_rw16(udf_ea_cksum((uint8_t *) implext)); 2376 } 2377 2378 /* application use extended attributes */ 2379 assert(udf_rw32(extattr->type) != 65536); 2380 assert(appl_attr_loc == l_ea); 2381 2382 /* append the attribute at the end of the current space */ 2383 bpos = data + l_ea; 2384 a_l = udf_rw32(extattr->a_l); 2385 2386 /* update impl. attribute locations */ 2387 if (udf_rw32(extattr->type) < 2048) { 2388 impl_attr_loc = l_ea + a_l; 2389 appl_attr_loc = l_ea + a_l; 2390 } 2391 if (udf_rw32(extattr->type) == 2048) { 2392 appl_attr_loc = l_ea + a_l; 2393 } 2394 2395 /* copy and advance */ 2396 memcpy(bpos, extattr, a_l); 2397 l_ea += a_l; 2398 l_ea = udf_rw32(l_ea); 2399 memcpy(l_eap, &l_ea, sizeof(l_ea)); 2400 2401 /* do the `dance` again backwards */ 2402 if (context.dscrver != 2) { 2403 if (impl_attr_loc == l_ea) 2404 impl_attr_loc = UDF_IMPL_ATTR_LOC_NOT_PRESENT; 2405 if (appl_attr_loc == l_ea) 2406 appl_attr_loc = UDF_APPL_ATTR_LOC_NOT_PRESENT; 2407 } 2408 2409 /* store offsets */ 2410 extattrhdr->impl_attr_loc = udf_rw32(impl_attr_loc); 2411 extattrhdr->appl_attr_loc = udf_rw32(appl_attr_loc); 2412 2413 /* make sure the header sums stays correct */ 2414 udf_validate_tag_and_crc_sums((union dscrptr *) extattrhdr); 2415 } 2416 2417 /* --------------------------------------------------------------------- */ 2418 2419 int 2420 udf_create_new_fe(struct file_entry **fep, int file_type, struct stat *st) 2421 { 2422 struct file_entry *fe; 2423 struct icb_tag *icb; 2424 struct timestamp birthtime; 2425 struct filetimes_extattr_entry *ft_extattr; 2426 uint32_t crclen; /* XXX: should be 16; need to detect overflow */ 2427 uint16_t icbflags; 2428 2429 *fep = NULL; 2430 fe = calloc(1, context.sector_size); 2431 if (fe == NULL) 2432 return ENOMEM; 2433 2434 udf_inittag(&fe->tag, TAGID_FENTRY, /* loc */ 0); 2435 icb = &fe->icbtag; 2436 2437 /* 2438 * Always use strategy type 4 unless on WORM which we don't support 2439 * (yet). Fill in defaults and set for internal allocation of data. 2440 */ 2441 icb->strat_type = udf_rw16(4); 2442 icb->max_num_entries = udf_rw16(1); 2443 icb->file_type = file_type; /* 8 bit */ 2444 icb->flags = udf_rw16(UDF_ICB_INTERN_ALLOC); 2445 2446 fe->perm = udf_rw32(0x7fff); /* all is allowed */ 2447 fe->link_cnt = udf_rw16(0); /* explicit setting */ 2448 2449 fe->ckpoint = udf_rw32(1); /* user supplied file version */ 2450 2451 udf_set_timestamp_now(&birthtime); 2452 udf_set_timestamp_now(&fe->atime); 2453 udf_set_timestamp_now(&fe->attrtime); 2454 udf_set_timestamp_now(&fe->mtime); 2455 2456 /* set attributes */ 2457 if (st) { 2458 #if !HAVE_NBTOOL_CONFIG_H 2459 udf_set_timestamp(&birthtime, st->st_birthtime); 2460 #else 2461 udf_set_timestamp(&birthtime, 0); 2462 #endif 2463 udf_set_timestamp(&fe->atime, st->st_atime); 2464 udf_set_timestamp(&fe->attrtime, st->st_ctime); 2465 udf_set_timestamp(&fe->mtime, st->st_mtime); 2466 fe->uid = udf_rw32(st->st_uid); 2467 fe->gid = udf_rw32(st->st_gid); 2468 2469 fe->perm = udf_rw32(unix_mode_to_udf_perm(st->st_mode)); 2470 2471 icbflags = udf_rw16(fe->icbtag.flags); 2472 icbflags &= ~UDF_ICB_TAG_FLAGS_SETUID; 2473 icbflags &= ~UDF_ICB_TAG_FLAGS_SETGID; 2474 icbflags &= ~UDF_ICB_TAG_FLAGS_STICKY; 2475 if (st->st_mode & S_ISUID) 2476 icbflags |= UDF_ICB_TAG_FLAGS_SETUID; 2477 if (st->st_mode & S_ISGID) 2478 icbflags |= UDF_ICB_TAG_FLAGS_SETGID; 2479 if (st->st_mode & S_ISVTX) 2480 icbflags |= UDF_ICB_TAG_FLAGS_STICKY; 2481 fe->icbtag.flags = udf_rw16(icbflags); 2482 } 2483 2484 udf_set_regid(&fe->imp_id, context.impl_name); 2485 udf_add_impl_regid(&fe->imp_id); 2486 fe->unique_id = udf_rw64(context.unique_id); 2487 udf_advance_uniqueid(); 2488 2489 fe->l_ea = udf_rw32(0); 2490 2491 /* create extended attribute to record our creation time */ 2492 ft_extattr = calloc(1, UDF_FILETIMES_ATTR_SIZE(1)); 2493 ft_extattr->hdr.type = udf_rw32(UDF_FILETIMES_ATTR_NO); 2494 ft_extattr->hdr.subtype = 1; /* [4/48.10.5] */ 2495 ft_extattr->hdr.a_l = udf_rw32(UDF_FILETIMES_ATTR_SIZE(1)); 2496 ft_extattr->d_l = udf_rw32(UDF_TIMESTAMP_SIZE); /* one item */ 2497 ft_extattr->existence = UDF_FILETIMES_FILE_CREATION; 2498 ft_extattr->times[0] = birthtime; 2499 2500 udf_extattr_insert_internal((union dscrptr *) fe, 2501 (struct extattr_entry *) ft_extattr); 2502 free(ft_extattr); 2503 2504 /* record fidlength information */ 2505 fe->inf_len = udf_rw64(0); 2506 fe->l_ad = udf_rw32(0); 2507 fe->logblks_rec = udf_rw64(0); /* intern */ 2508 2509 crclen = sizeof(struct file_entry) - 1 - UDF_DESC_TAG_LENGTH; 2510 crclen += udf_rw32(fe->l_ea); 2511 2512 /* make sure the header sums stays correct */ 2513 fe->tag.desc_crc_len = udf_rw16(crclen); 2514 udf_validate_tag_and_crc_sums((union dscrptr *) fe); 2515 2516 *fep = fe; 2517 return 0; 2518 } 2519 2520 2521 int 2522 udf_create_new_efe(struct extfile_entry **efep, int file_type, struct stat *st) 2523 { 2524 struct extfile_entry *efe; 2525 struct icb_tag *icb; 2526 uint32_t crclen; /* XXX: should be 16; need to detect overflow */ 2527 uint16_t icbflags; 2528 2529 *efep = NULL; 2530 efe = calloc(1, context.sector_size); 2531 if (efe == NULL) 2532 return ENOMEM; 2533 2534 udf_inittag(&efe->tag, TAGID_EXTFENTRY, /* loc */ 0); 2535 icb = &efe->icbtag; 2536 2537 /* 2538 * Always use strategy type 4 unless on WORM which we don't support 2539 * (yet). Fill in defaults and set for internal allocation of data. 2540 */ 2541 icb->strat_type = udf_rw16(4); 2542 icb->max_num_entries = udf_rw16(1); 2543 icb->file_type = file_type; /* 8 bit */ 2544 icb->flags = udf_rw16(UDF_ICB_INTERN_ALLOC); 2545 2546 efe->perm = udf_rw32(0x7fff); /* all is allowed */ 2547 efe->link_cnt = udf_rw16(0); /* explicit setting */ 2548 2549 efe->ckpoint = udf_rw32(1); /* user supplied file version */ 2550 2551 udf_set_timestamp_now(&efe->ctime); 2552 udf_set_timestamp_now(&efe->atime); 2553 udf_set_timestamp_now(&efe->attrtime); 2554 udf_set_timestamp_now(&efe->mtime); 2555 2556 /* set attributes */ 2557 if (st) { 2558 #if !HAVE_NBTOOL_CONFIG_H 2559 udf_set_timestamp(&efe->ctime, st->st_birthtime); 2560 #else 2561 udf_set_timestamp(&efe->ctime, 0); 2562 #endif 2563 udf_set_timestamp(&efe->atime, st->st_atime); 2564 udf_set_timestamp(&efe->attrtime, st->st_ctime); 2565 udf_set_timestamp(&efe->mtime, st->st_mtime); 2566 efe->uid = udf_rw32(st->st_uid); 2567 efe->gid = udf_rw32(st->st_gid); 2568 2569 efe->perm = udf_rw32(unix_mode_to_udf_perm(st->st_mode)); 2570 2571 icbflags = udf_rw16(efe->icbtag.flags); 2572 icbflags &= ~UDF_ICB_TAG_FLAGS_SETUID; 2573 icbflags &= ~UDF_ICB_TAG_FLAGS_SETGID; 2574 icbflags &= ~UDF_ICB_TAG_FLAGS_STICKY; 2575 if (st->st_mode & S_ISUID) 2576 icbflags |= UDF_ICB_TAG_FLAGS_SETUID; 2577 if (st->st_mode & S_ISGID) 2578 icbflags |= UDF_ICB_TAG_FLAGS_SETGID; 2579 if (st->st_mode & S_ISVTX) 2580 icbflags |= UDF_ICB_TAG_FLAGS_STICKY; 2581 efe->icbtag.flags = udf_rw16(icbflags); 2582 } 2583 2584 udf_set_regid(&efe->imp_id, context.impl_name); 2585 udf_add_impl_regid(&efe->imp_id); 2586 2587 efe->unique_id = udf_rw64(context.unique_id); 2588 udf_advance_uniqueid(); 2589 2590 /* record fidlength information */ 2591 efe->inf_len = udf_rw64(0); 2592 efe->obj_size = udf_rw64(0); 2593 efe->l_ad = udf_rw32(0); 2594 efe->logblks_rec = udf_rw64(0); 2595 2596 crclen = sizeof(struct extfile_entry) - 1 - UDF_DESC_TAG_LENGTH; 2597 2598 /* make sure the header sums stays correct */ 2599 efe->tag.desc_crc_len = udf_rw16(crclen); 2600 udf_validate_tag_and_crc_sums((union dscrptr *) efe); 2601 2602 *efep = efe; 2603 return 0; 2604 } 2605 2606 /* --------------------------------------------------------------------- */ 2607 2608 /* for METADATA file appending only */ 2609 static void 2610 udf_append_meta_mapping_part_to_efe(struct extfile_entry *efe, 2611 struct short_ad *mapping) 2612 { 2613 struct icb_tag *icb; 2614 uint64_t inf_len, obj_size, logblks_rec; 2615 uint32_t l_ad, l_ea; 2616 uint16_t crclen; 2617 uintptr_t bpos; 2618 2619 inf_len = udf_rw64(efe->inf_len); 2620 obj_size = udf_rw64(efe->obj_size); 2621 logblks_rec = udf_rw64(efe->logblks_rec); 2622 l_ad = udf_rw32(efe->l_ad); 2623 l_ea = udf_rw32(efe->l_ea); 2624 crclen = udf_rw16(efe->tag.desc_crc_len); 2625 icb = &efe->icbtag; 2626 2627 /* set our allocation to shorts if not already done */ 2628 icb->flags = udf_rw16(UDF_ICB_SHORT_ALLOC); 2629 2630 /* append short_ad */ 2631 bpos = (uintptr_t)efe->data + l_ea + l_ad; 2632 memcpy((void *)bpos, mapping, sizeof(struct short_ad)); 2633 2634 l_ad += sizeof(struct short_ad); 2635 crclen += sizeof(struct short_ad); 2636 inf_len += UDF_EXT_LEN(udf_rw32(mapping->len)); 2637 obj_size += UDF_EXT_LEN(udf_rw32(mapping->len)); 2638 logblks_rec = UDF_ROUNDUP(inf_len, context.sector_size) / 2639 context.sector_size; 2640 2641 efe->l_ad = udf_rw32(l_ad); 2642 efe->inf_len = udf_rw64(inf_len); 2643 efe->obj_size = udf_rw64(obj_size); 2644 efe->logblks_rec = udf_rw64(logblks_rec); 2645 efe->tag.desc_crc_len = udf_rw16(crclen); 2646 } 2647 2648 2649 /* for METADATA file appending only */ 2650 static void 2651 udf_append_meta_mapping_to_efe(struct extfile_entry *efe, 2652 uint16_t partnr, uint32_t lb_num, 2653 uint64_t len) 2654 { 2655 struct short_ad mapping; 2656 uint64_t max_len, part_len; 2657 2658 /* calculate max length meta allocation sizes */ 2659 max_len = UDF_EXT_MAXLEN / context.sector_size; /* in sectors */ 2660 max_len = (max_len / layout.meta_blockingnr) * layout.meta_blockingnr; 2661 max_len = max_len * context.sector_size; 2662 2663 memset(&mapping, 0, sizeof(mapping)); 2664 while (len) { 2665 part_len = MIN(len, max_len); 2666 mapping.lb_num = udf_rw32(lb_num); 2667 mapping.len = udf_rw32(part_len); 2668 2669 udf_append_meta_mapping_part_to_efe(efe, &mapping); 2670 2671 lb_num += part_len / context.sector_size; 2672 len -= part_len; 2673 } 2674 } 2675 2676 2677 int 2678 udf_create_meta_files(void) 2679 { 2680 struct extfile_entry *efe; 2681 struct long_ad meta_icb; 2682 uint64_t bytes; 2683 uint32_t sector_size; 2684 int filetype, error; 2685 2686 sector_size = context.sector_size; 2687 2688 memset(&meta_icb, 0, sizeof(meta_icb)); 2689 meta_icb.len = udf_rw32(sector_size); 2690 meta_icb.loc.part_num = udf_rw16(context.data_part); 2691 2692 /* create metadata file */ 2693 meta_icb.loc.lb_num = udf_rw32(layout.meta_file); 2694 filetype = UDF_ICB_FILETYPE_META_MAIN; 2695 error = udf_create_new_efe(&efe, filetype, NULL); 2696 if (error) 2697 return error; 2698 context.meta_file = efe; 2699 context.meta_file->unique_id = udf_rw64(0); 2700 2701 /* create metadata mirror file */ 2702 meta_icb.loc.lb_num = udf_rw32(layout.meta_mirror); 2703 filetype = UDF_ICB_FILETYPE_META_MIRROR; 2704 error = udf_create_new_efe(&efe, filetype, NULL); 2705 if (error) 2706 return error; 2707 context.meta_mirror = efe; 2708 context.meta_mirror->unique_id = udf_rw64(0); 2709 2710 if (!(context.format_flags & FORMAT_READONLY)) { 2711 /* create metadata bitmap file */ 2712 meta_icb.loc.lb_num = udf_rw32(layout.meta_bitmap); 2713 filetype = UDF_ICB_FILETYPE_META_BITMAP; 2714 error = udf_create_new_efe(&efe, filetype, NULL); 2715 if (error) 2716 return error; 2717 context.meta_bitmap = efe; 2718 context.meta_bitmap->unique_id = udf_rw64(0); 2719 } 2720 2721 /* restart unique id */ 2722 context.unique_id = 0x10; 2723 2724 /* XXX no support for metadata mirroring yet */ 2725 /* insert extents */ 2726 efe = context.meta_file; 2727 udf_append_meta_mapping_to_efe(efe, context.data_part, 2728 layout.meta_part_start_lba, 2729 (uint64_t) layout.meta_part_size_lba * sector_size); 2730 2731 efe = context.meta_mirror; 2732 udf_append_meta_mapping_to_efe(efe, context.data_part, 2733 layout.meta_part_start_lba, 2734 (uint64_t) layout.meta_part_size_lba * sector_size); 2735 2736 if (context.meta_bitmap) { 2737 efe = context.meta_bitmap; 2738 bytes = udf_space_bitmap_len(layout.meta_part_size_lba); 2739 udf_append_meta_mapping_to_efe(efe, context.data_part, 2740 layout.meta_bitmap_space, bytes); 2741 } 2742 2743 return 0; 2744 } 2745 2746 2747 /* --------------------------------------------------------------------- */ 2748 2749 int 2750 udf_create_new_rootdir(union dscrptr **dscr) 2751 { 2752 struct file_entry *fe; 2753 struct extfile_entry *efe; 2754 struct long_ad root_icb; 2755 int filetype, error; 2756 2757 memset(&root_icb, 0, sizeof(root_icb)); 2758 root_icb.len = udf_rw32(context.sector_size); 2759 root_icb.loc.lb_num = udf_rw32(layout.rootdir); 2760 root_icb.loc.part_num = udf_rw16(context.metadata_part); 2761 2762 filetype = UDF_ICB_FILETYPE_DIRECTORY; 2763 if (context.dscrver == 2) { 2764 error = udf_create_new_fe(&fe, filetype, NULL); 2765 *dscr = (union dscrptr *) fe; 2766 } else { 2767 error = udf_create_new_efe(&efe, filetype, NULL); 2768 *dscr = (union dscrptr *) efe; 2769 } 2770 if (error) 2771 return error; 2772 2773 /* append '..' */ 2774 udf_append_parentfid(*dscr, &root_icb); 2775 2776 /* rootdir has explicit only one link on creation; '..' is no link */ 2777 if (context.dscrver == 2) { 2778 fe->link_cnt = udf_rw16(1); 2779 } else { 2780 efe->link_cnt = udf_rw16(1); 2781 } 2782 2783 context.num_directories++; 2784 assert(context.num_directories == 1); 2785 2786 return 0; 2787 } 2788 2789 2790 void 2791 udf_prepend_VAT_file(void) 2792 { 2793 /* old style VAT has no prepend */ 2794 if (context.dscrver == 2) { 2795 context.vat_start = 0; 2796 context.vat_size = 0; 2797 return; 2798 } 2799 2800 context.vat_start = offsetof(struct udf_vat, data); 2801 context.vat_size = offsetof(struct udf_vat, data); 2802 } 2803 2804 2805 void 2806 udf_vat_update(uint32_t virt, uint32_t phys) 2807 { 2808 uint32_t *vatpos; 2809 uint32_t new_size; 2810 2811 if (context.vtop_tp[context.metadata_part] != UDF_VTOP_TYPE_VIRT) 2812 return; 2813 2814 new_size = MAX(context.vat_size, 2815 (context.vat_start + (virt+1)*sizeof(uint32_t))); 2816 2817 if (new_size > context.vat_allocated) { 2818 context.vat_allocated = 2819 UDF_ROUNDUP(new_size, context.sector_size); 2820 context.vat_contents = realloc(context.vat_contents, 2821 context.vat_allocated); 2822 assert(context.vat_contents); 2823 /* XXX could also report error */ 2824 } 2825 vatpos = (uint32_t *) (context.vat_contents + context.vat_start); 2826 vatpos[virt] = udf_rw32(phys); 2827 2828 context.vat_size = MAX(context.vat_size, 2829 (context.vat_start + (virt+1)*sizeof(uint32_t))); 2830 } 2831 2832 2833 int 2834 udf_append_VAT_file(void) 2835 { 2836 struct udf_oldvat_tail *oldvat_tail; 2837 struct udf_vat *vathdr; 2838 int32_t len_diff; 2839 2840 /* new style VAT has VAT LVInt analog in front */ 2841 if (context.dscrver == 3) { 2842 /* set up VATv2 descriptor */ 2843 vathdr = (struct udf_vat *) context.vat_contents; 2844 vathdr->header_len = udf_rw16(sizeof(struct udf_vat) - 1); 2845 vathdr->impl_use_len = udf_rw16(0); 2846 memcpy(vathdr->logvol_id, context.logical_vol->logvol_id, 128); 2847 vathdr->prev_vat = udf_rw32(UDF_NO_PREV_VAT); 2848 vathdr->num_files = udf_rw32(context.num_files); 2849 vathdr->num_directories = udf_rw32(context.num_directories); 2850 2851 vathdr->min_udf_readver = udf_rw16(context.min_udf); 2852 vathdr->min_udf_writever = udf_rw16(context.min_udf); 2853 vathdr->max_udf_writever = udf_rw16(context.max_udf); 2854 2855 return 0; 2856 } 2857 2858 /* old style VAT has identifier appended */ 2859 2860 /* append "*UDF Virtual Alloc Tbl" id and prev. VAT location */ 2861 len_diff = context.vat_allocated - context.vat_size; 2862 assert(len_diff >= 0); 2863 if (len_diff < (int32_t) sizeof(struct udf_oldvat_tail)) { 2864 context.vat_allocated += context.sector_size; 2865 context.vat_contents = realloc(context.vat_contents, 2866 context.vat_allocated); 2867 assert(context.vat_contents); 2868 /* XXX could also report error */ 2869 } 2870 2871 oldvat_tail = (struct udf_oldvat_tail *) (context.vat_contents + 2872 context.vat_size); 2873 2874 udf_set_regid(&oldvat_tail->id, "*UDF Virtual Alloc Tbl"); 2875 udf_add_udf_regid(&oldvat_tail->id); 2876 oldvat_tail->prev_vat = udf_rw32(UDF_NO_PREV_VAT); 2877 2878 context.vat_size += sizeof(struct udf_oldvat_tail); 2879 2880 return 0; 2881 } 2882 2883 2884 int 2885 udf_create_VAT(union dscrptr **vat_dscr, struct long_ad *vatdata_loc) 2886 { 2887 struct impl_extattr_entry *implext; 2888 struct vatlvext_extattr_entry *vatlvext; 2889 struct long_ad *allocpos; 2890 uint8_t *bpos, *extattr; 2891 uint32_t ea_len, inf_len, vat_len, blks; 2892 int filetype; 2893 int error; 2894 2895 assert((layout.rootdir < 2) && (layout.fsd < 2)); 2896 2897 if (context.dscrver == 2) { 2898 struct file_entry *fe; 2899 2900 /* old style VAT */ 2901 filetype = UDF_ICB_FILETYPE_UNKNOWN; 2902 error = udf_create_new_fe(&fe, filetype, NULL); 2903 if (error) 2904 return error; 2905 2906 /* append VAT LVExtension attribute */ 2907 ea_len = sizeof(struct impl_extattr_entry) - 2 + 4 + 2908 sizeof(struct vatlvext_extattr_entry); 2909 2910 extattr = calloc(1, ea_len); 2911 2912 implext = (struct impl_extattr_entry *) extattr; 2913 implext->hdr.type = udf_rw32(2048); /* [4/48.10.8] */ 2914 implext->hdr.subtype = 1; /* [4/48.10.8.2] */ 2915 implext->hdr.a_l = udf_rw32(ea_len); /* VAT LVext EA size */ 2916 /* use 4 bytes of imp use for UDF checksum [UDF 3.3.4.5] */ 2917 implext->iu_l = udf_rw32(4); 2918 udf_set_regid(&implext->imp_id, "*UDF VAT LVExtension"); 2919 udf_add_udf_regid(&implext->imp_id); 2920 2921 /* VAT LVExtension data follows UDF IU space */ 2922 bpos = ((uint8_t *) implext->data) + 4; 2923 vatlvext = (struct vatlvext_extattr_entry *) bpos; 2924 2925 vatlvext->unique_id_chk = fe->unique_id; 2926 vatlvext->num_files = udf_rw32(context.num_files); 2927 vatlvext->num_directories = udf_rw32(context.num_directories); 2928 memcpy(vatlvext->logvol_id, context.logical_vol->logvol_id,128); 2929 2930 udf_extattr_insert_internal((union dscrptr *) fe, 2931 (struct extattr_entry *) extattr); 2932 2933 free(extattr); 2934 2935 fe->icbtag.flags = udf_rw16(UDF_ICB_LONG_ALLOC); 2936 2937 allocpos = (struct long_ad *) (fe->data + udf_rw32(fe->l_ea)); 2938 *allocpos = *vatdata_loc; 2939 2940 /* set length */ 2941 inf_len = context.vat_size; 2942 fe->inf_len = udf_rw64(inf_len); 2943 allocpos->len = udf_rw32(inf_len); 2944 fe->l_ad = udf_rw32(sizeof(struct long_ad)); 2945 blks = UDF_ROUNDUP(inf_len, context.sector_size) / 2946 context.sector_size; 2947 fe->logblks_rec = udf_rw64(blks); 2948 2949 /* update vat descriptor's CRC length */ 2950 vat_len = sizeof(struct file_entry) - 1 - UDF_DESC_TAG_LENGTH; 2951 vat_len += udf_rw32(fe->l_ad) + udf_rw32(fe->l_ea); 2952 fe->tag.desc_crc_len = udf_rw16(vat_len); 2953 2954 *vat_dscr = (union dscrptr *) fe; 2955 } else { 2956 /* the choice is between an EFE or an FE as VAT */ 2957 #if 1 2958 struct extfile_entry *efe; 2959 2960 /* new style VAT on FE */ 2961 filetype = UDF_ICB_FILETYPE_VAT; 2962 error = udf_create_new_efe(&efe, filetype, NULL); 2963 if (error) 2964 return error; 2965 2966 efe->icbtag.flags = udf_rw16(UDF_ICB_LONG_ALLOC); 2967 2968 allocpos = (struct long_ad *) efe->data; 2969 *allocpos = *vatdata_loc; 2970 2971 /* set length */ 2972 inf_len = context.vat_size; 2973 efe->inf_len = udf_rw64(inf_len); 2974 allocpos->len = udf_rw32(inf_len); 2975 efe->obj_size = udf_rw64(inf_len); 2976 efe->l_ad = udf_rw32(sizeof(struct long_ad)); 2977 blks = UDF_ROUNDUP(inf_len, context.sector_size) / 2978 context.sector_size; 2979 efe->logblks_rec = udf_rw64(blks); 2980 2981 vat_len = sizeof(struct extfile_entry)-1 - UDF_DESC_TAG_LENGTH; 2982 vat_len += udf_rw32(efe->l_ad); 2983 efe->tag.desc_crc_len = udf_rw16(vat_len); 2984 2985 *vat_dscr = (union dscrptr *) efe; 2986 #else 2987 struct file_entry *fe; 2988 uint32_t l_ea; 2989 2990 /* new style VAT on EFE */ 2991 filetype = UDF_ICB_FILETYPE_VAT; 2992 error = udf_create_new_fe(&fe, filetype, NULL); 2993 if (error) 2994 return error; 2995 2996 fe->icbtag.flags = udf_rw16(UDF_ICB_LONG_ALLOC); 2997 2998 l_ea = udf_rw32(fe->l_ea); 2999 allocpos = (struct long_ad *) (fe->data + l_ea); 3000 *allocpos = *vatdata_loc; 3001 3002 /* set length */ 3003 inf_len = context.vat_size; 3004 fe->inf_len = udf_rw64(inf_len); 3005 allocpos->len = udf_rw32(inf_len); 3006 fe->l_ad = udf_rw32(sizeof(struct long_ad)); 3007 blks = UDF_ROUNDUP(inf_len, context.sector_size) / 3008 context.sector_size; 3009 fe->logblks_rec = udf_rw64(blks); 3010 3011 vat_len = sizeof(struct file_entry)-1 - UDF_DESC_TAG_LENGTH; 3012 vat_len += udf_rw32(fe->l_ad) + udf_rw32(fe->l_ea); 3013 fe->tag.desc_crc_len = udf_rw16(vat_len); 3014 3015 *vat_dscr = (union dscrptr *) fe; 3016 #endif 3017 } 3018 3019 return 0; 3020 } 3021 3022 3023 int 3024 udf_writeout_VAT(void) 3025 { 3026 union dscrptr *vat_dscr; 3027 struct long_ad vatdata; 3028 uint32_t loc, phys, ext, sects; 3029 int rel_block, rest_block, error; 3030 3031 vat_dscr = NULL; 3032 /* update lvint to reflect the newest values (no writeout) */ 3033 udf_update_lvintd(UDF_INTEGRITY_CLOSED); 3034 3035 error = udf_append_VAT_file(); 3036 if (error) 3037 return error; 3038 3039 /* write out VAT data */ 3040 sects = UDF_ROUNDUP(context.vat_size, context.sector_size) / 3041 context.sector_size; 3042 layout.vat = context.alloc_pos[context.data_part]; 3043 udf_data_alloc(sects, &vatdata); 3044 //printf("layout.vat %d\n", layout.vat + udf_rw32(context.partitions[context.data_part]->start_loc)); 3045 3046 loc = udf_rw32(vatdata.loc.lb_num); 3047 udf_translate_vtop(loc, context.data_part, &phys, &ext); 3048 3049 error = udf_write_phys(context.vat_contents, phys, sects); 3050 if (error) 3051 return error; 3052 loc += sects; 3053 3054 /* create new VAT descriptor */ 3055 error = udf_create_VAT(&vat_dscr, &vatdata); 3056 if (error) 3057 return error; 3058 3059 //printf("VAT data at %d\n", vatdata.loc.lb_num); 3060 //printf("VAT itself at %d\n", loc + udf_rw32(context.partitions[context.data_part]->start_loc)); 3061 3062 /* at least one */ 3063 error = udf_write_dscr_virt(vat_dscr, loc, context.data_part, 1); 3064 loc++; 3065 3066 error = udf_translate_vtop(loc, context.data_part, &phys, &ext); 3067 assert(!error); 3068 3069 rel_block = phys - (UDF_ROUNDDOWN(phys, layout.blockingnr) + wrtrack_skew); 3070 rest_block = layout.blockingnr - rel_block; 3071 3072 for (int i = 0; i < rest_block; i++) { 3073 error = udf_write_dscr_virt(vat_dscr, loc, context.data_part, 1); 3074 loc++; 3075 } 3076 free(vat_dscr); 3077 3078 return error; 3079 } 3080 3081 3082 /* --------------------------------------------------------------------- */ 3083 /* 3084 * mmc_discinfo and mmc_trackinfo readers modified from original in udf main 3085 * code in sys/fs/udf/ 3086 */ 3087 3088 void 3089 udf_dump_discinfo(struct mmc_discinfo *di) 3090 { 3091 #ifdef DEBUG 3092 char bits[128]; 3093 3094 printf("Device/media info :\n"); 3095 printf("\tMMC profile 0x%02x\n", di->mmc_profile); 3096 printf("\tderived class %d\n", di->mmc_class); 3097 printf("\tsector size %d\n", di->sector_size); 3098 printf("\tdisc state %d\n", di->disc_state); 3099 printf("\tlast ses state %d\n", di->last_session_state); 3100 printf("\tbg format state %d\n", di->bg_format_state); 3101 printf("\tfrst track %d\n", di->first_track); 3102 printf("\tfst on last ses %d\n", di->first_track_last_session); 3103 printf("\tlst on last ses %d\n", di->last_track_last_session); 3104 printf("\tlink block penalty %d\n", di->link_block_penalty); 3105 snprintb(bits, sizeof(bits), MMC_DFLAGS_FLAGBITS, (uint64_t) di->disc_flags); 3106 printf("\tdisc flags %s\n", bits); 3107 printf("\tdisc id %x\n", di->disc_id); 3108 printf("\tdisc barcode %"PRIx64"\n", di->disc_barcode); 3109 3110 printf("\tnum sessions %d\n", di->num_sessions); 3111 printf("\tnum tracks %d\n", di->num_tracks); 3112 3113 snprintb(bits, sizeof(bits), MMC_CAP_FLAGBITS, di->mmc_cur); 3114 printf("\tcapabilities cur %s\n", bits); 3115 snprintb(bits, sizeof(bits), MMC_CAP_FLAGBITS, di->mmc_cap); 3116 printf("\tcapabilities cap %s\n", bits); 3117 printf("\n"); 3118 printf("\tlast_possible_lba %d\n", di->last_possible_lba); 3119 printf("\n"); 3120 #endif 3121 } 3122 3123 3124 void 3125 udf_synchronise_caches(void) 3126 { 3127 #if !HAVE_NBTOOL_CONFIG_H 3128 struct mmc_op mmc_op; 3129 3130 bzero(&mmc_op, sizeof(struct mmc_op)); 3131 mmc_op.operation = MMC_OP_SYNCHRONISECACHE; 3132 3133 /* this device might not know this ioct, so just be ignorant */ 3134 (void) ioctl(dev_fd, MMCOP, &mmc_op); 3135 #endif 3136 } 3137 3138 3139 /* 3140 * General Idea: 3141 * 3142 * stat the dev_fd 3143 * 3144 * If a S_ISREG(), we emulate using the emul_* settings. 3145 * 3146 * If its a device : 3147 * try the MMCGETDISCINFO ioctl() and be done. 3148 * 3149 * If that fails, its a regular disc and set the type to disc media. 3150 * 3151 */ 3152 3153 3154 int 3155 udf_update_discinfo(void) 3156 { 3157 off_t size, last_sector, secsize; 3158 int error; 3159 3160 memset(&mmc_discinfo, 0, sizeof(struct mmc_discinfo)); 3161 3162 #if !HAVE_NBTOOL_CONFIG_H 3163 /* check if we're on a MMC capable device, i.e. CD/DVD */ 3164 error = ioctl(dev_fd, MMCGETDISCINFO, &mmc_discinfo); 3165 if (error == 0) { 3166 if ((emul_mmc_profile != -1) && 3167 (emul_mmc_profile != mmc_discinfo.mmc_profile)) { 3168 errno = EINVAL; 3169 perror("media and specified disc type mismatch"); 3170 return errno; 3171 } 3172 emul_size = 0; 3173 return 0; 3174 } 3175 #endif 3176 3177 if (S_ISREG(dev_fd_stat.st_mode)) { 3178 /* file support; we pick the minimum sector size allowed */ 3179 if (emul_mmc_profile < 0) 3180 emul_mmc_profile = 0x01; 3181 if (emul_size == 0) 3182 emul_size = dev_fd_stat.st_size; 3183 size = emul_size; 3184 secsize = emul_sectorsize; 3185 last_sector = (size / secsize) - 1; 3186 if (ftruncate(dev_fd, size)) { 3187 perror("can't resize file"); 3188 return EXIT_FAILURE; 3189 } 3190 } else { 3191 #if !HAVE_NBTOOL_CONFIG_H 3192 struct disk_geom geo; 3193 struct dkwedge_info dkw; 3194 3195 /* sanity */ 3196 if (emul_mmc_profile <= 0) 3197 emul_mmc_profile = 0x01; 3198 if (emul_mmc_profile != 0x01) { 3199 warnx("format incompatible with disc partition"); 3200 return EXIT_FAILURE; 3201 } 3202 3203 /* get our disc info */ 3204 error = getdiskinfo(dev_name, dev_fd, NULL, &geo, &dkw); 3205 if (error) { 3206 warn("retrieving disc info failed"); 3207 return EXIT_FAILURE; 3208 } 3209 secsize = emul_sectorsize; 3210 last_sector = (dkw.dkw_size - 1) * geo.dg_secsize / secsize; 3211 #else 3212 warnx("disk partitions only usable outside tools"); 3213 return EIO; 3214 #endif 3215 } 3216 3217 /* commons */ 3218 mmc_discinfo.mmc_profile = emul_mmc_profile; 3219 mmc_discinfo.disc_state = MMC_STATE_CLOSED; 3220 mmc_discinfo.last_session_state = MMC_STATE_CLOSED; 3221 mmc_discinfo.bg_format_state = MMC_BGFSTATE_COMPLETED; 3222 mmc_discinfo.link_block_penalty = 0; 3223 3224 mmc_discinfo.disc_flags = MMC_DFLAGS_UNRESTRICTED; 3225 3226 mmc_discinfo.last_possible_lba = last_sector; 3227 mmc_discinfo.sector_size = secsize; 3228 3229 mmc_discinfo.num_sessions = 1; 3230 mmc_discinfo.num_tracks = 1; 3231 3232 mmc_discinfo.first_track = 1; 3233 mmc_discinfo.first_track_last_session = mmc_discinfo.last_track_last_session = 1; 3234 3235 mmc_discinfo.mmc_cur = MMC_CAP_RECORDABLE | MMC_CAP_ZEROLINKBLK; 3236 switch (emul_mmc_profile) { 3237 case 0x00: /* unknown, treat as CDROM */ 3238 case 0x08: /* CDROM */ 3239 case 0x10: /* DVDROM */ 3240 case 0x40: /* BDROM */ 3241 /* FALLTHROUGH */ 3242 case 0x01: /* disc */ 3243 /* set up a disc info profile for partitions/files */ 3244 mmc_discinfo.mmc_class = MMC_CLASS_DISC; 3245 mmc_discinfo.mmc_cur |= MMC_CAP_REWRITABLE | MMC_CAP_HW_DEFECTFREE; 3246 break; 3247 case 0x09: /* CD-R */ 3248 mmc_discinfo.mmc_class = MMC_CLASS_CD; 3249 mmc_discinfo.mmc_cur |= MMC_CAP_SEQUENTIAL; 3250 mmc_discinfo.disc_state = MMC_STATE_EMPTY; 3251 break; 3252 case 0x0a: /* CD-RW + CD-MRW (regretably) */ 3253 mmc_discinfo.mmc_class = MMC_CLASS_CD; 3254 mmc_discinfo.mmc_cur |= MMC_CAP_REWRITABLE; 3255 break; 3256 case 0x13: /* DVD-RW */ 3257 case 0x1a: /* DVD+RW */ 3258 mmc_discinfo.mmc_class = MMC_CLASS_DVD; 3259 mmc_discinfo.mmc_cur |= MMC_CAP_REWRITABLE; 3260 break; 3261 case 0x11: /* DVD-R */ 3262 case 0x14: /* DVD-RW sequential */ 3263 case 0x1b: /* DVD+R */ 3264 case 0x2b: /* DVD+R DL */ 3265 case 0x51: /* HD DVD-R */ 3266 mmc_discinfo.mmc_class = MMC_CLASS_DVD; 3267 mmc_discinfo.mmc_cur |= MMC_CAP_SEQUENTIAL; 3268 mmc_discinfo.disc_state = MMC_STATE_EMPTY; 3269 break; 3270 case 0x41: /* BD-R */ 3271 mmc_discinfo.mmc_class = MMC_CLASS_BD; 3272 mmc_discinfo.mmc_cur |= MMC_CAP_SEQUENTIAL | MMC_CAP_HW_DEFECTFREE; 3273 mmc_discinfo.disc_state = MMC_STATE_EMPTY; 3274 break; 3275 case 0x43: /* BD-RE */ 3276 mmc_discinfo.mmc_class = MMC_CLASS_BD; 3277 mmc_discinfo.mmc_cur |= MMC_CAP_REWRITABLE | MMC_CAP_HW_DEFECTFREE; 3278 break; 3279 default: 3280 errno = EINVAL; 3281 perror("unknown or unimplemented device type"); 3282 return errno; 3283 } 3284 mmc_discinfo.mmc_cap = mmc_discinfo.mmc_cur; 3285 3286 return 0; 3287 } 3288 3289 3290 int 3291 udf_update_trackinfo(struct mmc_trackinfo *ti) 3292 { 3293 int error, class; 3294 3295 #if !HAVE_NBTOOL_CONFIG_H 3296 class = mmc_discinfo.mmc_class; 3297 if (class != MMC_CLASS_DISC) { 3298 /* tracknr specified in struct ti */ 3299 error = ioctl(dev_fd, MMCGETTRACKINFO, ti); 3300 if (!error) 3301 return 0; 3302 } 3303 #endif 3304 3305 /* discs partition support */ 3306 if (ti->tracknr != 1) 3307 return EIO; 3308 3309 /* create fake ti (TODO check for resized vnds) */ 3310 ti->sessionnr = 1; 3311 3312 ti->track_mode = 0; /* XXX */ 3313 ti->data_mode = 0; /* XXX */ 3314 ti->flags = MMC_TRACKINFO_LRA_VALID | MMC_TRACKINFO_NWA_VALID; 3315 3316 ti->track_start = 0; 3317 ti->packet_size = emul_packetsize; 3318 3319 /* TODO support for resizable vnd */ 3320 ti->track_size = mmc_discinfo.last_possible_lba; 3321 ti->next_writable = mmc_discinfo.last_possible_lba + 1; //0; 3322 ti->last_recorded = ti->next_writable; 3323 ti->free_blocks = 0; 3324 3325 return 0; 3326 } 3327 3328 3329 int 3330 udf_opendisc(const char *device, int open_flags) 3331 { 3332 /* set global variable to the passed name */ 3333 dev_name = strdup(device); 3334 3335 /* open device */ 3336 if (open_flags & O_RDONLY) { 3337 dev_fd_rdonly = 1; 3338 if ((dev_fd = open(dev_name, O_RDONLY, 0)) == -1) { 3339 warn("device/image not found"); 3340 return EXIT_FAILURE; 3341 } 3342 } else { 3343 dev_fd_rdonly = 0; 3344 if ((dev_fd = open(dev_name, O_RDWR, 0)) == -1) { 3345 /* check if we need to create a file */ 3346 dev_fd = open(dev_name, O_RDONLY, 0); 3347 if (dev_fd > 0) { 3348 warn("device is there but can't be opened for " 3349 "read/write"); 3350 return EXIT_FAILURE; 3351 } 3352 if ((open_flags & O_CREAT) == 0) { 3353 warnx("device/image not found"); 3354 return EXIT_FAILURE; 3355 } 3356 /* need to create a file */ 3357 dev_fd = open(dev_name, O_RDWR | O_CREAT | O_TRUNC, 0666); 3358 if (dev_fd == -1) { 3359 warn("can't create image file"); 3360 return EXIT_FAILURE; 3361 } 3362 } 3363 } 3364 3365 /* stat the device/image */ 3366 if (fstat(dev_fd, &dev_fd_stat) != 0) { 3367 warn("can't stat the disc image"); 3368 return EXIT_FAILURE; 3369 } 3370 3371 /* sanity check and resizing of file */ 3372 if (S_ISREG(dev_fd_stat.st_mode)) { 3373 if (emul_size == 0) 3374 emul_size = dev_fd_stat.st_size; 3375 /* sanitise arguments */ 3376 emul_sectorsize &= ~511; 3377 if (emul_size & (emul_sectorsize-1)) { 3378 warnx("size of file is not a multiple of sector size, " 3379 "shrinking"); 3380 emul_size -= emul_size & (emul_sectorsize-1); 3381 } 3382 3383 /* grow the image */ 3384 if (ftruncate(dev_fd, emul_size)) { 3385 warn("can't resize file"); 3386 return EXIT_FAILURE; 3387 } 3388 /* restat the device/image */ 3389 if (fstat(dev_fd, &dev_fd_stat) != 0) { 3390 warn("can't re-stat the disc image"); 3391 return EXIT_FAILURE; 3392 } 3393 } else { 3394 if (!S_ISCHR(dev_fd_stat.st_mode)) { 3395 warnx("%s is not a raw device", dev_name); 3396 return EXIT_FAILURE; 3397 } 3398 } 3399 3400 /* just in case something went wrong, synchronise the drive's cache */ 3401 udf_synchronise_caches(); 3402 if (udf_update_discinfo()) { 3403 warnx("update discinfo failed"); 3404 return EXIT_FAILURE; 3405 } 3406 3407 /* honour minimum sector size of the device */ 3408 if (mmc_discinfo.sector_size > context.sector_size) 3409 context.sector_size = mmc_discinfo.sector_size; 3410 3411 if (mmc_discinfo.mmc_cur & MMC_CAP_SEQUENTIAL) 3412 udf_init_writequeue(UDF_WRITE_SEQUENTIAL); 3413 else { 3414 udf_init_writequeue(UDF_WRITE_PACKET); 3415 } 3416 return 0; 3417 } 3418 3419 3420 void 3421 udf_closedisc(void) 3422 { 3423 if (!write_queue_suspend) { 3424 udf_writeout_writequeue(true); 3425 assert(write_queuelen == 0); 3426 } 3427 3428 udf_synchronise_caches(); 3429 if (dev_fd) 3430 close(dev_fd); 3431 } 3432 3433 /* --------------------------------------------------------------------- */ 3434 3435 static int 3436 udf_setup_writeparams(void) 3437 { 3438 #if !HAVE_NBTOOL_CONFIG_H 3439 struct mmc_writeparams mmc_writeparams; 3440 int error; 3441 3442 if (mmc_discinfo.mmc_class == MMC_CLASS_DISC) 3443 return 0; 3444 3445 if (S_ISREG(dev_fd_stat.st_mode)) 3446 return 0; 3447 3448 /* 3449 * only CD burning normally needs setting up, but other disc types 3450 * might need other settings to be made. The MMC framework will set up 3451 * the necessary recording parameters according to the disc 3452 * characteristics read in. Modifications can be made in the discinfo 3453 * structure passed to change the nature of the disc. 3454 */ 3455 memset(&mmc_writeparams, 0, sizeof(struct mmc_writeparams)); 3456 mmc_writeparams.mmc_class = mmc_discinfo.mmc_class; 3457 mmc_writeparams.mmc_cur = mmc_discinfo.mmc_cur; 3458 3459 /* 3460 * UDF dictates first track to determine track mode for the whole 3461 * disc. [UDF 1.50/6.10.1.1, UDF 1.50/6.10.2.1] 3462 * To prevent problems with a `reserved' track in front we start with 3463 * the 2nd track and if that is not valid, go for the 1st. 3464 */ 3465 mmc_writeparams.tracknr = 2; 3466 mmc_writeparams.data_mode = MMC_DATAMODE_DEFAULT; /* XA disc */ 3467 mmc_writeparams.track_mode = MMC_TRACKMODE_DEFAULT; /* data */ 3468 3469 error = ioctl(dev_fd, MMCSETUPWRITEPARAMS, &mmc_writeparams); 3470 if (error) { 3471 mmc_writeparams.tracknr = 1; 3472 error = ioctl(dev_fd, MMCSETUPWRITEPARAMS, &mmc_writeparams); 3473 } 3474 return error; 3475 #else 3476 return 0; 3477 #endif 3478 } 3479 3480 3481 /* 3482 * On sequential recordable media, we might need to close the last session to 3483 * be able to write new anchors/new fs. 3484 */ 3485 static int 3486 udf_open_new_session(void) 3487 { 3488 #if !HAVE_NBTOOL_CONFIG_H 3489 struct mmc_trackinfo ti; 3490 struct mmc_op op; 3491 int tracknr, error; 3492 3493 /* if the drive is not sequential, we're done */ 3494 if ((mmc_discinfo.mmc_cur & MMC_CAP_SEQUENTIAL) == 0) 3495 return 0; 3496 3497 /* close the last session if its still open */ 3498 if (mmc_discinfo.last_session_state == MMC_STATE_INCOMPLETE) { 3499 /* 3500 * Leave the disc alone if force format is not set, it will 3501 * error out later 3502 */ 3503 if (!context.create_new_session) 3504 return 0; 3505 3506 // printf("Closing last open session if present\n"); 3507 /* close all associated tracks */ 3508 tracknr = mmc_discinfo.first_track_last_session; 3509 while (tracknr <= mmc_discinfo.last_track_last_session) { 3510 ti.tracknr = tracknr; 3511 error = udf_update_trackinfo(&ti); 3512 if (error) 3513 return error; 3514 // printf("\tClosing open track %d\n", tracknr); 3515 memset(&op, 0, sizeof(op)); 3516 op.operation = MMC_OP_CLOSETRACK; 3517 op.mmc_profile = mmc_discinfo.mmc_profile; 3518 op.tracknr = tracknr; 3519 error = ioctl(dev_fd, MMCOP, &op); 3520 if (error) 3521 return error; 3522 tracknr ++; 3523 } 3524 // printf("Closing session\n"); 3525 memset(&op, 0, sizeof(op)); 3526 op.operation = MMC_OP_CLOSESESSION; 3527 op.mmc_profile = mmc_discinfo.mmc_profile; 3528 op.sessionnr = mmc_discinfo.num_sessions; 3529 error = ioctl(dev_fd, MMCOP, &op); 3530 if (error) 3531 return error; 3532 3533 /* update discinfo since it changed by the operations */ 3534 error = udf_update_discinfo(); 3535 if (error) 3536 return error; 3537 } 3538 #endif 3539 return 0; 3540 } 3541 3542 3543 /* bit paranoid but tracks may need repair before they can be written to */ 3544 static void 3545 udf_repair_tracks(void) 3546 { 3547 #if !HAVE_NBTOOL_CONFIG_H 3548 struct mmc_trackinfo ti; 3549 struct mmc_op op; 3550 int tracknr, error; 3551 3552 tracknr = mmc_discinfo.first_track_last_session; 3553 while (tracknr <= mmc_discinfo.last_track_last_session) { 3554 ti.tracknr = tracknr; 3555 error = udf_update_trackinfo(&ti); 3556 if (error) { 3557 warnx("error updating track information for track %d", 3558 tracknr); 3559 /* resume */ 3560 tracknr++; 3561 continue; 3562 } 3563 3564 if (ti.flags & MMC_TRACKINFO_DAMAGED) { 3565 /* 3566 * Need to repair last track before anything can be done. 3567 * this is an optional command, so ignore its error but report 3568 * warning. 3569 */ 3570 memset(&op, 0, sizeof(op)); 3571 op.operation = MMC_OP_REPAIRTRACK; 3572 op.mmc_profile = mmc_discinfo.mmc_profile; 3573 op.tracknr = ti.tracknr; 3574 error = ioctl(dev_fd, MMCOP, &op); 3575 3576 if (error) 3577 warnx("drive notifies it can't explicitly repair " 3578 "damaged track, but it might autorepair\n"); 3579 } 3580 tracknr++; 3581 } 3582 /* tracks (if any) might not be damaged now, operations are ok now */ 3583 #endif 3584 } 3585 3586 3587 int 3588 udf_prepare_disc(void) 3589 { 3590 #if !HAVE_NBTOOL_CONFIG_H 3591 int error; 3592 3593 /* setup write parameters from discinfo */ 3594 error = udf_setup_writeparams(); 3595 if (error) 3596 return error; 3597 3598 udf_repair_tracks(); 3599 3600 /* open new session if needed */ 3601 return udf_open_new_session(); 3602 #endif 3603 return 0; 3604 } 3605 3606 3607 /* --------------------------------------------------------------------- */ 3608 3609 /* 3610 * write queue implementation 3611 */ 3612 3613 void 3614 udf_suspend_writing(void) 3615 { 3616 write_queue_suspend = 1; 3617 } 3618 3619 3620 void 3621 udf_allow_writing(void) 3622 { 3623 write_queue_suspend = 0; 3624 } 3625 3626 3627 static void 3628 udf_init_writequeue(int write_strategy) 3629 { 3630 context.write_strategy = write_strategy; 3631 write_queue_suspend = 0; 3632 3633 /* setup sector writeout queue's */ 3634 TAILQ_INIT(&write_queue); 3635 write_queuelen = 0; 3636 } 3637 3638 3639 int 3640 udf_write_sector(void *sector, uint64_t location) 3641 { 3642 struct wrpacket *packet, *found_packet; 3643 uint64_t rel_loc; 3644 uint64_t blockingnr = layout.blockingnr; 3645 int error; 3646 3647 assert(!dev_fd_rdonly); 3648 assert(blockingnr >= 1); 3649 assert(blockingnr <= 64); 3650 3651 /* 3652 * We have a write strategy but in practice packet writing is 3653 * preferable for all media types. 3654 */ 3655 3656 again: 3657 /* search location */ 3658 found_packet = NULL; 3659 TAILQ_FOREACH_REVERSE(packet, &write_queue, wrpacket_list, next) { 3660 if (packet->start_sectornr <= location) { 3661 found_packet = packet; 3662 break; 3663 } 3664 } 3665 3666 /* are we in a current packet? */ 3667 if (found_packet) { 3668 uint64_t base = found_packet->start_sectornr; 3669 if ((location >= base) && (location -base < blockingnr)) { 3670 /* fill in existing packet */ 3671 rel_loc = location - base; 3672 memcpy(found_packet->packet_data + 3673 rel_loc * context.sector_size, 3674 sector, context.sector_size); 3675 found_packet->present |= ((uint64_t) 1 << rel_loc); 3676 return 0; 3677 } 3678 } 3679 3680 if ((write_queuelen > UDF_MAX_QUEUELEN) && !write_queue_suspend) { 3681 /* we purge the queue and reset found_packet! */ 3682 error = udf_writeout_writequeue(false); 3683 if (error) 3684 return error; 3685 goto again; 3686 } 3687 3688 /* create new packet */ 3689 packet = calloc(1, sizeof(struct wrpacket)); 3690 if (packet == NULL) 3691 return errno; 3692 packet->packet_data = calloc(1, context.sector_size * blockingnr); 3693 if (packet->packet_data == NULL) { 3694 free(packet); 3695 return errno; 3696 } 3697 packet->start_sectornr = 3698 UDF_ROUNDDOWN(location, blockingnr) + wrtrack_skew; 3699 rel_loc = location - packet->start_sectornr; 3700 3701 memcpy(packet->packet_data + 3702 rel_loc * context.sector_size, 3703 sector, context.sector_size); 3704 packet->present = ((uint64_t) 1 << rel_loc); 3705 3706 if (found_packet) { 3707 TAILQ_INSERT_AFTER(&write_queue, found_packet, packet, next); 3708 } else { 3709 TAILQ_INSERT_HEAD(&write_queue, packet, next); 3710 } 3711 write_queuelen++; 3712 3713 return 0; 3714 } 3715 3716 3717 int 3718 udf_read_sector(void *sector, uint64_t location) 3719 { 3720 struct wrpacket *packet, *found_packet; 3721 ssize_t ret; 3722 uint64_t rpos, rel_loc; 3723 uint64_t blockingnr = layout.blockingnr; 3724 3725 rpos = (uint64_t) location * context.sector_size; 3726 3727 /* search location */ 3728 found_packet = NULL; 3729 TAILQ_FOREACH_REVERSE(packet, &write_queue, wrpacket_list, next) { 3730 if (packet->start_sectornr <= location) { 3731 found_packet = packet; 3732 break; 3733 } 3734 } 3735 3736 /* are we in a current packet? */ 3737 if (found_packet) { 3738 uint64_t base = found_packet->start_sectornr; 3739 if ((location >= base) && (location -base < blockingnr)) { 3740 /* fill in existing packet */ 3741 rel_loc = location - base; 3742 if (found_packet->present & ((uint64_t) 1 << rel_loc)) { 3743 memcpy(sector, found_packet->packet_data + 3744 rel_loc * context.sector_size, 3745 context.sector_size); 3746 } else { 3747 ret = pread(dev_fd, sector, context.sector_size, rpos); 3748 if (ret == -1) 3749 return errno; 3750 if (ret < (int) context.sector_size) 3751 return EIO; 3752 memcpy(found_packet->packet_data + 3753 rel_loc * context.sector_size, 3754 sector, context.sector_size); 3755 found_packet->present |= ((uint64_t) 1 << rel_loc); 3756 return 0; 3757 } 3758 } 3759 } 3760 /* don't create a packet just for we read something */ 3761 ret = pread(dev_fd, sector, context.sector_size, rpos); 3762 if (ret == -1) 3763 return errno; 3764 if (ret < (int) context.sector_size) 3765 return EIO; 3766 return 0; 3767 } 3768 3769 3770 /* 3771 * Now all write requests are queued in the TAILQ, write them out to the 3772 * disc/file image. Special care needs to be taken for devices that are only 3773 * strict overwritable i.e. only in packet size chunks 3774 * 3775 * XXX support for growing vnd? 3776 */ 3777 3778 static int 3779 udf_writeout_writequeue(bool complete) 3780 { 3781 struct wrpacket *packet, *next_packet; 3782 int blockingnr = layout.blockingnr; 3783 int linesize, offset, ret; 3784 uint8_t *linebuf; 3785 int32_t wsects; 3786 uint64_t present, all_present = -1; 3787 uint64_t rpos, wpos; 3788 static int t = 0; 3789 3790 if (write_queuelen == 0) 3791 return 0; 3792 3793 if (blockingnr < 64) 3794 all_present = ((uint64_t) 1 << blockingnr) -1; 3795 linesize = blockingnr * context.sector_size; 3796 linebuf = calloc(1, linesize); 3797 assert(linebuf); 3798 3799 /* fill in blanks if needed */ 3800 if (complete && (context.write_strategy != UDF_WRITE_SEQUENTIAL)) { 3801 TAILQ_FOREACH(packet, &write_queue, next) { 3802 present = packet->present; 3803 if (present != all_present) { 3804 printf("%c", "\\|/-"[t++ % 4]); fflush(stdout);fflush(stderr); 3805 //printf("%16lu : readin %08lx\n", packet->start_sectornr, packet->present ^ all_present); 3806 rpos = (uint64_t) packet->start_sectornr * context.sector_size; 3807 ret = pread(dev_fd, linebuf, linesize, rpos); 3808 if (ret == -1) { 3809 printf("\b"); 3810 warn("error reading in blanks, " 3811 "could indicate bad disc"); 3812 printf(" "); 3813 } 3814 for (int i = 0; i < blockingnr; i++) { 3815 //printf("present %08lx, testing bit %08lx, value %08lx\n", present, ((uint64_t) 1 << i), (present & ((uint64_t) 1 << i))); 3816 if ((present & ((uint64_t) 1 << i)) > 0) 3817 continue; 3818 //printf("NOT PRESENT\n"); 3819 offset = i * context.sector_size; 3820 memcpy(packet->packet_data + offset, 3821 linebuf + offset, 3822 context.sector_size); 3823 packet->present |= ((uint64_t) 1<<i); 3824 } 3825 printf("\b"); 3826 } 3827 assert(packet->present == all_present); 3828 } 3829 } 3830 3831 /* writeout */ 3832 TAILQ_FOREACH(packet, &write_queue, next) { 3833 if (complete || (packet->present == all_present)) { 3834 printf("%c", "\\|/-"[t++ % 4]); fflush(stdout);fflush(stderr); 3835 //printf("write %lu + %d\n", packet->start_sectornr, linesize / context.sector_size); 3836 3837 /* don't write past last possible lba */ 3838 wsects = (mmc_discinfo.last_possible_lba + 1 - packet->start_sectornr); 3839 assert(wsects >= 0); 3840 wsects = MIN(wsects, blockingnr); 3841 3842 wpos = (uint64_t) packet->start_sectornr * context.sector_size; 3843 ret = pwrite(dev_fd, 3844 packet->packet_data, 3845 wsects * context.sector_size, 3846 wpos); 3847 printf("\b"); 3848 if (ret == -1) 3849 warn("error writing packet, " 3850 "could indicate bad disc"); 3851 } 3852 } 3853 3854 /* removing completed packets */ 3855 TAILQ_FOREACH_SAFE(packet, &write_queue, next, next_packet) { 3856 if (complete || (packet->present == all_present)) { 3857 TAILQ_REMOVE(&write_queue, packet, next); 3858 free(packet->packet_data); 3859 free(packet); 3860 write_queuelen--; 3861 } 3862 } 3863 if (complete) { 3864 assert(TAILQ_EMPTY(&write_queue)); 3865 write_queuelen = 0; 3866 } 3867 3868 free(linebuf); 3869 return 0; 3870 } 3871 3872 3873 /* --------------------------------------------------------------------- */ 3874 3875 /* simplified version of kernel routine */ 3876 int 3877 udf_translate_vtop(uint32_t lb_num, uint16_t vpart, 3878 uint32_t *lb_numres, uint32_t *extres) 3879 { 3880 struct part_desc *pdesc; 3881 struct spare_map_entry *sme; 3882 struct short_ad *short_ad; 3883 struct extfile_entry *efe; 3884 uint32_t ext, len, lb_rel, lb_packet, vat_off; 3885 uint32_t start_lb, lb_offset, end_lb_offset; 3886 uint32_t udf_rw32_lbmap; 3887 uint32_t flags; 3888 uint8_t *vat_pos, *data_pos; 3889 int dscr_size, l_ea, l_ad, icbflags, addr_type; 3890 int rel, part; 3891 3892 if (vpart > UDF_VTOP_RAWPART) 3893 return EINVAL; 3894 3895 ext = INT_MAX; 3896 translate_again: 3897 part = context.vtop[vpart]; 3898 pdesc = context.partitions[part]; 3899 3900 switch (context.vtop_tp[vpart]) { 3901 case UDF_VTOP_TYPE_RAW : 3902 /* 1:1 to the end of the device */ 3903 *lb_numres = lb_num; 3904 *extres = MIN(ext, INT_MAX); 3905 return 0; 3906 case UDF_VTOP_TYPE_PHYS : 3907 /* transform into its disc logical block */ 3908 if (lb_num > udf_rw32(pdesc->part_len)) 3909 return EINVAL; 3910 *lb_numres = lb_num + udf_rw32(pdesc->start_loc); 3911 3912 /* extent from here to the end of the partition */ 3913 *extres = MIN(ext, udf_rw32(pdesc->part_len) - lb_num); 3914 if (*extres == 0) 3915 return EINVAL; 3916 return 0; 3917 case UDF_VTOP_TYPE_VIRT : 3918 /* only maps one logical block, lookup in VAT */ 3919 if (lb_num * 4 >= context.vat_size) 3920 return EINVAL; 3921 vat_off = context.vat_start + lb_num * 4; 3922 vat_pos = context.vat_contents + vat_off; 3923 udf_rw32_lbmap = *((uint32_t *) vat_pos); 3924 3925 if (vat_off >= context.vat_size) /* XXX > or >= ? */ 3926 return EINVAL; 3927 lb_num = udf_rw32(udf_rw32_lbmap); 3928 3929 /* transform into its disc logical block */ 3930 if (lb_num > udf_rw32(pdesc->part_len)) 3931 return EINVAL; 3932 *lb_numres = lb_num + udf_rw32(pdesc->start_loc); 3933 3934 /* just one logical block */ 3935 *extres = 1; 3936 return 0; 3937 case UDF_VTOP_TYPE_SPAREABLE : 3938 /* check if the packet containing the lb_num is remapped */ 3939 lb_packet = lb_num / layout.spareable_blockingnr; 3940 lb_rel = lb_num % layout.spareable_blockingnr; 3941 3942 for (rel = 0; rel < udf_rw16(context.sparing_table->rt_l); rel++) { 3943 sme = &context.sparing_table->entries[rel]; 3944 if (lb_packet == udf_rw32(sme->org)) { 3945 /* NOTE maps to absolute disc logical block! */ 3946 *lb_numres = udf_rw32(sme->map) + lb_rel; 3947 *extres = layout.spareable_blockingnr - lb_rel; 3948 return 0; 3949 } 3950 } 3951 3952 /* transform into its disc logical block */ 3953 if (lb_num > udf_rw32(pdesc->part_len)) 3954 return EINVAL; 3955 *lb_numres = lb_num + udf_rw32(pdesc->start_loc); 3956 3957 /* rest of block */ 3958 *extres = MIN(ext, layout.spareable_blockingnr - lb_rel); 3959 return 0; 3960 case UDF_VTOP_TYPE_META : 3961 /* we have to look into the file's allocation descriptors */ 3962 3963 /* get first overlapping extent */ 3964 efe = context.meta_file; 3965 dscr_size = sizeof(struct extfile_entry) - 1; 3966 l_ea = udf_rw32(efe->l_ea); 3967 l_ad = udf_rw32(efe->l_ad); 3968 3969 icbflags = udf_rw16(efe->icbtag.flags); 3970 addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK; 3971 if (addr_type != UDF_ICB_SHORT_ALLOC) { 3972 warnx("specification violation: metafile not using" 3973 "short allocs"); 3974 return EINVAL; 3975 } 3976 3977 data_pos = (uint8_t *) context.meta_file + dscr_size + l_ea; 3978 short_ad = (struct short_ad *) data_pos; 3979 lb_offset = 0; 3980 while (l_ad > 0) { 3981 len = udf_rw32(short_ad->len); 3982 start_lb = udf_rw32(short_ad->lb_num); 3983 flags = UDF_EXT_FLAGS(len); 3984 len = UDF_EXT_LEN(len); 3985 if (flags == UDF_EXT_REDIRECT) { 3986 warnx("implementation limit: no support for " 3987 "extent redirection in metadata file"); 3988 return EINVAL; 3989 } 3990 end_lb_offset = lb_offset + len / context.sector_size; 3991 /* overlap? */ 3992 if (end_lb_offset > lb_num) 3993 break; 3994 short_ad++; 3995 lb_offset = end_lb_offset; 3996 l_ad -= sizeof(struct short_ad); 3997 } 3998 if (l_ad <= 0) { 3999 warnx("looking up outside metadata partition!"); 4000 return EINVAL; 4001 } 4002 lb_num = start_lb + (lb_num - lb_offset); 4003 vpart = part; 4004 ext = end_lb_offset - lb_num; 4005 /* 4006 * vpart and lb_num are updated, translate again since we 4007 * might be mapped on spareable media 4008 */ 4009 goto translate_again; 4010 default: 4011 printf("UDF vtop translation scheme %d unimplemented yet\n", 4012 context.vtop_tp[vpart]); 4013 } 4014 4015 return EINVAL; 4016 } 4017 4018 /* --------------------------------------------------------------------- */ 4019 4020 int 4021 udf_read_phys(void *blob, uint32_t location, uint32_t sects) 4022 { 4023 uint32_t phys, cnt; 4024 uint8_t *bpos; 4025 int error; 4026 4027 for (cnt = 0; cnt < sects; cnt++) { 4028 bpos = (uint8_t *) blob; 4029 bpos += context.sector_size * cnt; 4030 4031 phys = location + cnt; 4032 error = udf_read_sector(bpos, phys); 4033 if (error) 4034 return error; 4035 } 4036 return 0; 4037 } 4038 4039 4040 int 4041 udf_write_phys(void *blob, uint32_t location, uint32_t sects) 4042 { 4043 uint32_t phys, cnt; 4044 uint8_t *bpos; 4045 int error; 4046 4047 for (cnt = 0; cnt < sects; cnt++) { 4048 bpos = (uint8_t *) blob; 4049 bpos += context.sector_size * cnt; 4050 4051 phys = location + cnt; 4052 error = udf_write_sector(bpos, phys); 4053 if (error) 4054 return error; 4055 } 4056 return 0; 4057 } 4058 4059 4060 int 4061 udf_read_virt(void *blob, uint32_t location, uint16_t vpart, 4062 uint32_t sectors) 4063 { 4064 uint32_t phys, ext; 4065 uint8_t *data; 4066 int error; 4067 4068 /* determine physical location */ 4069 data = (uint8_t *) blob; 4070 while (sectors) { 4071 if (udf_translate_vtop(location, vpart, &phys, &ext)) { 4072 // warnx("internal error: bad translation"); 4073 return EINVAL; 4074 } 4075 ext = MIN(sectors, ext); 4076 error = udf_read_phys(data, phys, ext); 4077 if (error) 4078 return error; 4079 location += ext; 4080 data += ext * context.sector_size; 4081 sectors -= ext; 4082 } 4083 return 0; 4084 } 4085 4086 4087 int 4088 udf_write_virt(void *blob, uint32_t location, uint16_t vpart, 4089 uint32_t sectors) 4090 { 4091 uint32_t phys, ext, alloc_pos; 4092 uint8_t *data; 4093 int error; 4094 4095 /* determine physical location */ 4096 if (context.vtop_tp[vpart] == UDF_VTOP_TYPE_VIRT) { 4097 assert(sectors == 1); 4098 alloc_pos = context.alloc_pos[context.data_part]; 4099 udf_vat_update(location, alloc_pos); 4100 udf_translate_vtop(alloc_pos, context.vtop[vpart], &phys, &ext); 4101 context.alloc_pos[context.data_part]++; 4102 return udf_write_phys(blob, phys, sectors); 4103 } 4104 4105 data = (uint8_t *) blob; 4106 while (sectors) { 4107 if (udf_translate_vtop(location, vpart, &phys, &ext)) { 4108 warnx("internal error: bad translation"); 4109 return EINVAL; 4110 } 4111 ext = MIN(sectors, ext); 4112 error = udf_write_phys(data, phys, ext); 4113 if (error) 4114 return error; 4115 location += ext; 4116 data += ext * context.sector_size; 4117 sectors -= ext; 4118 } 4119 return 0; 4120 } 4121 4122 4123 int 4124 udf_read_dscr_phys(uint32_t sector, union dscrptr **dstp) 4125 { 4126 union dscrptr *dst, *new_dst; 4127 uint8_t *pos; 4128 uint32_t sectors, dscrlen, sector_size; 4129 int error; 4130 4131 sector_size = context.sector_size; 4132 4133 *dstp = dst = NULL; 4134 dscrlen = sector_size; 4135 4136 /* read initial piece */ 4137 dst = malloc(sector_size); 4138 assert(dst); 4139 error = udf_read_sector(dst, sector); 4140 // if (error) 4141 // warn("read error"); 4142 4143 if (!error) { 4144 /* check if its an empty block */ 4145 if (is_zero(dst, sector_size)) { 4146 /* return no error but with no dscrptr */ 4147 /* dispose first block */ 4148 free(dst); 4149 return 0; 4150 } 4151 /* check if its a valid tag */ 4152 error = udf_check_tag(dst); 4153 if (error) { 4154 free(dst); 4155 return 0; 4156 } 4157 /* calculate descriptor size */ 4158 dscrlen = udf_tagsize(dst, sector_size); 4159 } 4160 4161 if (!error && (dscrlen > sector_size)) { 4162 /* read the rest of descriptor */ 4163 4164 new_dst = realloc(dst, dscrlen); 4165 if (new_dst == NULL) { 4166 free(dst); 4167 return ENOMEM; 4168 } 4169 dst = new_dst; 4170 4171 sectors = dscrlen / sector_size; 4172 pos = (uint8_t *) dst + sector_size; 4173 error = udf_read_phys(pos, sector + 1, sectors-1); 4174 if (error) 4175 warnx("read error"); 4176 } 4177 if (!error) 4178 error = udf_check_tag_payload(dst, dscrlen); 4179 if (error && dst) { 4180 free(dst); 4181 dst = NULL; 4182 } 4183 *dstp = dst; 4184 4185 return error; 4186 } 4187 4188 4189 int 4190 udf_write_dscr_phys(union dscrptr *dscr, uint32_t location, 4191 uint32_t sectors) 4192 { 4193 dscr->tag.tag_loc = udf_rw32(location); 4194 (void) udf_validate_tag_and_crc_sums(dscr); 4195 4196 assert(sectors == udf_tagsize(dscr, context.sector_size) / context.sector_size); 4197 return udf_write_phys(dscr, location, sectors); 4198 } 4199 4200 4201 int 4202 udf_read_dscr_virt(uint32_t sector, uint16_t vpart, union dscrptr **dstp) 4203 { 4204 union dscrptr *dst, *new_dst; 4205 uint8_t *pos; 4206 uint32_t sectors, dscrlen, sector_size; 4207 int error; 4208 4209 sector_size = context.sector_size; 4210 4211 *dstp = dst = NULL; 4212 dscrlen = sector_size; 4213 4214 /* read initial piece */ 4215 dst = calloc(1, sector_size); 4216 assert(dst); 4217 error = udf_read_virt(dst, sector, vpart, 1); 4218 if (error) 4219 return error; 4220 4221 if (!error) { 4222 /* check if its a valid tag */ 4223 error = udf_check_tag(dst); 4224 if (error) { 4225 /* check if its an empty block */ 4226 if (is_zero(dst, sector_size)) { 4227 /* return no error but with no dscrptr */ 4228 /* dispose first block */ 4229 free(dst); 4230 return 0; 4231 } 4232 } 4233 /* calculate descriptor size */ 4234 dscrlen = udf_tagsize(dst, sector_size); 4235 } 4236 4237 if (!error && (dscrlen > sector_size)) { 4238 /* read the rest of descriptor */ 4239 4240 new_dst = realloc(dst, dscrlen); 4241 if (new_dst == NULL) { 4242 free(dst); 4243 return ENOMEM; 4244 } 4245 dst = new_dst; 4246 4247 sectors = dscrlen / sector_size; 4248 pos = (uint8_t *) dst + sector_size; 4249 error = udf_read_virt(pos, sector + 1, vpart, sectors-1); 4250 if (error) 4251 warn("read error"); 4252 } 4253 if (!error) 4254 error = udf_check_tag_payload(dst, dscrlen); 4255 if (error && dst) { 4256 free(dst); 4257 dst = NULL; 4258 } 4259 *dstp = dst; 4260 4261 return error; 4262 } 4263 4264 4265 int 4266 udf_write_dscr_virt(union dscrptr *dscr, uint32_t location, uint16_t vpart, 4267 uint32_t sectors) 4268 { 4269 struct file_entry *fe; 4270 struct extfile_entry *efe; 4271 struct extattrhdr_desc *extattrhdr; 4272 4273 extattrhdr = NULL; 4274 if (udf_rw16(dscr->tag.id) == TAGID_FENTRY) { 4275 fe = (struct file_entry *) dscr; 4276 if (udf_rw32(fe->l_ea) > 0) 4277 extattrhdr = (struct extattrhdr_desc *) fe->data; 4278 } 4279 if (udf_rw16(dscr->tag.id) == TAGID_EXTFENTRY) { 4280 efe = (struct extfile_entry *) dscr; 4281 if (udf_rw32(efe->l_ea) > 0) 4282 extattrhdr = (struct extattrhdr_desc *) efe->data; 4283 } 4284 if (extattrhdr) { 4285 extattrhdr->tag.tag_loc = udf_rw32(location); 4286 udf_validate_tag_and_crc_sums((union dscrptr *) extattrhdr); 4287 } 4288 4289 dscr->tag.tag_loc = udf_rw32(location); 4290 udf_validate_tag_and_crc_sums(dscr); 4291 4292 assert(sectors >= (udf_tagsize(dscr, context.sector_size) / context.sector_size)); 4293 return udf_write_virt(dscr, location, vpart, sectors); 4294 } 4295 4296 4297 int 4298 is_zero(void *blob, int size) { 4299 uint8_t *p = blob; 4300 for (int i = 0; i < size; i++, p++) 4301 if (*p) 4302 return 0; 4303 return 1; 4304 } 4305 4306 /* --------------------------------------------------------------------- */ 4307 4308 static void 4309 udf_partition_alloc(int nblk, int vpart, struct long_ad *pos) 4310 { 4311 memset(pos, 0, sizeof(*pos)); 4312 pos->len = udf_rw32(nblk * context.sector_size); 4313 pos->loc.lb_num = udf_rw32(context.alloc_pos[vpart]); 4314 pos->loc.part_num = udf_rw16(vpart); 4315 4316 udf_mark_allocated(context.alloc_pos[vpart], vpart, nblk); 4317 context.alloc_pos[vpart] += nblk; 4318 } 4319 4320 4321 void 4322 udf_metadata_alloc(int nblk, struct long_ad *pos) 4323 { 4324 udf_partition_alloc(nblk, context.metadata_part, pos); 4325 } 4326 4327 4328 void 4329 udf_data_alloc(int nblk, struct long_ad *pos) 4330 { 4331 udf_partition_alloc(nblk, context.data_part, pos); 4332 } 4333 4334 4335 void 4336 udf_fids_alloc(int nblk, struct long_ad *pos) 4337 { 4338 udf_partition_alloc(nblk, context.fids_part, pos); 4339 } 4340 4341 4342 /* --------------------------------------------------------------------- */ 4343 4344 /* 4345 * udf_derive_format derives the format_flags from the disc's mmc_discinfo. 4346 * The resulting flags uniquely define a disc format. Note there are at least 4347 * 7 distinct format types defined in UDF. 4348 */ 4349 4350 #define UDF_VERSION(a) \ 4351 (((a) == 0x102) || ((a) == 0x150) || ((a) == 0x200) || \ 4352 ((a) == 0x201) || ((a) == 0x250) || ((a) == 0x260)) 4353 4354 int 4355 udf_derive_format(int req_enable, int req_disable) 4356 { 4357 int format_flags; 4358 int media_accesstype; 4359 4360 /* disc writability, formatted, appendable */ 4361 if ((mmc_discinfo.mmc_cur & MMC_CAP_RECORDABLE) == 0) { 4362 warnx("can't newfs readonly device"); 4363 return EROFS; 4364 } 4365 if (mmc_discinfo.mmc_cur & MMC_CAP_SEQUENTIAL) { 4366 /* sequentials need sessions appended */ 4367 if (mmc_discinfo.disc_state == MMC_STATE_CLOSED) { 4368 warnx("can't append session to a closed disc"); 4369 return EROFS; 4370 } 4371 if ((mmc_discinfo.disc_state != MMC_STATE_EMPTY) && 4372 !context.create_new_session) { 4373 warnx("disc not empty! Use -F to force " 4374 "initialisation"); 4375 return EROFS; 4376 } 4377 } else { 4378 /* check if disc (being) formatted or has been started on */ 4379 if (mmc_discinfo.disc_state == MMC_STATE_EMPTY) { 4380 warnx("disc is not formatted"); 4381 return EROFS; 4382 } 4383 } 4384 4385 /* determine UDF format */ 4386 format_flags = 0; 4387 if (mmc_discinfo.mmc_cur & MMC_CAP_REWRITABLE) { 4388 /* all rewritable media */ 4389 format_flags |= FORMAT_REWRITABLE; 4390 if (context.min_udf >= 0x0250) { 4391 /* standard dictates meta as default */ 4392 format_flags |= FORMAT_META; 4393 } 4394 4395 if ((mmc_discinfo.mmc_cur & MMC_CAP_HW_DEFECTFREE) == 0) { 4396 /* spareables for defect management */ 4397 if (context.min_udf >= 0x150) 4398 format_flags |= FORMAT_SPAREABLE; 4399 } 4400 } else { 4401 /* all once recordable media */ 4402 format_flags |= FORMAT_WRITEONCE; 4403 if (mmc_discinfo.mmc_cur & MMC_CAP_SEQUENTIAL) { 4404 format_flags |= FORMAT_SEQUENTIAL; 4405 4406 if (mmc_discinfo.mmc_cur & MMC_CAP_PSEUDOOVERWRITE) { 4407 /* logical overwritable */ 4408 format_flags |= FORMAT_LOW; 4409 } else { 4410 /* have to use VAT for overwriting */ 4411 format_flags |= FORMAT_VAT; 4412 } 4413 } else { 4414 /* rare WORM devices, but BluRay has one, strat4096 */ 4415 format_flags |= FORMAT_WORM; 4416 } 4417 } 4418 4419 /* enable/disable requests */ 4420 if (req_disable & FORMAT_META) { 4421 format_flags &= ~(FORMAT_META | FORMAT_LOW); 4422 req_disable &= ~FORMAT_META; 4423 } 4424 if ((format_flags & FORMAT_VAT) & UDF_512_TRACK) 4425 format_flags |= FORMAT_TRACK512; 4426 4427 if (req_enable & FORMAT_READONLY) { 4428 format_flags |= FORMAT_READONLY; 4429 } 4430 4431 /* determine partition/media access type */ 4432 media_accesstype = UDF_ACCESSTYPE_NOT_SPECIFIED; 4433 if (mmc_discinfo.mmc_cur & MMC_CAP_REWRITABLE) { 4434 media_accesstype = UDF_ACCESSTYPE_OVERWRITABLE; 4435 if (mmc_discinfo.mmc_cur & MMC_CAP_ERASABLE) 4436 media_accesstype = UDF_ACCESSTYPE_REWRITEABLE; 4437 } else { 4438 /* all once recordable media */ 4439 media_accesstype = UDF_ACCESSTYPE_WRITE_ONCE; 4440 } 4441 if (mmc_discinfo.mmc_cur & MMC_CAP_PSEUDOOVERWRITE) 4442 media_accesstype = UDF_ACCESSTYPE_PSEUDO_OVERWITE; 4443 4444 /* patch up media accesstype */ 4445 if (req_enable & FORMAT_READONLY) { 4446 /* better now */ 4447 media_accesstype = UDF_ACCESSTYPE_READ_ONLY; 4448 } 4449 4450 /* adjust minimum version limits */ 4451 if (format_flags & FORMAT_VAT) 4452 context.min_udf = MAX(context.min_udf, 0x0150); 4453 if (format_flags & FORMAT_SPAREABLE) 4454 context.min_udf = MAX(context.min_udf, 0x0150); 4455 if (format_flags & FORMAT_META) 4456 context.min_udf = MAX(context.min_udf, 0x0250); 4457 if (format_flags & FORMAT_LOW) 4458 context.min_udf = MAX(context.min_udf, 0x0260); 4459 4460 /* adjust maximum version limits not to tease or break things */ 4461 if (!(format_flags & (FORMAT_META | FORMAT_LOW | FORMAT_VAT)) && 4462 (context.max_udf > 0x200)) 4463 context.max_udf = 0x201; 4464 4465 if ((format_flags & (FORMAT_VAT | FORMAT_SPAREABLE)) == 0) 4466 if (context.max_udf <= 0x150) 4467 context.min_udf = 0x102; 4468 4469 /* limit Ecma 167 descriptor if possible/needed */ 4470 context.dscrver = 3; 4471 if ((context.min_udf < 0x200) || (context.max_udf < 0x200)) { 4472 context.dscrver = 2; 4473 context.max_udf = 0x150; /* last version < 0x200 */ 4474 } 4475 4476 /* is it possible ? */ 4477 if (context.min_udf > context.max_udf) { 4478 warnx("initialisation prohibited by specified maximum " 4479 "UDF version 0x%04x. Minimum version required 0x%04x", 4480 context.max_udf, context.min_udf); 4481 return EPERM; 4482 } 4483 4484 if (!UDF_VERSION(context.min_udf) || !UDF_VERSION(context.max_udf)) { 4485 warnx("internal error, invalid min/max udf versionsi in %s", 4486 __func__); 4487 return EPERM; 4488 } 4489 context.format_flags = format_flags; 4490 context.media_accesstype = media_accesstype; 4491 4492 return 0; 4493 } 4494 4495 #undef UDF_VERSION 4496 4497 4498 /* --------------------------------------------------------------------- */ 4499 4500 int 4501 udf_proces_names(void) 4502 { 4503 struct timeval time_of_day; 4504 uint32_t primary_nr; 4505 uint64_t volset_nr; 4506 4507 if (context.logvol_name == NULL) 4508 context.logvol_name = strdup("anonymous"); 4509 if (context.primary_name == NULL) { 4510 if (mmc_discinfo.disc_flags & MMC_DFLAGS_DISCIDVALID) { 4511 primary_nr = mmc_discinfo.disc_id; 4512 } else { 4513 primary_nr = (uint32_t) random(); 4514 } 4515 context.primary_name = calloc(32, 1); 4516 sprintf(context.primary_name, "%08"PRIx32, primary_nr); 4517 } 4518 if (context.volset_name == NULL) { 4519 if (mmc_discinfo.disc_flags & MMC_DFLAGS_BARCODEVALID) { 4520 volset_nr = mmc_discinfo.disc_barcode; 4521 } else { 4522 (void)gettimeofday(&time_of_day, NULL); 4523 volset_nr = (uint64_t) random(); 4524 volset_nr |= ((uint64_t) time_of_day.tv_sec) << 32; 4525 } 4526 context.volset_name = calloc(128,1); 4527 sprintf(context.volset_name, "%016"PRIx64, volset_nr); 4528 } 4529 if (context.fileset_name == NULL) 4530 context.fileset_name = strdup("anonymous"); 4531 4532 /* check passed/created identifiers */ 4533 if (strlen(context.logvol_name) > 128) { 4534 warnx("logical volume name too long"); 4535 return EINVAL; 4536 } 4537 if (strlen(context.primary_name) > 32) { 4538 warnx("primary volume name too long"); 4539 return EINVAL; 4540 } 4541 if (strlen(context.volset_name) > 128) { 4542 warnx("volume set name too long"); 4543 return EINVAL; 4544 } 4545 if (strlen(context.fileset_name) > 32) { 4546 warnx("fileset name too long"); 4547 return EINVAL; 4548 } 4549 4550 /* signal all OK */ 4551 return 0; 4552 } 4553 4554 /* --------------------------------------------------------------------- */ 4555 4556 int 4557 udf_write_iso9660_vrs(void) 4558 { 4559 struct vrs_desc *iso9660_vrs_desc; 4560 uint32_t pos; 4561 int error, cnt, dpos; 4562 4563 /* create ISO/Ecma-167 identification descriptors */ 4564 if ((iso9660_vrs_desc = calloc(1, context.sector_size)) == NULL) 4565 return ENOMEM; 4566 4567 /* 4568 * All UDF formats should have their ISO/Ecma-167 descriptors written 4569 * except when not possible due to track reservation in the case of 4570 * VAT 4571 */ 4572 if ((context.format_flags & FORMAT_TRACK512) == 0) { 4573 dpos = (2048 + context.sector_size - 1) / context.sector_size; 4574 4575 /* wipe at least 6 times 2048 byte `sectors' */ 4576 for (cnt = 0; cnt < 6 *dpos; cnt++) { 4577 pos = layout.iso9660_vrs + cnt; 4578 if ((error = udf_write_sector(iso9660_vrs_desc, pos))) { 4579 free(iso9660_vrs_desc); 4580 return error; 4581 } 4582 } 4583 4584 /* common VRS fields in all written out ISO descriptors */ 4585 iso9660_vrs_desc->struct_type = 0; 4586 iso9660_vrs_desc->version = 1; 4587 pos = layout.iso9660_vrs; 4588 4589 /* BEA01, NSR[23], TEA01 */ 4590 memcpy(iso9660_vrs_desc->identifier, "BEA01", 5); 4591 if ((error = udf_write_sector(iso9660_vrs_desc, pos))) { 4592 free(iso9660_vrs_desc); 4593 return error; 4594 } 4595 pos += dpos; 4596 4597 if (context.dscrver == 2) 4598 memcpy(iso9660_vrs_desc->identifier, "NSR02", 5); 4599 else 4600 memcpy(iso9660_vrs_desc->identifier, "NSR03", 5); 4601 ; 4602 if ((error = udf_write_sector(iso9660_vrs_desc, pos))) { 4603 free(iso9660_vrs_desc); 4604 return error; 4605 } 4606 pos += dpos; 4607 4608 memcpy(iso9660_vrs_desc->identifier, "TEA01", 5); 4609 if ((error = udf_write_sector(iso9660_vrs_desc, pos))) { 4610 free(iso9660_vrs_desc); 4611 return error; 4612 } 4613 } 4614 4615 free(iso9660_vrs_desc); 4616 /* return success */ 4617 return 0; 4618 } 4619 4620 4621 /* --------------------------------------------------------------------- */ 4622 4623 int 4624 udf_get_blockingnr(struct mmc_trackinfo *ti) 4625 { 4626 int blockingnr; 4627 4628 /* determine blockingnr */ 4629 blockingnr = ti->packet_size; 4630 if (blockingnr <= 1) { 4631 /* paranoia on blockingnr */ 4632 switch (mmc_discinfo.mmc_profile) { 4633 case 0x01 : /* DISC */ 4634 blockingnr = 64; 4635 break; 4636 case 0x08 : /* CDROM */ 4637 case 0x09 : /* CD-R */ 4638 case 0x0a : /* CD-RW */ 4639 blockingnr = 32; /* UDF requirement */ 4640 break; 4641 case 0x10 : /* DVDROM */ 4642 case 0x11 : /* DVD-R (DL) */ 4643 case 0x12 : /* DVD-RAM */ 4644 case 0x1b : /* DVD+R */ 4645 case 0x2b : /* DVD+R Dual layer */ 4646 case 0x13 : /* DVD-RW restricted overwrite */ 4647 case 0x14 : /* DVD-RW sequential */ 4648 case 0x1a : /* DVD+RW */ 4649 blockingnr = 16; /* SCSI definition */ 4650 break; 4651 case 0x40 : /* BDROM */ 4652 case 0x41 : /* BD-R Sequential recording (SRM) */ 4653 case 0x42 : /* BD-R Random recording (RRM) */ 4654 case 0x43 : /* BD-RE */ 4655 case 0x51 : /* HD DVD-R */ 4656 case 0x52 : /* HD DVD-RW */ 4657 blockingnr = 32; /* SCSI definition */ 4658 break; 4659 default: 4660 break; 4661 } 4662 } 4663 return blockingnr; 4664 } 4665 4666 4667 int 4668 udf_spareable_blocks(void) 4669 { 4670 if (mmc_discinfo.mmc_class == MMC_CLASS_CD) { 4671 /* not too much for CD-RW, still 20MiB */ 4672 return 32; 4673 } else { 4674 /* take a value for DVD*RW mainly, BD is `defect free' */ 4675 return 512; 4676 } 4677 } 4678 4679 4680 int 4681 udf_spareable_blockingnr(void) 4682 { 4683 struct mmc_trackinfo ti; 4684 int spareable_blockingnr; 4685 int error; 4686 4687 /* determine span/size */ 4688 ti.tracknr = mmc_discinfo.first_track_last_session; 4689 error = udf_update_trackinfo(&ti); 4690 spareable_blockingnr = udf_get_blockingnr(&ti); 4691 if (error) 4692 spareable_blockingnr = 32; 4693 4694 /* 4695 * Note that for (bug) compatibility with version UDF 2.00 4696 * (fixed in 2.01 and higher) the blocking size needs to be 32 4697 * sectors otherwise the drive's blockingnr. 4698 */ 4699 if (context.min_udf <= 0x200) 4700 spareable_blockingnr = 32; 4701 return spareable_blockingnr; 4702 } 4703 4704 4705 /* 4706 * Main function that creates and writes out disc contents based on the 4707 * format_flags's that uniquely define the type of disc to create. 4708 */ 4709 4710 int 4711 udf_do_newfs_prefix(void) 4712 { 4713 union dscrptr *zero_dscr; 4714 union dscrptr *dscr; 4715 struct mmc_trackinfo ti; 4716 uint32_t blockingnr; 4717 uint32_t cnt, loc, len; 4718 int sectcopy; 4719 int error, integrity_type; 4720 int data_part, metadata_part; 4721 int format_flags; 4722 4723 /* init */ 4724 format_flags = context.format_flags; 4725 4726 /* determine span/size */ 4727 ti.tracknr = mmc_discinfo.first_track_last_session; 4728 error = udf_update_trackinfo(&ti); 4729 if (error) 4730 return error; 4731 4732 if (mmc_discinfo.sector_size > context.sector_size) { 4733 warnx("impossible to format: " 4734 "sector size %d too small for media sector size %d", 4735 context.sector_size, mmc_discinfo.sector_size); 4736 return EIO; 4737 } 4738 4739 /* determine blockingnr */ 4740 blockingnr = udf_get_blockingnr(&ti); 4741 if (blockingnr <= 0) { 4742 warnx("can't fixup blockingnumber for device " 4743 "type %d", mmc_discinfo.mmc_profile); 4744 warnx("device is not returning valid blocking" 4745 " number and media type is unknown"); 4746 return EINVAL; 4747 } 4748 4749 wrtrack_skew = 0; 4750 if (mmc_discinfo.mmc_cur & MMC_CAP_SEQUENTIAL) 4751 wrtrack_skew = ti.next_writable % blockingnr; 4752 4753 /* get layout */ 4754 error = udf_calculate_disc_layout(context.min_udf, 4755 ti.track_start, mmc_discinfo.last_possible_lba, 4756 context.sector_size, blockingnr); 4757 4758 /* cache partition for we need it often */ 4759 data_part = context.data_part; 4760 metadata_part = context.metadata_part; 4761 4762 /* Create sparing table descriptor if applicable */ 4763 if (format_flags & FORMAT_SPAREABLE) { 4764 if ((error = udf_create_sparing_tabled())) 4765 return error; 4766 4767 if (context.check_surface) { 4768 if ((error = udf_surface_check())) 4769 return error; 4770 } 4771 } 4772 4773 /* Create a generic terminator descriptor (later reused) */ 4774 terminator_dscr = calloc(1, context.sector_size); 4775 if (terminator_dscr == NULL) 4776 return ENOMEM; 4777 udf_create_terminator(terminator_dscr, 0); 4778 4779 /* 4780 * Create the two Volume Descriptor Sets (VDS) each containing the 4781 * following descriptors : primary volume, partition space, 4782 * unallocated space, logical volume, implementation use and the 4783 * terminator 4784 */ 4785 4786 /* start of volume recognition sequence building */ 4787 context.vds_seq = 0; 4788 4789 /* Create primary volume descriptor */ 4790 if ((error = udf_create_primaryd())) 4791 return error; 4792 4793 /* Create partition descriptor */ 4794 if ((error = udf_create_partitiond(context.data_part))) 4795 return error; 4796 4797 /* Create unallocated space descriptor */ 4798 if ((error = udf_create_unalloc_spaced())) 4799 return error; 4800 4801 /* Create logical volume descriptor */ 4802 if ((error = udf_create_logical_dscr())) 4803 return error; 4804 4805 /* Create implementation use descriptor */ 4806 /* TODO input of fields 1,2,3 and passing them */ 4807 if ((error = udf_create_impvold(NULL, NULL, NULL))) 4808 return error; 4809 4810 /* Create anchors */ 4811 for (cnt = 0; cnt < 3; cnt++) { 4812 if ((error = udf_create_anchor(cnt))) { 4813 return error; 4814 } 4815 } 4816 4817 /* 4818 * Write out what we've created so far. 4819 * 4820 * Start with wipeout of VRS1 upto start of partition. This allows 4821 * formatting for sequentials with the track reservation and it 4822 * cleans old rubbish on rewritables. For sequentials without the 4823 * track reservation all is wiped from track start. 4824 */ 4825 if ((zero_dscr = calloc(1, context.sector_size)) == NULL) 4826 return ENOMEM; 4827 4828 loc = (format_flags & FORMAT_TRACK512) ? layout.vds1 : ti.track_start; 4829 for (; loc < layout.part_start_lba; loc++) { 4830 if ((error = udf_write_sector(zero_dscr, loc))) { 4831 free(zero_dscr); 4832 return error; 4833 } 4834 } 4835 free(zero_dscr); 4836 4837 /* writeout iso9660 vrs */ 4838 if ((error = udf_write_iso9660_vrs())) 4839 return error; 4840 4841 /* Writeout anchors */ 4842 for (cnt = 0; cnt < 3; cnt++) { 4843 dscr = (union dscrptr *) context.anchors[cnt]; 4844 loc = layout.anchors[cnt]; 4845 if ((error = udf_write_dscr_phys(dscr, loc, 1))) { 4846 err(1, "ERR!"); 4847 return error; 4848 } 4849 4850 /* sequential media has only one anchor */ 4851 if (format_flags & FORMAT_SEQUENTIAL) 4852 break; 4853 } 4854 4855 /* write out main and secondary VRS */ 4856 for (sectcopy = 1; sectcopy <= 2; sectcopy++) { 4857 loc = (sectcopy == 1) ? layout.vds1 : layout.vds2; 4858 4859 /* primary volume descriptor */ 4860 dscr = (union dscrptr *) context.primary_vol; 4861 error = udf_write_dscr_phys(dscr, loc, 1); 4862 if (error) 4863 return error; 4864 loc++; 4865 4866 /* partition descriptor(s) */ 4867 for (cnt = 0; cnt < UDF_PARTITIONS; cnt++) { 4868 dscr = (union dscrptr *) context.partitions[cnt]; 4869 if (dscr) { 4870 error = udf_write_dscr_phys(dscr, loc, 1); 4871 if (error) 4872 return error; 4873 loc++; 4874 } 4875 } 4876 4877 /* unallocated space descriptor */ 4878 dscr = (union dscrptr *) context.unallocated; 4879 error = udf_write_dscr_phys(dscr, loc, 1); 4880 if (error) 4881 return error; 4882 loc++; 4883 4884 /* logical volume descriptor */ 4885 dscr = (union dscrptr *) context.logical_vol; 4886 error = udf_write_dscr_phys(dscr, loc, 1); 4887 if (error) 4888 return error; 4889 loc++; 4890 4891 /* implementation use descriptor */ 4892 dscr = (union dscrptr *) context.implementation; 4893 error = udf_write_dscr_phys(dscr, loc, 1); 4894 if (error) 4895 return error; 4896 loc++; 4897 4898 /* terminator descriptor */ 4899 error = udf_write_dscr_phys(terminator_dscr, loc, 1); 4900 if (error) 4901 return error; 4902 loc++; 4903 } 4904 4905 /* writeout the two spareable table descriptors (if needed) */ 4906 if (format_flags & FORMAT_SPAREABLE) { 4907 for (sectcopy = 1; sectcopy <= 2; sectcopy++) { 4908 loc = (sectcopy == 1) ? layout.spt_1 : layout.spt_2; 4909 dscr = (union dscrptr *) context.sparing_table; 4910 len = udf_tagsize(dscr, context.sector_size) / 4911 context.sector_size; 4912 4913 /* writeout */ 4914 error = udf_write_dscr_phys(dscr, loc, len); 4915 if (error) 4916 return error; 4917 } 4918 } 4919 4920 /* 4921 * Create unallocated space bitmap descriptor. Sequential recorded 4922 * media report their own free/used space; no free/used space tables 4923 * should be recorded for these. 4924 */ 4925 if ((format_flags & (FORMAT_SEQUENTIAL | FORMAT_READONLY)) == 0) { 4926 error = udf_create_space_bitmap( 4927 layout.alloc_bitmap_dscr_size, 4928 layout.part_size_lba, 4929 &context.part_unalloc_bits[data_part]); 4930 if (error) 4931 return error; 4932 /* TODO: freed space bitmap if applicable */ 4933 4934 /* mark space allocated for the unallocated space bitmap */ 4935 udf_mark_allocated(layout.unalloc_space, data_part, 4936 layout.alloc_bitmap_dscr_size); 4937 } 4938 4939 /* 4940 * Create metadata partition file entries and allocate and init their 4941 * space and free space maps. 4942 */ 4943 if (format_flags & FORMAT_META) { 4944 error = udf_create_meta_files(); 4945 if (error) 4946 return error; 4947 4948 /* mark space allocated for meta partition and its bitmap */ 4949 udf_mark_allocated(layout.meta_file, data_part, 1); 4950 udf_mark_allocated(layout.meta_mirror, data_part, 1); 4951 udf_mark_allocated(layout.meta_part_start_lba, data_part, 4952 layout.meta_part_size_lba); 4953 4954 if (context.meta_bitmap) { 4955 /* metadata bitmap creation and accounting */ 4956 error = udf_create_space_bitmap( 4957 layout.meta_bitmap_dscr_size, 4958 layout.meta_part_size_lba, 4959 &context.part_unalloc_bits[metadata_part]); 4960 if (error) 4961 return error; 4962 4963 udf_mark_allocated(layout.meta_bitmap, data_part, 1); 4964 /* mark space allocated for the unallocated space bitmap */ 4965 udf_mark_allocated(layout.meta_bitmap_space, 4966 data_part, 4967 layout.meta_bitmap_dscr_size); 4968 } 4969 } 4970 4971 /* create logical volume integrity descriptor */ 4972 context.num_files = 0; 4973 context.num_directories = 0; 4974 integrity_type = UDF_INTEGRITY_OPEN; 4975 if ((error = udf_create_lvintd(integrity_type))) 4976 return error; 4977 4978 /* writeout initial open integrity sequence + terminator */ 4979 loc = layout.lvis; 4980 dscr = (union dscrptr *) context.logvol_integrity; 4981 error = udf_write_dscr_phys(dscr, loc, 1); 4982 if (error) 4983 return error; 4984 loc++; 4985 error = udf_write_dscr_phys(terminator_dscr, loc, 1); 4986 if (error) 4987 return error; 4988 4989 /* create VAT if needed */ 4990 if (format_flags & FORMAT_VAT) { 4991 context.vat_allocated = context.sector_size; 4992 context.vat_contents = malloc(context.vat_allocated); 4993 assert(context.vat_contents); 4994 4995 udf_prepend_VAT_file(); 4996 } 4997 4998 /* create FSD and writeout */ 4999 if ((error = udf_create_fsd())) 5000 return error; 5001 udf_mark_allocated(layout.fsd, metadata_part, 1); 5002 5003 dscr = (union dscrptr *) context.fileset_desc; 5004 error = udf_write_dscr_virt(dscr, layout.fsd, metadata_part, 1); 5005 5006 return error; 5007 } 5008 5009 5010 /* specific routine for newfs to create empty rootdirectory */ 5011 int 5012 udf_do_rootdir(void) 5013 { 5014 union dscrptr *root_dscr; 5015 int error; 5016 5017 /* create root directory and write out */ 5018 assert(context.unique_id == 0x10); 5019 context.unique_id = 0; 5020 if ((error = udf_create_new_rootdir(&root_dscr))) 5021 return error; 5022 udf_mark_allocated(layout.rootdir, context.metadata_part, 1); 5023 5024 error = udf_write_dscr_virt(root_dscr, 5025 layout.rootdir, context.metadata_part, 1); 5026 5027 free(root_dscr); 5028 5029 return error; 5030 } 5031 5032 5033 int 5034 udf_do_newfs_postfix(void) 5035 { 5036 union dscrptr *dscr; 5037 uint32_t loc, len; 5038 int data_part, metadata_part; 5039 int format_flags = context.format_flags; 5040 int error; 5041 5042 /* cache partition for we need it often */ 5043 data_part = context.data_part; 5044 metadata_part = context.metadata_part; 5045 5046 if ((format_flags & FORMAT_SEQUENTIAL) == 0) { 5047 /* update lvint and mark it closed */ 5048 udf_update_lvintd(UDF_INTEGRITY_CLOSED); 5049 5050 /* overwrite initial terminator */ 5051 loc = layout.lvis+1; 5052 dscr = (union dscrptr *) context.logvol_integrity; 5053 error = udf_write_dscr_phys(dscr, loc, 1); 5054 if (error) 5055 return error; 5056 loc++; 5057 5058 /* mark end of integrity descriptor sequence again */ 5059 error = udf_write_dscr_phys(terminator_dscr, loc, 1); 5060 if (error) 5061 return error; 5062 } 5063 5064 /* write out unallocated space bitmap on non sequential media */ 5065 if ((format_flags & (FORMAT_SEQUENTIAL | FORMAT_READONLY)) == 0) { 5066 /* writeout unallocated space bitmap */ 5067 loc = layout.unalloc_space; 5068 dscr = (union dscrptr *) (context.part_unalloc_bits[data_part]); 5069 len = layout.alloc_bitmap_dscr_size; 5070 error = udf_write_dscr_virt(dscr, loc, data_part, len); 5071 if (error) 5072 return error; 5073 } 5074 5075 if (format_flags & FORMAT_META) { 5076 loc = layout.meta_file; 5077 dscr = (union dscrptr *) context.meta_file; 5078 error = udf_write_dscr_virt(dscr, loc, data_part, 1); 5079 if (error) 5080 return error; 5081 5082 loc = layout.meta_mirror; 5083 dscr = (union dscrptr *) context.meta_mirror; 5084 error = udf_write_dscr_virt(dscr, loc, data_part, 1); 5085 if (error) 5086 return error; 5087 5088 if (context.meta_bitmap) { 5089 loc = layout.meta_bitmap; 5090 dscr = (union dscrptr *) context.meta_bitmap; 5091 error = udf_write_dscr_virt(dscr, loc, data_part, 1); 5092 if (error) 5093 return error; 5094 5095 /* writeout unallocated space bitmap */ 5096 loc = layout.meta_bitmap_space; 5097 dscr = (union dscrptr *) 5098 (context.part_unalloc_bits[metadata_part]); 5099 len = layout.meta_bitmap_dscr_size; 5100 error = udf_write_dscr_virt(dscr, loc, data_part, len); 5101 if (error) 5102 return error; 5103 } 5104 } 5105 5106 /* create and writeout a VAT */ 5107 if (format_flags & FORMAT_VAT) 5108 udf_writeout_VAT(); 5109 5110 /* done */ 5111 return 0; 5112 } 5113