1 /* $NetBSD: udf_create.c,v 1.25 2015/06/16 23:18:55 christos Exp $ */ 2 3 /* 4 * Copyright (c) 2006, 2008 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_create.c,v 1.25 2015/06/16 23:18:55 christos Exp $"); 34 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <stddef.h> 38 #include <string.h> 39 #include <errno.h> 40 #include <time.h> 41 #include <assert.h> 42 #include <err.h> 43 #include <sys/types.h> 44 #include <sys/param.h> 45 #include "unicode.h" 46 #include "udf_create.h" 47 48 49 #if 0 50 # ifndef DEBUG 51 # define DEBUG 52 # endif 53 #endif 54 55 /* 56 * NOTE that there is some overlap between this code and the udf kernel fs. 57 * This is intentially though it might better be factored out one day. 58 */ 59 60 void 61 udf_init_create_context(void) 62 { 63 /* clear */ 64 memset(&context, 0, sizeof(struct udf_create_context)); 65 66 /* fill with defaults currently known */ 67 context.dscrver = 3; 68 context.min_udf = 0x0102; 69 context.max_udf = 0x0260; 70 context.serialnum = 1; /* default */ 71 72 context.gmtoff = 0; 73 context.sector_size = 512; /* minimum for UDF */ 74 75 context.logvol_name = NULL; 76 context.primary_name = NULL; 77 context.volset_name = NULL; 78 context.fileset_name = NULL; 79 80 /* most basic identification */ 81 context.app_name = "*NetBSD"; 82 context.app_version_main = 0; 83 context.app_version_sub = 0; 84 context.impl_name = "*NetBSD"; 85 86 context.vds_seq = 0; /* first one starts with zero */ 87 88 /* Minimum value of 16 : UDF 3.2.1.1, 3.3.3.4. */ 89 context.unique_id = 0x10; 90 91 context.num_files = 0; 92 context.num_directories = 0; 93 94 context.data_part = 0; 95 context.metadata_part = 0; 96 context.metadata_alloc_pos = 0; 97 context.data_alloc_pos = 0; 98 } 99 100 101 /* version can be specified as 0xabc or a.bc */ 102 static int 103 parse_udfversion(const char *pos, uint32_t *version) { 104 int hex = 0; 105 char c1, c2, c3, c4; 106 107 *version = 0; 108 if (*pos == '0') { 109 pos++; 110 /* expect hex format */ 111 hex = 1; 112 if (*pos++ != 'x') 113 return 1; 114 } 115 116 c1 = *pos++; 117 if (c1 < '0' || c1 > '9') 118 return 1; 119 c1 -= '0'; 120 121 c2 = *pos++; 122 if (!hex) { 123 if (c2 != '.') 124 return 1; 125 c2 = *pos++; 126 } 127 if (c2 < '0' || c2 > '9') 128 return 1; 129 c2 -= '0'; 130 131 c3 = *pos++; 132 if (c3 < '0' || c3 > '9') 133 return 1; 134 c3 -= '0'; 135 136 c4 = *pos++; 137 if (c4 != 0) 138 return 1; 139 140 *version = c1 * 0x100 + c2 * 0x10 + c3; 141 return 0; 142 } 143 144 145 /* parse a given string for an udf version */ 146 int 147 a_udf_version(const char *s, const char *id_type) 148 { 149 uint32_t version; 150 151 if (parse_udfversion(s, &version)) 152 errx(1, "unknown %s id %s; specify as hex or float", id_type, s); 153 return version; 154 } 155 156 157 static uint32_t 158 udf_space_bitmap_len(uint32_t part_size) 159 { 160 return sizeof(struct space_bitmap_desc)-1 + 161 part_size/8; 162 } 163 164 165 static uint32_t 166 udf_bytes_to_sectors(uint64_t bytes) 167 { 168 uint32_t sector_size = layout.sector_size; 169 return (bytes + sector_size -1) / sector_size; 170 } 171 172 173 int 174 udf_calculate_disc_layout(int format_flags, int min_udf, 175 uint32_t wrtrack_skew, 176 uint32_t first_lba, uint32_t last_lba, 177 uint32_t sector_size, uint32_t blockingnr, 178 uint32_t sparable_blocks, float meta_fract) 179 { 180 uint64_t kbsize, bytes; 181 uint32_t sparable_blockingnr; 182 uint32_t align_blockingnr; 183 uint32_t pos, mpos; 184 185 /* clear */ 186 memset(&layout, 0, sizeof(layout)); 187 188 /* fill with parameters */ 189 layout.wrtrack_skew = wrtrack_skew; 190 layout.first_lba = first_lba; 191 layout.last_lba = last_lba; 192 layout.sector_size = sector_size; 193 layout.blockingnr = blockingnr; 194 layout.sparable_blocks = sparable_blocks; 195 196 /* start disc layouting */ 197 198 /* 199 * location of iso9660 vrs is defined as first sector AFTER 32kb, 200 * minimum `sector size' 2048 201 */ 202 layout.iso9660_vrs = ((32*1024 + sector_size - 1) / sector_size) 203 + first_lba; 204 205 /* anchor starts at specified offset in sectors */ 206 layout.anchors[0] = first_lba + 256; 207 if (format_flags & FORMAT_TRACK512) 208 layout.anchors[0] = first_lba + 512; 209 layout.anchors[1] = last_lba - 256; 210 layout.anchors[2] = last_lba; 211 212 /* update workable space */ 213 first_lba = layout.anchors[0] + blockingnr; 214 last_lba = layout.anchors[1] - 1; 215 216 /* XXX rest of anchor packet can be added to unallocated space descr */ 217 218 /* reserve space for VRS and VRS copy and associated tables */ 219 layout.vds_size = MAX(16, blockingnr); /* UDF 2.2.3.1+2 */ 220 layout.vds1 = first_lba; 221 first_lba += layout.vds_size; /* next packet */ 222 223 if (format_flags & FORMAT_SEQUENTIAL) { 224 /* for sequential, append them ASAP */ 225 layout.vds2 = first_lba; 226 first_lba += layout.vds_size; 227 } else { 228 layout.vds2 = layout.anchors[1] - layout.vds_size; 229 last_lba = layout.vds2 - 1; /* XXX -1 ?? */ 230 } 231 232 /* reserve space for logvol integrity sequence */ 233 layout.lvis_size = MAX(8192/sector_size, 2 * blockingnr); 234 if (format_flags & FORMAT_VAT) 235 layout.lvis_size = 2; 236 if (format_flags & FORMAT_WORM) 237 layout.lvis_size = 64 * blockingnr; 238 239 /* TODO skip bad blocks in LVID sequence; for now use f.e. */ 240 //first_lba+=128; 241 layout.lvis = first_lba; 242 first_lba += layout.lvis_size; 243 244 /* initial guess of UDF partition size */ 245 layout.part_start_lba = first_lba; 246 layout.part_size_lba = last_lba - layout.part_start_lba; 247 248 /* all non sequential media needs an unallocated space bitmap */ 249 layout.alloc_bitmap_dscr_size = 0; 250 if ((format_flags & (FORMAT_SEQUENTIAL | FORMAT_READONLY)) == 0) { 251 bytes = udf_space_bitmap_len(layout.part_size_lba); 252 layout.alloc_bitmap_dscr_size = udf_bytes_to_sectors(bytes); 253 254 /* XXX freed space map when applicable */ 255 } 256 257 /* 258 * Note that for (bug) compatibility with version UDF 2.00 (fixed in 259 * 2.01 and higher) the blocking size needs to be 32 sectors otherwise 260 * the drive's blockingnr. 261 */ 262 263 sparable_blockingnr = blockingnr; 264 if (min_udf <= 0x200) 265 sparable_blockingnr = 32; 266 267 align_blockingnr = blockingnr; 268 if (format_flags & (FORMAT_SPARABLE | FORMAT_META)) 269 align_blockingnr = sparable_blockingnr; 270 271 layout.align_blockingnr = align_blockingnr; 272 layout.sparable_blockingnr = sparable_blockingnr; 273 274 /* 275 * Align partition LBA space to blocking granularity. Not strickly 276 * nessisary for non sparables but safer for the VRS data since it is 277 * not updated sporadically 278 */ 279 280 if ((format_flags & (FORMAT_SEQUENTIAL | FORMAT_READONLY)) == 0) { 281 #ifdef DEBUG 282 printf("Lost %d slack sectors at start\n", UDF_ROUNDUP( 283 first_lba - wrtrack_skew, align_blockingnr) - 284 (first_lba - wrtrack_skew)); 285 printf("Lost %d slack sectors at end\n", 286 (first_lba - wrtrack_skew) - UDF_ROUNDDOWN( 287 first_lba - wrtrack_skew, align_blockingnr)); 288 #endif 289 290 first_lba = UDF_ROUNDUP( first_lba - wrtrack_skew, 291 align_blockingnr); 292 last_lba = UDF_ROUNDDOWN(last_lba - wrtrack_skew, 293 align_blockingnr); 294 } 295 296 if ((format_flags & FORMAT_SPARABLE) == 0) 297 layout.sparable_blocks = 0; 298 299 if (format_flags & FORMAT_SPARABLE) { 300 layout.sparable_area_size = 301 layout.sparable_blocks * sparable_blockingnr; 302 303 /* a sparing table descriptor is a whole blockingnr sectors */ 304 layout.sparing_table_dscr_lbas = sparable_blockingnr; 305 306 /* place the descriptors at the start and end of the area */ 307 layout.spt_1 = first_lba; 308 first_lba += layout.sparing_table_dscr_lbas; 309 310 layout.spt_2 = last_lba - layout.sparing_table_dscr_lbas; 311 last_lba -= layout.sparing_table_dscr_lbas; 312 313 /* allocate sparable section */ 314 layout.sparable_area = first_lba; 315 first_lba += layout.sparable_area_size; 316 } 317 318 /* update guess of UDF partition size */ 319 layout.part_start_lba = first_lba; 320 layout.part_size_lba = last_lba - layout.part_start_lba; 321 322 /* determine partition selection for data and metadata */ 323 context.data_part = 0; 324 context.metadata_part = context.data_part; 325 if ((format_flags & FORMAT_VAT) || (format_flags & FORMAT_META)) 326 context.metadata_part = context.data_part + 1; 327 328 /* 329 * Pick fixed logical space sector numbers for main FSD, rootdir and 330 * unallocated space. The reason for this pre-allocation is that they 331 * are referenced in the volume descriptor sequence and hence can't be 332 * allocated later. 333 */ 334 pos = 0; 335 layout.unalloc_space = pos; 336 pos += layout.alloc_bitmap_dscr_size; 337 338 /* claim metadata descriptors and partition space [UDF 2.2.10] */ 339 if (format_flags & FORMAT_META) { 340 /* note: all in backing partition space */ 341 layout.meta_file = pos++; 342 layout.meta_bitmap = pos++;; 343 layout.meta_mirror = layout.part_size_lba-1; 344 layout.meta_alignment = MAX(blockingnr, sparable_blockingnr); 345 layout.meta_blockingnr = MAX(layout.meta_alignment, 32); 346 347 /* calculate our partition length and store in sectors */ 348 layout.meta_part_size_lba = layout.part_size_lba * meta_fract; 349 layout.meta_part_size_lba = MAX(layout.meta_part_size_lba, 32); 350 layout.meta_part_size_lba = 351 UDF_ROUNDDOWN(layout.meta_part_size_lba, layout.meta_blockingnr); 352 353 /* calculate positions */ 354 bytes = udf_space_bitmap_len(layout.meta_part_size_lba); 355 layout.meta_bitmap_dscr_size = udf_bytes_to_sectors(bytes); 356 357 layout.meta_bitmap_space = pos; 358 pos += layout.meta_bitmap_dscr_size; 359 360 layout.meta_part_start_lba = UDF_ROUNDUP(pos, layout.meta_alignment); 361 } 362 363 mpos = (context.metadata_part == context.data_part) ? pos : 0; 364 layout.fsd = mpos; mpos += 1; 365 layout.rootdir = mpos; mpos += 1; 366 layout.vat = mpos; mpos += 1; /* if present */ 367 368 #if 0 369 printf("Summary so far\n"); 370 printf("\tiso9660_vrs\t\t%d\n", layout.iso9660_vrs); 371 printf("\tanchor0\t\t\t%d\n", layout.anchors[0]); 372 printf("\tanchor1\t\t\t%d\n", layout.anchors[1]); 373 printf("\tanchor2\t\t\t%d\n", layout.anchors[2]); 374 printf("\tvds_size\t\t%d\n", layout.vds_size); 375 printf("\tvds1\t\t\t%d\n", layout.vds1); 376 printf("\tvds2\t\t\t%d\n", layout.vds2); 377 printf("\tlvis_size\t\t%d\n", layout.lvis_size); 378 printf("\tlvis\t\t\t%d\n", layout.lvis); 379 if (format_flags & FORMAT_SPARABLE) { 380 printf("\tsparable size\t\t%d\n", layout.sparable_area_size); 381 printf("\tsparable\t\t%d\n", layout.sparable_area); 382 } 383 printf("\tpartition start lba\t%d\n", layout.part_start_lba); 384 printf("\tpartition size\t\t%d KiB, %d MiB\n", 385 (layout.part_size_lba * sector_size) / 1024, 386 (layout.part_size_lba * sector_size) / (1024*1024)); 387 if ((format_flags & FORMAT_SEQUENTIAL) == 0) { 388 printf("\tpart bitmap start\t%d\n", layout.unalloc_space); 389 printf("\t\tfor %d lba\n", layout.alloc_bitmap_dscr_size); 390 } 391 if (format_flags & FORMAT_META) { 392 printf("\tmeta blockingnr\t\t%d\n", layout.meta_blockingnr); 393 printf("\tmeta alignment\t\t%d\n", layout.meta_alignment); 394 printf("\tmeta size\t\t%d KiB, %d MiB\n", 395 (layout.meta_part_size_lba * sector_size) / 1024, 396 (layout.meta_part_size_lba * sector_size) / (1024*1024)); 397 printf("\tmeta file\t\t%d\n", layout.meta_file); 398 printf("\tmeta mirror\t\t%d\n", layout.meta_mirror); 399 printf("\tmeta bitmap\t\t%d\n", layout.meta_bitmap); 400 printf("\tmeta bitmap start\t%d\n", layout.meta_bitmap_space); 401 printf("\t\tfor %d lba\n", layout.meta_bitmap_dscr_size); 402 printf("\tmeta space start\t%d\n", layout.meta_part_start_lba); 403 printf("\t\tfor %d lba\n", layout.meta_part_size_lba); 404 } 405 printf("\n"); 406 #endif 407 408 kbsize = (uint64_t) last_lba * sector_size; 409 printf("Total space on this medium approx. " 410 "%"PRIu64" KiB, %"PRIu64" MiB\n", 411 kbsize/1024, kbsize/(1024*1024)); 412 kbsize = (uint64_t)(layout.part_size_lba - layout.alloc_bitmap_dscr_size 413 - layout.meta_bitmap_dscr_size) * sector_size; 414 printf("Free space on this volume approx. " 415 "%"PRIu64" KiB, %"PRIu64" MiB\n\n", 416 kbsize/1024, kbsize/(1024*1024)); 417 418 return 0; 419 } 420 421 422 int 423 udf_validate_tag_sum(union dscrptr *dscr) 424 { 425 struct desc_tag *tag = &dscr->tag; 426 uint8_t *pos, sum, cnt; 427 428 /* calculate TAG header checksum */ 429 pos = (uint8_t *) tag; 430 sum = 0; 431 432 for(cnt = 0; cnt < 16; cnt++) { 433 if (cnt != 4) sum += *pos; 434 pos++; 435 }; 436 tag->cksum = sum; /* 8 bit */ 437 438 return 0; 439 } 440 441 442 /* assumes sector number of descriptor to be allready present */ 443 int 444 udf_validate_tag_and_crc_sums(union dscrptr *dscr) 445 { 446 struct desc_tag *tag = &dscr->tag; 447 uint16_t crc; 448 449 /* check payload CRC if applicable */ 450 if (udf_rw16(tag->desc_crc_len) > 0) { 451 crc = udf_cksum(((uint8_t *) tag) + UDF_DESC_TAG_LENGTH, 452 udf_rw16(tag->desc_crc_len)); 453 tag->desc_crc = udf_rw16(crc); 454 }; 455 456 /* calculate TAG header checksum */ 457 return udf_validate_tag_sum(dscr); 458 } 459 460 461 void 462 udf_inittag(struct desc_tag *tag, int tagid, uint32_t loc) 463 { 464 tag->id = udf_rw16(tagid); 465 tag->descriptor_ver = udf_rw16(context.dscrver); 466 tag->cksum = 0; 467 tag->reserved = 0; 468 tag->serial_num = udf_rw16(context.serialnum); 469 tag->tag_loc = udf_rw32(loc); 470 } 471 472 473 int 474 udf_create_anchor(int num) 475 { 476 struct anchor_vdp *avdp; 477 uint32_t vds_extent_len = layout.vds_size * context.sector_size; 478 479 if ((avdp = calloc(1, context.sector_size)) == NULL) 480 return ENOMEM; 481 482 udf_inittag(&avdp->tag, TAGID_ANCHOR, layout.anchors[num]); 483 484 avdp->main_vds_ex.loc = udf_rw32(layout.vds1); 485 avdp->main_vds_ex.len = udf_rw32(vds_extent_len); 486 487 avdp->reserve_vds_ex.loc = udf_rw32(layout.vds2); 488 avdp->reserve_vds_ex.len = udf_rw32(vds_extent_len); 489 490 /* CRC length for an anchor is 512 - tag length; defined in Ecma 167 */ 491 avdp->tag.desc_crc_len = udf_rw16(512-UDF_DESC_TAG_LENGTH); 492 493 context.anchors[num] = avdp; 494 return 0; 495 } 496 497 498 void 499 udf_create_terminator(union dscrptr *dscr, uint32_t loc) 500 { 501 memset(dscr, 0, context.sector_size); 502 udf_inittag(&dscr->tag, TAGID_TERM, loc); 503 504 /* CRC length for an anchor is 512 - tag length; defined in Ecma 167 */ 505 dscr->tag.desc_crc_len = udf_rw16(512-UDF_DESC_TAG_LENGTH); 506 } 507 508 509 void 510 udf_osta_charset(struct charspec *charspec) 511 { 512 memset(charspec, 0, sizeof(*charspec)); 513 charspec->type = 0; 514 strcpy((char *) charspec->inf, "OSTA Compressed Unicode"); 515 } 516 517 518 void 519 udf_encode_osta_id(char *osta_id, uint16_t len, char *text) 520 { 521 uint16_t u16_name[1024]; 522 uint8_t *pos; 523 uint16_t *pos16; 524 525 memset(osta_id, 0, len); 526 if (!text || (strlen(text) == 0)) return; 527 528 memset(u16_name, 0, sizeof(uint16_t) * 1023); 529 530 /* convert ascii to 16 bits unicode */ 531 pos = (uint8_t *) text; 532 pos16 = u16_name; 533 while (*pos) { 534 *pos16 = *pos; 535 pos++; pos16++; 536 }; 537 *pos16 = 0; 538 539 udf_CompressUnicode(len, 8, (unicode_t *) u16_name, (byte *) osta_id); 540 541 /* Ecma 167/7.2.13 states that length is recorded in the last byte */ 542 osta_id[len-1] = strlen(text)+1; 543 } 544 545 546 /* first call udf_set_regid and then the suffix */ 547 void 548 udf_set_regid(struct regid *regid, char const *name) 549 { 550 memset(regid, 0, sizeof(*regid)); 551 regid->flags = 0; /* not dirty and not protected */ 552 strcpy((char *) regid->id, name); 553 } 554 555 556 void 557 udf_add_domain_regid(struct regid *regid) 558 { 559 uint16_t *ver; 560 561 ver = (uint16_t *) regid->id_suffix; 562 *ver = udf_rw16(context.min_udf); 563 } 564 565 566 void 567 udf_add_udf_regid(struct regid *regid) 568 { 569 uint16_t *ver; 570 571 ver = (uint16_t *) regid->id_suffix; 572 *ver = udf_rw16(context.min_udf); 573 574 regid->id_suffix[2] = 4; /* unix */ 575 regid->id_suffix[3] = 8; /* NetBSD */ 576 } 577 578 579 void 580 udf_add_impl_regid(struct regid *regid) 581 { 582 regid->id_suffix[0] = 4; /* unix */ 583 regid->id_suffix[1] = 8; /* NetBSD */ 584 } 585 586 587 void 588 udf_add_app_regid(struct regid *regid) 589 { 590 regid->id_suffix[0] = context.app_version_main; 591 regid->id_suffix[1] = context.app_version_sub; 592 } 593 594 595 /* 596 * Fill in timestamp structure based on clock_gettime(). Time is reported back 597 * as a time_t accompanied with a nano second field. 598 * 599 * The husec, usec and csec could be relaxed in type. 600 */ 601 static void 602 udf_timespec_to_timestamp(struct timespec *timespec, struct timestamp *timestamp) 603 { 604 struct tm tm; 605 uint64_t husec, usec, csec; 606 607 memset(timestamp, 0, sizeof(*timestamp)); 608 gmtime_r(×pec->tv_sec, &tm); 609 610 /* 611 * Time type and time zone : see ECMA 1/7.3, UDF 2., 2.1.4.1, 3.1.1. 612 * 613 * Lower 12 bits are two complement signed timezone offset if bit 12 614 * (method 1) is clear. Otherwise if bit 12 is set, specify timezone 615 * offset to -2047 i.e. unsigned `zero' 616 */ 617 618 /* set method 1 for CUT/GMT */ 619 timestamp->type_tz = udf_rw16((1<<12) + 0); 620 timestamp->year = udf_rw16(tm.tm_year + 1900); 621 timestamp->month = tm.tm_mon + 1; /* `tm' uses 0..11 for months */ 622 timestamp->day = tm.tm_mday; 623 timestamp->hour = tm.tm_hour; 624 timestamp->minute = tm.tm_min; 625 timestamp->second = tm.tm_sec; 626 627 usec = (timespec->tv_nsec + 500) / 1000; /* round */ 628 husec = usec / 100; 629 usec -= husec * 100; /* only 0-99 in usec */ 630 csec = husec / 100; /* only 0-99 in csec */ 631 husec -= csec * 100; /* only 0-99 in husec */ 632 633 /* in rare cases there is overflow in csec */ 634 csec = MIN(99, csec); 635 husec = MIN(99, husec); 636 usec = MIN(99, usec); 637 638 timestamp->centisec = csec; 639 timestamp->hund_usec = husec; 640 timestamp->usec = usec; 641 } 642 643 644 void 645 udf_set_timestamp_now(struct timestamp *timestamp) 646 { 647 struct timespec now; 648 649 #ifdef CLOCK_REALTIME 650 (void)clock_gettime(CLOCK_REALTIME, &now); 651 #else 652 struct timeval time_of_day; 653 654 (void)gettimeofday(&time_of_day, NULL); 655 now.tv_sec = time_of_day.tv_sec; 656 now.tv_nsec = time_of_day.tv_usec * 1000; 657 #endif 658 udf_timespec_to_timestamp(&now, timestamp); 659 } 660 661 662 /* some code copied from sys/fs/udf */ 663 664 static void 665 udf_set_timestamp(struct timestamp *timestamp, time_t value) 666 { 667 struct timespec t; 668 669 memset(&t, 0, sizeof(struct timespec)); 670 t.tv_sec = value; 671 t.tv_nsec = 0; 672 udf_timespec_to_timestamp(&t, timestamp); 673 } 674 675 676 static uint32_t 677 unix_mode_to_udf_perm(mode_t mode) 678 { 679 uint32_t perm; 680 681 perm = ((mode & S_IRWXO) ); 682 perm |= ((mode & S_IRWXG) << 2); 683 perm |= ((mode & S_IRWXU) << 4); 684 perm |= ((mode & S_IWOTH) << 3); 685 perm |= ((mode & S_IWGRP) << 5); 686 perm |= ((mode & S_IWUSR) << 7); 687 688 return perm; 689 } 690 691 /* end of copied code */ 692 693 694 int 695 udf_create_primaryd(void) 696 { 697 struct pri_vol_desc *pri; 698 uint16_t crclen; 699 700 pri = calloc(1, context.sector_size); 701 if (pri == NULL) 702 return ENOMEM; 703 704 memset(pri, 0, context.sector_size); 705 udf_inittag(&pri->tag, TAGID_PRI_VOL, /* loc */ 0); 706 pri->seq_num = udf_rw32(context.vds_seq); context.vds_seq++; 707 708 pri->pvd_num = udf_rw32(0); /* default serial */ 709 udf_encode_osta_id(pri->vol_id, 32, context.primary_name); 710 711 /* set defaults for single disc volumes as UDF prescribes */ 712 pri->vds_num = udf_rw16(1); 713 pri->max_vol_seq = udf_rw16(1); 714 pri->ichg_lvl = udf_rw16(2); 715 pri->max_ichg_lvl = udf_rw16(3); 716 pri->flags = udf_rw16(0); 717 718 pri->charset_list = udf_rw32(1); /* only CS0 */ 719 pri->max_charset_list = udf_rw32(1); /* only CS0 */ 720 721 udf_encode_osta_id(pri->volset_id, 128, context.volset_name); 722 udf_osta_charset(&pri->desc_charset); 723 udf_osta_charset(&pri->explanatory_charset); 724 725 udf_set_regid(&pri->app_id, context.app_name); 726 udf_add_app_regid(&pri->app_id); 727 728 udf_set_regid(&pri->imp_id, context.impl_name); 729 udf_add_impl_regid(&pri->imp_id); 730 731 udf_set_timestamp_now(&pri->time); 732 733 crclen = sizeof(struct pri_vol_desc) - UDF_DESC_TAG_LENGTH; 734 pri->tag.desc_crc_len = udf_rw16(crclen); 735 736 context.primary_vol = pri; 737 738 return 0; 739 } 740 741 742 /* XXX no support for unallocated or freed space tables yet (!) */ 743 int 744 udf_create_partitiond(int part_num, int part_accesstype) 745 { 746 struct part_desc *pd; 747 struct part_hdr_desc *phd; 748 uint32_t sector_size, bitmap_bytes; 749 uint16_t crclen; 750 751 sector_size = context.sector_size; 752 bitmap_bytes = layout.alloc_bitmap_dscr_size * sector_size; 753 754 if (context.partitions[part_num]) { 755 printf("Internal error: partition %d allready defined\n", 756 part_num); 757 return EINVAL; 758 } 759 760 pd = calloc(1, context.sector_size); 761 if (pd == NULL) 762 return ENOMEM; 763 phd = &pd->_impl_use.part_hdr; 764 765 udf_inittag(&pd->tag, TAGID_PARTITION, /* loc */ 0); 766 pd->seq_num = udf_rw32(context.vds_seq); context.vds_seq++; 767 768 pd->flags = udf_rw16(1); /* allocated */ 769 pd->part_num = udf_rw16(part_num); /* only one physical partition */ 770 771 if (context.dscrver == 2) { 772 udf_set_regid(&pd->contents, "+NSR02"); 773 } else { 774 udf_set_regid(&pd->contents, "+NSR03"); 775 } 776 udf_add_app_regid(&pd->contents); 777 778 phd->unalloc_space_bitmap.len = udf_rw32(bitmap_bytes); 779 phd->unalloc_space_bitmap.lb_num = udf_rw32(layout.unalloc_space); 780 781 if (layout.freed_space) { 782 phd->freed_space_bitmap.len = udf_rw32(bitmap_bytes); 783 phd->freed_space_bitmap.lb_num = udf_rw32(layout.freed_space); 784 } 785 786 pd->access_type = udf_rw32(part_accesstype); 787 pd->start_loc = udf_rw32(layout.part_start_lba); 788 pd->part_len = udf_rw32(layout.part_size_lba); 789 790 udf_set_regid(&pd->imp_id, context.impl_name); 791 udf_add_impl_regid(&pd->imp_id); 792 793 crclen = sizeof(struct part_desc) - UDF_DESC_TAG_LENGTH; 794 pd->tag.desc_crc_len = udf_rw16(crclen); 795 796 context.partitions[part_num] = pd; 797 798 return 0; 799 } 800 801 802 int 803 udf_create_unalloc_spaced(void) 804 { 805 struct unalloc_sp_desc *usd; 806 uint16_t crclen; 807 808 usd = calloc(1, context.sector_size); 809 if (usd == NULL) 810 return ENOMEM; 811 812 udf_inittag(&usd->tag, TAGID_UNALLOC_SPACE, /* loc */ 0); 813 usd->seq_num = udf_rw32(context.vds_seq); context.vds_seq++; 814 815 /* no default entries */ 816 usd->alloc_desc_num = udf_rw32(0); /* no entries */ 817 818 crclen = sizeof(struct unalloc_sp_desc) - sizeof(struct extent_ad); 819 crclen -= UDF_DESC_TAG_LENGTH; 820 usd->tag.desc_crc_len = udf_rw16(crclen); 821 822 context.unallocated = usd; 823 824 return 0; 825 } 826 827 828 static int 829 udf_create_base_logical_dscr(void) 830 { 831 struct logvol_desc *lvd; 832 uint32_t sector_size; 833 uint16_t crclen; 834 835 sector_size = context.sector_size; 836 837 lvd = calloc(1, sector_size); 838 if (lvd == NULL) 839 return ENOMEM; 840 841 udf_inittag(&lvd->tag, TAGID_LOGVOL, /* loc */ 0); 842 lvd->seq_num = udf_rw32(context.vds_seq); context.vds_seq++; 843 844 udf_osta_charset(&lvd->desc_charset); 845 udf_encode_osta_id(lvd->logvol_id, 128, context.logvol_name); 846 lvd->lb_size = udf_rw32(context.sector_size); 847 848 udf_set_regid(&lvd->domain_id, "*OSTA UDF Compliant"); 849 udf_add_domain_regid(&lvd->domain_id); 850 851 /* no partition mappings/entries yet */ 852 lvd->mt_l = udf_rw32(0); 853 lvd->n_pm = udf_rw32(0); 854 855 udf_set_regid(&lvd->imp_id, context.impl_name); 856 udf_add_impl_regid(&lvd->imp_id); 857 858 lvd->integrity_seq_loc.loc = udf_rw32(layout.lvis); 859 lvd->integrity_seq_loc.len = udf_rw32(layout.lvis_size * sector_size); 860 861 /* just one fsd for now */ 862 lvd->lv_fsd_loc.len = udf_rw32(sector_size); 863 lvd->lv_fsd_loc.loc.part_num = udf_rw32(context.metadata_part); 864 lvd->lv_fsd_loc.loc.lb_num = udf_rw32(layout.fsd); 865 866 crclen = sizeof(struct logvol_desc) - 1 - UDF_DESC_TAG_LENGTH; 867 lvd->tag.desc_crc_len = udf_rw16(crclen); 868 869 context.logical_vol = lvd; 870 context.vtop_tp[UDF_VTOP_RAWPART] = UDF_VTOP_TYPE_RAW; 871 context.vtop_offset[UDF_VTOP_RAWPART] = 0; 872 873 return 0; 874 } 875 876 877 static void 878 udf_add_logvol_part_physical(uint16_t phys_part) 879 { 880 struct logvol_desc *logvol = context.logical_vol; 881 union udf_pmap *pmap; 882 uint8_t *pmap_pos; 883 uint16_t crclen; 884 uint32_t pmap1_size, log_part; 885 886 log_part = udf_rw32(logvol->n_pm); 887 pmap_pos = logvol->maps + udf_rw32(logvol->mt_l); 888 pmap1_size = sizeof(struct part_map_1); 889 890 pmap = (union udf_pmap *) pmap_pos; 891 pmap->pm1.type = 1; 892 pmap->pm1.len = sizeof(struct part_map_1); 893 pmap->pm1.vol_seq_num = udf_rw16(1); /* no multi-volume */ 894 pmap->pm1.part_num = udf_rw16(phys_part); 895 896 context.vtop [log_part] = phys_part; 897 context.vtop_tp [log_part] = UDF_VTOP_TYPE_PHYS; 898 context.vtop_offset[log_part] = layout.part_start_lba; 899 context.part_size[log_part] = layout.part_size_lba; 900 context.part_free[log_part] = layout.part_size_lba; 901 902 /* increment number of partitions and length */ 903 logvol->n_pm = udf_rw32(log_part + 1); 904 logvol->mt_l = udf_rw32(udf_rw32(logvol->mt_l) + pmap1_size); 905 906 crclen = udf_rw16(logvol->tag.desc_crc_len) + pmap1_size; 907 logvol->tag.desc_crc_len = udf_rw16(crclen); 908 } 909 910 911 static void 912 udf_add_logvol_part_virtual(uint16_t phys_part) 913 { 914 union udf_pmap *pmap; 915 struct logvol_desc *logvol = context.logical_vol; 916 uint8_t *pmap_pos; 917 uint16_t crclen; 918 uint32_t pmapv_size, log_part; 919 920 log_part = udf_rw32(logvol->n_pm); 921 pmap_pos = logvol->maps + udf_rw32(logvol->mt_l); 922 pmapv_size = sizeof(struct part_map_2); 923 924 pmap = (union udf_pmap *) pmap_pos; 925 pmap->pmv.type = 2; 926 pmap->pmv.len = pmapv_size; 927 928 udf_set_regid(&pmap->pmv.id, "*UDF Virtual Partition"); 929 udf_add_udf_regid(&pmap->pmv.id); 930 931 pmap->pmv.vol_seq_num = udf_rw16(1); /* no multi-volume */ 932 pmap->pmv.part_num = udf_rw16(phys_part); 933 934 context.vtop [log_part] = phys_part; 935 context.vtop_tp [log_part] = UDF_VTOP_TYPE_VIRT; 936 context.vtop_offset[log_part] = context.vtop_offset[phys_part]; 937 context.part_size[log_part] = 0xffffffff; 938 context.part_free[log_part] = 0xffffffff; 939 940 /* increment number of partitions and length */ 941 logvol->n_pm = udf_rw32(log_part + 1); 942 logvol->mt_l = udf_rw32(udf_rw32(logvol->mt_l) + pmapv_size); 943 944 crclen = udf_rw16(logvol->tag.desc_crc_len) + pmapv_size; 945 logvol->tag.desc_crc_len = udf_rw16(crclen); 946 } 947 948 949 /* sparing table size is in bytes */ 950 static void 951 udf_add_logvol_part_sparable(uint16_t phys_part) 952 { 953 union udf_pmap *pmap; 954 struct logvol_desc *logvol = context.logical_vol; 955 uint32_t *st_pos, sparable_bytes, pmaps_size; 956 uint8_t *pmap_pos, num; 957 uint16_t crclen; 958 uint32_t log_part; 959 960 log_part = udf_rw32(logvol->n_pm); 961 pmap_pos = logvol->maps + udf_rw32(logvol->mt_l); 962 pmaps_size = sizeof(struct part_map_2); 963 sparable_bytes = layout.sparable_area_size * context.sector_size; 964 965 pmap = (union udf_pmap *) pmap_pos; 966 pmap->pms.type = 2; 967 pmap->pms.len = pmaps_size; 968 969 udf_set_regid(&pmap->pmv.id, "*UDF Sparable Partition"); 970 udf_add_udf_regid(&pmap->pmv.id); 971 972 pmap->pms.vol_seq_num = udf_rw16(1); /* no multi-volume */ 973 pmap->pms.part_num = udf_rw16(phys_part); 974 975 pmap->pms.packet_len = udf_rw16(layout.sparable_blockingnr); 976 pmap->pms.st_size = udf_rw32(sparable_bytes); 977 978 /* enter spare tables */ 979 st_pos = &pmap->pms.st_loc[0]; 980 *st_pos++ = udf_rw32(layout.spt_1); 981 *st_pos++ = udf_rw32(layout.spt_2); 982 983 num = 2; 984 if (layout.spt_2 == 0) num--; 985 if (layout.spt_1 == 0) num--; 986 pmap->pms.n_st = num; /* 8 bit */ 987 988 /* the vtop_offset needs to explicitly set since there is no phys. */ 989 context.vtop [log_part] = phys_part; 990 context.vtop_tp [log_part] = UDF_VTOP_TYPE_SPARABLE; 991 context.vtop_offset[log_part] = layout.part_start_lba; 992 context.part_size[log_part] = layout.part_size_lba; 993 context.part_free[log_part] = layout.part_size_lba; 994 995 /* increment number of partitions and length */ 996 logvol->n_pm = udf_rw32(log_part + 1); 997 logvol->mt_l = udf_rw32(udf_rw32(logvol->mt_l) + pmaps_size); 998 999 crclen = udf_rw16(logvol->tag.desc_crc_len) + pmaps_size; 1000 logvol->tag.desc_crc_len = udf_rw16(crclen); 1001 } 1002 1003 1004 int 1005 udf_create_sparing_tabled(void) 1006 { 1007 struct udf_sparing_table *spt; 1008 struct spare_map_entry *sme; 1009 uint32_t loc, cnt; 1010 uint32_t crclen; /* XXX: should be 16; need to detect overflow */ 1011 1012 spt = calloc(context.sector_size, layout.sparing_table_dscr_lbas); 1013 if (spt == NULL) 1014 return ENOMEM; 1015 1016 /* a sparing table descriptor is a whole sparable_blockingnr sectors */ 1017 udf_inittag(&spt->tag, TAGID_SPARING_TABLE, /* loc */ 0); 1018 1019 udf_set_regid(&spt->id, "*UDF Sparing Table"); 1020 udf_add_udf_regid(&spt->id); 1021 1022 spt->rt_l = udf_rw16(layout.sparable_blocks); 1023 spt->seq_num = udf_rw32(0); /* first generation */ 1024 1025 for (cnt = 0; cnt < layout.sparable_blocks; cnt++) { 1026 sme = &spt->entries[cnt]; 1027 loc = layout.sparable_area + cnt * layout.sparable_blockingnr; 1028 sme->org = udf_rw32(0xffffffff); /* open for reloc */ 1029 sme->map = udf_rw32(loc); 1030 } 1031 1032 /* calculate crc len for actual size */ 1033 crclen = sizeof(struct udf_sparing_table) - UDF_DESC_TAG_LENGTH; 1034 crclen += (layout.sparable_blocks-1) * sizeof(struct spare_map_entry); 1035 /* XXX ensure crclen doesn't exceed UINT16_MAX ? */ 1036 spt->tag.desc_crc_len = udf_rw16((uint16_t)crclen); 1037 1038 context.sparing_table = spt; 1039 1040 return 0; 1041 } 1042 1043 1044 static void 1045 udf_add_logvol_part_meta(uint16_t phys_part) 1046 { 1047 union udf_pmap *pmap; 1048 struct logvol_desc *logvol = context.logical_vol; 1049 uint8_t *pmap_pos; 1050 uint32_t pmapv_size, log_part; 1051 uint16_t crclen; 1052 1053 log_part = udf_rw32(logvol->n_pm); 1054 pmap_pos = logvol->maps + udf_rw32(logvol->mt_l); 1055 pmapv_size = sizeof(struct part_map_2); 1056 1057 pmap = (union udf_pmap *) pmap_pos; 1058 pmap->pmm.type = 2; 1059 pmap->pmm.len = pmapv_size; 1060 1061 udf_set_regid(&pmap->pmm.id, "*UDF Metadata Partition"); 1062 udf_add_udf_regid(&pmap->pmm.id); 1063 1064 pmap->pmm.vol_seq_num = udf_rw16(1); /* no multi-volume */ 1065 pmap->pmm.part_num = udf_rw16(phys_part); 1066 1067 /* fill in meta data file(s) and alloc/alignment unit sizes */ 1068 pmap->pmm.meta_file_lbn = udf_rw32(layout.meta_file); 1069 pmap->pmm.meta_mirror_file_lbn = udf_rw32(layout.meta_mirror); 1070 pmap->pmm.meta_bitmap_file_lbn = udf_rw32(layout.meta_bitmap); 1071 pmap->pmm.alloc_unit_size = udf_rw32(layout.meta_blockingnr); 1072 pmap->pmm.alignment_unit_size = udf_rw16(layout.meta_alignment); 1073 pmap->pmm.flags = 0; /* METADATA_DUPLICATED */ 1074 1075 context.vtop [log_part] = phys_part; 1076 context.vtop_tp [log_part] = UDF_VTOP_TYPE_META; 1077 context.vtop_offset[log_part] = 1078 context.vtop_offset[phys_part] + layout.meta_part_start_lba; 1079 context.part_size[log_part] = layout.meta_part_size_lba; 1080 context.part_free[log_part] = layout.meta_part_size_lba; 1081 1082 /* increment number of partitions and length */ 1083 logvol->n_pm = udf_rw32(log_part + 1); 1084 logvol->mt_l = udf_rw32(udf_rw32(logvol->mt_l) + pmapv_size); 1085 1086 crclen = udf_rw16(logvol->tag.desc_crc_len) + pmapv_size; 1087 logvol->tag.desc_crc_len = udf_rw16(crclen); 1088 } 1089 1090 1091 int 1092 udf_create_logical_dscr(int format_flags) 1093 { 1094 int error; 1095 1096 if ((error = udf_create_base_logical_dscr())) 1097 return error; 1098 1099 /* we pass data_part for there might be a read-only part one day */ 1100 if (format_flags & FORMAT_SPARABLE) { 1101 /* sparable partition mapping has no physical mapping */ 1102 udf_add_logvol_part_sparable(context.data_part); 1103 } else { 1104 udf_add_logvol_part_physical(context.data_part); 1105 } 1106 1107 if (format_flags & FORMAT_VAT) { 1108 /* add VAT virtual mapping; reflects on datapart */ 1109 udf_add_logvol_part_virtual(context.data_part); 1110 } 1111 if (format_flags & FORMAT_META) { 1112 /* add META data mapping; reflects on datapart */ 1113 udf_add_logvol_part_meta(context.data_part); 1114 } 1115 1116 return 0; 1117 } 1118 1119 1120 int 1121 udf_create_impvold(char *field1, char *field2, char *field3) 1122 { 1123 struct impvol_desc *ivd; 1124 struct udf_lv_info *lvi; 1125 uint16_t crclen; 1126 1127 ivd = calloc(1, context.sector_size); 1128 if (ivd == NULL) 1129 return ENOMEM; 1130 lvi = &ivd->_impl_use.lv_info; 1131 1132 udf_inittag(&ivd->tag, TAGID_IMP_VOL, /* loc */ 0); 1133 ivd->seq_num = udf_rw32(context.vds_seq); context.vds_seq++; 1134 1135 udf_set_regid(&ivd->impl_id, "*UDF LV Info"); 1136 udf_add_udf_regid(&ivd->impl_id); 1137 1138 /* fill in UDF specific part */ 1139 udf_osta_charset(&lvi->lvi_charset); 1140 udf_encode_osta_id(lvi->logvol_id, 128, context.logvol_name); 1141 1142 udf_encode_osta_id(lvi->lvinfo1, 36, field1); 1143 udf_encode_osta_id(lvi->lvinfo2, 36, field2); 1144 udf_encode_osta_id(lvi->lvinfo3, 36, field3); 1145 1146 udf_set_regid(&lvi->impl_id, context.impl_name); 1147 udf_add_impl_regid(&lvi->impl_id); 1148 1149 crclen = sizeof(struct impvol_desc) - UDF_DESC_TAG_LENGTH; 1150 ivd->tag.desc_crc_len = udf_rw16(crclen); 1151 1152 context.implementation = ivd; 1153 1154 return 0; 1155 } 1156 1157 1158 /* XXX might need to be sanitised a bit later */ 1159 void 1160 udf_update_lvintd(int type) 1161 { 1162 struct logvol_int_desc *lvid; 1163 struct udf_logvol_info *lvinfo; 1164 struct logvol_desc *logvol; 1165 uint32_t *pos; 1166 uint32_t cnt, l_iu, num_partmappings; 1167 uint32_t crclen; /* XXX: should be 16; need to detect overflow */ 1168 1169 lvid = context.logvol_integrity; 1170 logvol = context.logical_vol; 1171 1172 assert(lvid); 1173 assert(logvol); 1174 1175 lvid->integrity_type = udf_rw32(type); 1176 1177 num_partmappings = udf_rw32(logvol->n_pm); 1178 1179 udf_set_timestamp_now(&lvid->time); 1180 1181 lvinfo = (struct udf_logvol_info *) 1182 (lvid->tables + num_partmappings * 2); 1183 udf_set_regid(&lvinfo->impl_id, context.impl_name); 1184 udf_add_impl_regid(&lvinfo->impl_id); 1185 1186 lvinfo->num_files = udf_rw32(context.num_files); 1187 lvinfo->num_directories = udf_rw32(context.num_directories); 1188 1189 lvid->lvint_next_unique_id = udf_rw64(context.unique_id); 1190 1191 /* XXX sane enough ? */ 1192 lvinfo->min_udf_readver = udf_rw16(context.min_udf); 1193 lvinfo->min_udf_writever = udf_rw16(context.min_udf); 1194 lvinfo->max_udf_writever = udf_rw16(context.max_udf); 1195 1196 lvid->num_part = udf_rw32(num_partmappings); 1197 1198 /* no impl. use needed */ 1199 l_iu = sizeof(struct udf_logvol_info); 1200 lvid->l_iu = udf_rw32(l_iu); 1201 1202 pos = &lvid->tables[0]; 1203 for (cnt = 0; cnt < num_partmappings; cnt++) { 1204 *pos++ = udf_rw32(context.part_free[cnt]); 1205 } 1206 for (cnt = 0; cnt < num_partmappings; cnt++) { 1207 *pos++ = udf_rw32(context.part_size[cnt]); 1208 } 1209 1210 crclen = sizeof(struct logvol_int_desc) -4 -UDF_DESC_TAG_LENGTH + l_iu; 1211 crclen += num_partmappings * 2 * 4; 1212 /* XXX ensure crclen doesn't exceed UINT16_MAX ? */ 1213 lvid->tag.desc_crc_len = udf_rw16(crclen); 1214 1215 context.logvol_info = lvinfo; 1216 } 1217 1218 1219 int 1220 udf_create_lvintd(int type) 1221 { 1222 struct logvol_int_desc *lvid; 1223 1224 lvid = calloc(1, context.sector_size); 1225 if (lvid == NULL) 1226 return ENOMEM; 1227 1228 udf_inittag(&lvid->tag, TAGID_LOGVOL_INTEGRITY, /* loc */ 0); 1229 1230 context.logvol_integrity = lvid; 1231 1232 udf_update_lvintd(type); 1233 1234 return 0; 1235 } 1236 1237 1238 int 1239 udf_create_fsd(void) 1240 { 1241 struct fileset_desc *fsd; 1242 uint16_t crclen; 1243 1244 fsd = calloc(1, context.sector_size); 1245 if (fsd == NULL) 1246 return ENOMEM; 1247 1248 udf_inittag(&fsd->tag, TAGID_FSD, /* loc */ 0); 1249 1250 udf_set_timestamp_now(&fsd->time); 1251 fsd->ichg_lvl = udf_rw16(3); /* UDF 2.3.2.1 */ 1252 fsd->max_ichg_lvl = udf_rw16(3); /* UDF 2.3.2.2 */ 1253 1254 fsd->charset_list = udf_rw32(1); /* only CS0 */ 1255 fsd->max_charset_list = udf_rw32(1); /* only CS0 */ 1256 1257 fsd->fileset_num = udf_rw32(0); /* only one fsd */ 1258 fsd->fileset_desc_num = udf_rw32(0); /* origional */ 1259 1260 udf_osta_charset(&fsd->logvol_id_charset); 1261 udf_encode_osta_id(fsd->logvol_id, 128, context.logvol_name); 1262 1263 udf_osta_charset(&fsd->fileset_charset); 1264 udf_encode_osta_id(fsd->fileset_id, 32, context.fileset_name); 1265 1266 /* copyright file and abstract file names obmitted */ 1267 1268 fsd->rootdir_icb.len = udf_rw32(context.sector_size); 1269 fsd->rootdir_icb.loc.lb_num = udf_rw32(layout.rootdir); 1270 fsd->rootdir_icb.loc.part_num = udf_rw16(context.metadata_part); 1271 1272 udf_set_regid(&fsd->domain_id, "*OSTA UDF Compliant"); 1273 udf_add_domain_regid(&fsd->domain_id); 1274 1275 /* next_ex stays zero */ 1276 /* no system streamdirs yet */ 1277 1278 crclen = sizeof(struct fileset_desc) - UDF_DESC_TAG_LENGTH; 1279 fsd->tag.desc_crc_len = udf_rw16(crclen); 1280 1281 context.fileset_desc = fsd; 1282 1283 return 0; 1284 } 1285 1286 1287 int 1288 udf_create_space_bitmap(uint32_t dscr_size, uint32_t part_size_lba, 1289 struct space_bitmap_desc **sbdp) 1290 { 1291 struct space_bitmap_desc *sbd; 1292 uint32_t cnt; 1293 uint16_t crclen; 1294 1295 *sbdp = NULL; 1296 sbd = calloc(context.sector_size, dscr_size); 1297 if (sbd == NULL) 1298 return ENOMEM; 1299 1300 udf_inittag(&sbd->tag, TAGID_SPACE_BITMAP, /* loc */ 0); 1301 1302 sbd->num_bits = udf_rw32(part_size_lba); 1303 sbd->num_bytes = udf_rw32((part_size_lba + 7)/8); 1304 1305 /* fill space with 0xff to indicate free */ 1306 for (cnt = 0; cnt < udf_rw32(sbd->num_bytes); cnt++) 1307 sbd->data[cnt] = 0xff; 1308 1309 /* set crc to only cover the header (UDF 2.3.1.2, 2.3.8.1) */ 1310 crclen = sizeof(struct space_bitmap_desc) -1 - UDF_DESC_TAG_LENGTH; 1311 sbd->tag.desc_crc_len = udf_rw16(crclen); 1312 1313 *sbdp = sbd; 1314 return 0; 1315 } 1316 1317 1318 /* --------------------------------------------------------------------- */ 1319 1320 int 1321 udf_register_bad_block(uint32_t location) 1322 { 1323 struct udf_sparing_table *spt; 1324 struct spare_map_entry *sme, *free_sme; 1325 uint32_t cnt; 1326 1327 spt = context.sparing_table; 1328 if (spt == NULL) { 1329 printf("internal error: adding bad block to non sparable\n"); 1330 return EINVAL; 1331 } 1332 1333 /* find us a free spare map entry */ 1334 free_sme = NULL; 1335 for (cnt = 0; cnt < layout.sparable_blocks; cnt++) { 1336 sme = &spt->entries[cnt]; 1337 /* if we are allready in it, bail out */ 1338 if (udf_rw32(sme->org) == location) 1339 return 0; 1340 if (udf_rw32(sme->org) == 0xffffffff) { 1341 free_sme = sme; 1342 break; 1343 } 1344 } 1345 if (free_sme == NULL) { 1346 printf("Disc relocation blocks full; disc too damanged\n"); 1347 return EINVAL; 1348 } 1349 free_sme->org = udf_rw32(location); 1350 1351 return 0; 1352 } 1353 1354 1355 void 1356 udf_mark_allocated(uint32_t start_lb, int partnr, uint32_t blocks) 1357 { 1358 union dscrptr *dscr; 1359 uint8_t *bpos; 1360 uint32_t cnt, bit; 1361 1362 /* account for space used on underlying partition */ 1363 context.part_free[partnr] -= blocks; 1364 #ifdef DEBUG 1365 printf("mark allocated : partnr %d, start_lb %d for %d blocks\n", 1366 partnr, start_lb, blocks); 1367 #endif 1368 1369 switch (context.vtop_tp[partnr]) { 1370 case UDF_VTOP_TYPE_VIRT: 1371 /* nothing */ 1372 break; 1373 case UDF_VTOP_TYPE_PHYS: 1374 case UDF_VTOP_TYPE_SPARABLE: 1375 case UDF_VTOP_TYPE_META: 1376 if (context.part_unalloc_bits[context.vtop[partnr]] == NULL) { 1377 context.part_free[partnr] = 0; 1378 break; 1379 } 1380 #ifdef DEBUG 1381 printf("Marking %d+%d as used\n", start_lb, blocks); 1382 #endif 1383 dscr = (union dscrptr *) (context.part_unalloc_bits[partnr]); 1384 for (cnt = start_lb; cnt < start_lb + blocks; cnt++) { 1385 bpos = &dscr->sbd.data[cnt / 8]; 1386 bit = cnt % 8; 1387 *bpos &= ~(1<< bit); 1388 } 1389 break; 1390 default: 1391 printf("internal error: reality check in mapping type %d\n", 1392 context.vtop_tp[partnr]); 1393 exit(EXIT_FAILURE); 1394 } 1395 } 1396 1397 1398 void 1399 udf_advance_uniqueid(void) 1400 { 1401 /* Minimum value of 16 : UDF 3.2.1.1, 3.3.3.4. */ 1402 context.unique_id++; 1403 if (context.unique_id < 0x10) 1404 context.unique_id = 0x10; 1405 } 1406 1407 /* --------------------------------------------------------------------- */ 1408 1409 static void 1410 unix_to_udf_name(char *result, uint8_t *result_len, 1411 char const *name, int name_len, struct charspec *chsp) 1412 { 1413 uint16_t *raw_name; 1414 uint16_t *outchp; 1415 const char *inchp; 1416 const char *osta_id = "OSTA Compressed Unicode"; 1417 int udf_chars, is_osta_typ0, bits; 1418 size_t cnt; 1419 1420 /* allocate temporary unicode-16 buffer */ 1421 raw_name = malloc(1024); 1422 assert(raw_name); 1423 1424 /* convert utf8 to unicode-16 */ 1425 *raw_name = 0; 1426 inchp = name; 1427 outchp = raw_name; 1428 bits = 8; 1429 for (cnt = name_len, udf_chars = 0; cnt;) { 1430 *outchp = wget_utf8(&inchp, &cnt); 1431 if (*outchp > 0xff) 1432 bits=16; 1433 outchp++; 1434 udf_chars++; 1435 } 1436 /* null terminate just in case */ 1437 *outchp++ = 0; 1438 1439 is_osta_typ0 = (chsp->type == 0); 1440 is_osta_typ0 &= (strcmp((char *) chsp->inf, osta_id) == 0); 1441 if (is_osta_typ0) { 1442 udf_chars = udf_CompressUnicode(udf_chars, bits, 1443 (unicode_t *) raw_name, 1444 (byte *) result); 1445 } else { 1446 printf("unix to udf name: no CHSP0 ?\n"); 1447 /* XXX assume 8bit char length byte latin-1 */ 1448 *result++ = 8; udf_chars = 1; 1449 strncpy(result, name + 1, name_len); 1450 udf_chars += name_len; 1451 } 1452 *result_len = udf_chars; 1453 free(raw_name); 1454 } 1455 1456 1457 #define UDF_SYMLINKBUFLEN (64*1024) /* picked */ 1458 int 1459 udf_encode_symlink(uint8_t **pathbufp, uint32_t *pathlenp, char *target) 1460 { 1461 struct charspec osta_charspec; 1462 struct pathcomp pathcomp; 1463 char *pathbuf, *pathpos, *compnamepos; 1464 // char *mntonname; 1465 // int mntonnamelen; 1466 int pathlen, len, compnamelen; 1467 int error; 1468 1469 /* process `target' to an UDF structure */ 1470 pathbuf = malloc(UDF_SYMLINKBUFLEN); 1471 assert(pathbuf); 1472 1473 *pathbufp = NULL; 1474 *pathlenp = 0; 1475 1476 pathpos = pathbuf; 1477 pathlen = 0; 1478 udf_osta_charset(&osta_charspec); 1479 1480 if (*target == '/') { 1481 /* symlink starts from the root */ 1482 len = UDF_PATH_COMP_SIZE; 1483 memset(&pathcomp, 0, len); 1484 pathcomp.type = UDF_PATH_COMP_ROOT; 1485 1486 #if 0 1487 /* XXX how to check for in makefs? */ 1488 /* check if its mount-point relative! */ 1489 mntonname = udf_node->ump->vfs_mountp->mnt_stat.f_mntonname; 1490 mntonnamelen = strlen(mntonname); 1491 if (strlen(target) >= mntonnamelen) { 1492 if (strncmp(target, mntonname, mntonnamelen) == 0) { 1493 pathcomp.type = UDF_PATH_COMP_MOUNTROOT; 1494 target += mntonnamelen; 1495 } 1496 } else { 1497 target++; 1498 } 1499 #else 1500 target++; 1501 #endif 1502 1503 memcpy(pathpos, &pathcomp, len); 1504 pathpos += len; 1505 pathlen += len; 1506 } 1507 1508 error = 0; 1509 while (*target) { 1510 /* ignore multiple '/' */ 1511 while (*target == '/') { 1512 target++; 1513 } 1514 if (!*target) 1515 break; 1516 1517 /* extract component name */ 1518 compnamelen = 0; 1519 compnamepos = target; 1520 while ((*target) && (*target != '/')) { 1521 target++; 1522 compnamelen++; 1523 } 1524 1525 /* just trunc if too long ?? (security issue) */ 1526 if (compnamelen >= 127) { 1527 error = ENAMETOOLONG; 1528 break; 1529 } 1530 1531 /* convert unix name to UDF name */ 1532 len = sizeof(struct pathcomp); 1533 memset(&pathcomp, 0, len); 1534 pathcomp.type = UDF_PATH_COMP_NAME; 1535 len = UDF_PATH_COMP_SIZE; 1536 1537 if ((compnamelen == 2) && (strncmp(compnamepos, "..", 2) == 0)) 1538 pathcomp.type = UDF_PATH_COMP_PARENTDIR; 1539 if ((compnamelen == 1) && (*compnamepos == '.')) 1540 pathcomp.type = UDF_PATH_COMP_CURDIR; 1541 1542 if (pathcomp.type == UDF_PATH_COMP_NAME) { 1543 unix_to_udf_name( 1544 (char *) &pathcomp.ident, &pathcomp.l_ci, 1545 compnamepos, compnamelen, 1546 &osta_charspec); 1547 len = UDF_PATH_COMP_SIZE + pathcomp.l_ci; 1548 } 1549 1550 if (pathlen + len >= UDF_SYMLINKBUFLEN) { 1551 error = ENAMETOOLONG; 1552 break; 1553 } 1554 1555 memcpy(pathpos, &pathcomp, len); 1556 pathpos += len; 1557 pathlen += len; 1558 } 1559 1560 if (error) { 1561 /* aparently too big */ 1562 free(pathbuf); 1563 return error; 1564 } 1565 1566 /* return status of symlink contents writeout */ 1567 *pathbufp = (uint8_t *) pathbuf; 1568 *pathlenp = pathlen; 1569 1570 return 0; 1571 1572 } 1573 #undef UDF_SYMLINKBUFLEN 1574 1575 1576 int 1577 udf_fidsize(struct fileid_desc *fid) 1578 { 1579 uint32_t size; 1580 1581 if (udf_rw16(fid->tag.id) != TAGID_FID) 1582 errx(EINVAL, "got udf_fidsize on non FID"); 1583 1584 size = UDF_FID_SIZE + fid->l_fi + udf_rw16(fid->l_iu); 1585 size = (size + 3) & ~3; 1586 1587 return size; 1588 } 1589 1590 1591 int 1592 udf_create_parentfid(struct fileid_desc *fid, struct long_ad *parent) 1593 { 1594 /* the size of an empty FID is 38 but needs to be a multiple of 4 */ 1595 int fidsize = 40; 1596 1597 udf_inittag(&fid->tag, TAGID_FID, udf_rw32(parent->loc.lb_num)); 1598 fid->file_version_num = udf_rw16(1); /* UDF 2.3.4.1 */ 1599 fid->file_char = UDF_FILE_CHAR_DIR | UDF_FILE_CHAR_PAR; 1600 fid->icb = *parent; 1601 fid->icb.longad_uniqueid = parent->longad_uniqueid; 1602 fid->tag.desc_crc_len = udf_rw16(fidsize - UDF_DESC_TAG_LENGTH); 1603 1604 /* we have to do the fid here explicitly for simplicity */ 1605 udf_validate_tag_and_crc_sums((union dscrptr *) fid); 1606 1607 return fidsize; 1608 } 1609 1610 1611 void 1612 udf_create_fid(uint32_t diroff, struct fileid_desc *fid, char *name, 1613 int file_char, struct long_ad *ref) 1614 { 1615 struct charspec osta_charspec; 1616 uint32_t endfid; 1617 uint32_t fidsize, lb_rest; 1618 1619 memset(fid, 0, sizeof(*fid)); 1620 udf_inittag(&fid->tag, TAGID_FID, udf_rw32(ref->loc.lb_num)); 1621 fid->file_version_num = udf_rw16(1); /* UDF 2.3.4.1 */ 1622 fid->file_char = file_char; 1623 fid->l_iu = udf_rw16(0); 1624 fid->icb = *ref; 1625 fid->icb.longad_uniqueid = ref->longad_uniqueid; 1626 1627 udf_osta_charset(&osta_charspec); 1628 unix_to_udf_name((char *) fid->data, &fid->l_fi, name, strlen(name), 1629 &osta_charspec); 1630 1631 /* 1632 * OK, tricky part: we need to pad so the next descriptor header won't 1633 * cross the sector boundary 1634 */ 1635 endfid = diroff + udf_fidsize(fid); 1636 lb_rest = context.sector_size - (endfid % context.sector_size); 1637 if (lb_rest < sizeof(struct desc_tag)) { 1638 /* add at least 32 */ 1639 fid->l_iu = udf_rw16(32); 1640 udf_set_regid((struct regid *) fid->data, context.impl_name); 1641 udf_add_impl_regid((struct regid *) fid->data); 1642 1643 unix_to_udf_name((char *) fid->data + udf_rw16(fid->l_iu), 1644 &fid->l_fi, name, strlen(name), &osta_charspec); 1645 } 1646 1647 fidsize = udf_fidsize(fid); 1648 fid->tag.desc_crc_len = udf_rw16(fidsize - UDF_DESC_TAG_LENGTH); 1649 1650 /* make sure the header sums stays correct */ 1651 udf_validate_tag_and_crc_sums((union dscrptr *)fid); 1652 } 1653 1654 1655 static void 1656 udf_append_parentfid(union dscrptr *dscr, struct long_ad *parent_icb) 1657 { 1658 struct file_entry *fe; 1659 struct extfile_entry *efe; 1660 struct fileid_desc *fid; 1661 uint32_t l_ea; 1662 uint32_t fidsize, crclen; 1663 uint8_t *bpos, *data; 1664 1665 fe = NULL; 1666 efe = NULL; 1667 if (udf_rw16(dscr->tag.id) == TAGID_FENTRY) { 1668 fe = &dscr->fe; 1669 data = fe->data; 1670 l_ea = udf_rw32(fe->l_ea); 1671 } else if (udf_rw16(dscr->tag.id) == TAGID_EXTFENTRY) { 1672 efe = &dscr->efe; 1673 data = efe->data; 1674 l_ea = udf_rw32(efe->l_ea); 1675 } else { 1676 errx(1, "Bad tag passed to udf_append_parentfid"); 1677 } 1678 1679 /* create '..' */ 1680 bpos = data + l_ea; 1681 fid = (struct fileid_desc *) bpos; 1682 fidsize = udf_create_parentfid(fid, parent_icb); 1683 1684 /* record fidlength information */ 1685 if (fe) { 1686 fe->inf_len = udf_rw64(fidsize); 1687 fe->l_ad = udf_rw32(fidsize); 1688 fe->logblks_rec = udf_rw64(0); /* intern */ 1689 crclen = sizeof(struct file_entry); 1690 } else { 1691 efe->inf_len = udf_rw64(fidsize); 1692 efe->obj_size = udf_rw64(fidsize); 1693 efe->l_ad = udf_rw32(fidsize); 1694 efe->logblks_rec = udf_rw64(0); /* intern */ 1695 crclen = sizeof(struct extfile_entry); 1696 } 1697 crclen -= 1 + UDF_DESC_TAG_LENGTH; 1698 crclen += l_ea + fidsize; 1699 dscr->tag.desc_crc_len = udf_rw16(crclen); 1700 1701 /* make sure the header sums stays correct */ 1702 udf_validate_tag_and_crc_sums(dscr); 1703 } 1704 1705 1706 1707 /* 1708 * Order of extended attributes : 1709 * ECMA 167 EAs 1710 * Non block aligned Implementation Use EAs 1711 * Block aligned Implementation Use EAs (not in newfs_udf) 1712 * Application Use EAs (not in newfs_udf) 1713 * 1714 * no checks for doubles, must be called in-order 1715 */ 1716 static void 1717 udf_extattr_append_internal(union dscrptr *dscr, struct extattr_entry *extattr) 1718 { 1719 struct file_entry *fe; 1720 struct extfile_entry *efe; 1721 struct extattrhdr_desc *extattrhdr; 1722 struct impl_extattr_entry *implext; 1723 uint32_t impl_attr_loc, appl_attr_loc, l_ea, a_l, exthdr_len; 1724 uint32_t *l_eap, l_ad; 1725 uint16_t *spos; 1726 uint8_t *bpos, *data; 1727 1728 if (udf_rw16(dscr->tag.id) == TAGID_FENTRY) { 1729 fe = &dscr->fe; 1730 data = fe->data; 1731 l_eap = &fe->l_ea; 1732 l_ad = udf_rw32(fe->l_ad); 1733 } else if (udf_rw16(dscr->tag.id) == TAGID_EXTFENTRY) { 1734 efe = &dscr->efe; 1735 data = efe->data; 1736 l_eap = &efe->l_ea; 1737 l_ad = udf_rw32(efe->l_ad); 1738 } else { 1739 errx(1, "Bad tag passed to udf_extattr_append_internal"); 1740 } 1741 1742 /* should have a header! */ 1743 extattrhdr = (struct extattrhdr_desc *) data; 1744 l_ea = udf_rw32(*l_eap); 1745 if (l_ea == 0) { 1746 #if !defined(NDEBUG) && defined(__minix) 1747 assert(l_ad == 0); 1748 #else 1749 if (l_ad != 0) { 1750 printf("%s:%d: l_ad != 0\n", __func__, __LINE__); 1751 abort(); 1752 } 1753 #endif /* !defined(NDEBUG) && defined(__minix) */ 1754 /* create empty extended attribute header */ 1755 exthdr_len = sizeof(struct extattrhdr_desc); 1756 1757 udf_inittag(&extattrhdr->tag, TAGID_EXTATTR_HDR, /* loc */ 0); 1758 extattrhdr->impl_attr_loc = udf_rw32(exthdr_len); 1759 extattrhdr->appl_attr_loc = udf_rw32(exthdr_len); 1760 extattrhdr->tag.desc_crc_len = udf_rw16(8); 1761 1762 /* record extended attribute header length */ 1763 l_ea = exthdr_len; 1764 *l_eap = udf_rw32(l_ea); 1765 } 1766 1767 /* extract locations */ 1768 impl_attr_loc = udf_rw32(extattrhdr->impl_attr_loc); 1769 appl_attr_loc = udf_rw32(extattrhdr->appl_attr_loc); 1770 if (impl_attr_loc == UDF_IMPL_ATTR_LOC_NOT_PRESENT) 1771 impl_attr_loc = l_ea; 1772 if (appl_attr_loc == UDF_IMPL_ATTR_LOC_NOT_PRESENT) 1773 appl_attr_loc = l_ea; 1774 1775 /* Ecma 167 EAs */ 1776 if (udf_rw32(extattr->type) < 2048) { 1777 assert(impl_attr_loc == l_ea); 1778 assert(appl_attr_loc == l_ea); 1779 } 1780 1781 /* implementation use extended attributes */ 1782 if (udf_rw32(extattr->type) == 2048) { 1783 assert(appl_attr_loc == l_ea); 1784 1785 /* calculate and write extended attribute header checksum */ 1786 implext = (struct impl_extattr_entry *) extattr; 1787 assert(udf_rw32(implext->iu_l) == 4); /* [UDF 3.3.4.5] */ 1788 spos = (uint16_t *) implext->data; 1789 *spos = udf_rw16(udf_ea_cksum((uint8_t *) implext)); 1790 } 1791 1792 /* application use extended attributes */ 1793 assert(udf_rw32(extattr->type) != 65536); 1794 assert(appl_attr_loc == l_ea); 1795 1796 /* append the attribute at the end of the current space */ 1797 bpos = data + udf_rw32(*l_eap); 1798 a_l = udf_rw32(extattr->a_l); 1799 1800 /* update impl. attribute locations */ 1801 if (udf_rw32(extattr->type) < 2048) { 1802 impl_attr_loc = l_ea + a_l; 1803 appl_attr_loc = l_ea + a_l; 1804 } 1805 if (udf_rw32(extattr->type) == 2048) { 1806 appl_attr_loc = l_ea + a_l; 1807 } 1808 1809 /* copy and advance */ 1810 memcpy(bpos, extattr, a_l); 1811 l_ea += a_l; 1812 *l_eap = udf_rw32(l_ea); 1813 1814 /* do the `dance` again backwards */ 1815 if (context.dscrver != 2) { 1816 if (impl_attr_loc == l_ea) 1817 impl_attr_loc = UDF_IMPL_ATTR_LOC_NOT_PRESENT; 1818 if (appl_attr_loc == l_ea) 1819 appl_attr_loc = UDF_APPL_ATTR_LOC_NOT_PRESENT; 1820 } 1821 1822 /* store offsets */ 1823 extattrhdr->impl_attr_loc = udf_rw32(impl_attr_loc); 1824 extattrhdr->appl_attr_loc = udf_rw32(appl_attr_loc); 1825 1826 /* make sure the header sums stays correct */ 1827 udf_validate_tag_and_crc_sums((union dscrptr *) extattrhdr); 1828 } 1829 1830 1831 int 1832 udf_create_new_fe(struct file_entry **fep, int file_type, struct stat *st) 1833 { 1834 struct file_entry *fe; 1835 struct icb_tag *icb; 1836 struct timestamp birthtime; 1837 struct filetimes_extattr_entry *ft_extattr; 1838 uint32_t crclen; /* XXX: should be 16; need to detect overflow */ 1839 uint16_t icbflags; 1840 1841 *fep = NULL; 1842 fe = calloc(1, context.sector_size); 1843 if (fe == NULL) 1844 return ENOMEM; 1845 1846 udf_inittag(&fe->tag, TAGID_FENTRY, /* loc */ 0); 1847 icb = &fe->icbtag; 1848 1849 /* 1850 * Always use strategy type 4 unless on WORM wich we don't support 1851 * (yet). Fill in defaults and set for internal allocation of data. 1852 */ 1853 icb->strat_type = udf_rw16(4); 1854 icb->max_num_entries = udf_rw16(1); 1855 icb->file_type = file_type; /* 8 bit */ 1856 icb->flags = udf_rw16(UDF_ICB_INTERN_ALLOC); 1857 1858 fe->perm = udf_rw32(0x7fff); /* all is allowed */ 1859 fe->link_cnt = udf_rw16(0); /* explicit setting */ 1860 1861 fe->ckpoint = udf_rw32(1); /* user supplied file version */ 1862 1863 udf_set_timestamp_now(&birthtime); 1864 udf_set_timestamp_now(&fe->atime); 1865 udf_set_timestamp_now(&fe->attrtime); 1866 udf_set_timestamp_now(&fe->mtime); 1867 1868 /* set attributes */ 1869 if (st) { 1870 #if !HAVE_NBTOOL_CONFIG_H 1871 udf_set_timestamp(&birthtime, st->st_birthtime); 1872 #else 1873 udf_set_timestamp(&birthtime, 0); 1874 #endif 1875 udf_set_timestamp(&fe->atime, st->st_atime); 1876 udf_set_timestamp(&fe->attrtime, st->st_ctime); 1877 udf_set_timestamp(&fe->mtime, st->st_mtime); 1878 fe->uid = udf_rw32(st->st_uid); 1879 fe->gid = udf_rw32(st->st_gid); 1880 1881 fe->perm = unix_mode_to_udf_perm(st->st_mode); 1882 1883 icbflags = udf_rw16(fe->icbtag.flags); 1884 icbflags &= ~UDF_ICB_TAG_FLAGS_SETUID; 1885 icbflags &= ~UDF_ICB_TAG_FLAGS_SETGID; 1886 icbflags &= ~UDF_ICB_TAG_FLAGS_STICKY; 1887 if (st->st_mode & S_ISUID) 1888 icbflags |= UDF_ICB_TAG_FLAGS_SETUID; 1889 if (st->st_mode & S_ISGID) 1890 icbflags |= UDF_ICB_TAG_FLAGS_SETGID; 1891 if (st->st_mode & S_ISVTX) 1892 icbflags |= UDF_ICB_TAG_FLAGS_STICKY; 1893 fe->icbtag.flags = udf_rw16(icbflags); 1894 } 1895 1896 udf_set_regid(&fe->imp_id, context.impl_name); 1897 udf_add_impl_regid(&fe->imp_id); 1898 fe->unique_id = udf_rw64(context.unique_id); 1899 udf_advance_uniqueid(); 1900 1901 fe->l_ea = udf_rw32(0); 1902 1903 /* create extended attribute to record our creation time */ 1904 ft_extattr = calloc(1, UDF_FILETIMES_ATTR_SIZE(1)); 1905 ft_extattr->hdr.type = udf_rw32(UDF_FILETIMES_ATTR_NO); 1906 ft_extattr->hdr.subtype = 1; /* [4/48.10.5] */ 1907 ft_extattr->hdr.a_l = udf_rw32(UDF_FILETIMES_ATTR_SIZE(1)); 1908 ft_extattr->d_l = udf_rw32(UDF_TIMESTAMP_SIZE); /* one item */ 1909 ft_extattr->existence = UDF_FILETIMES_FILE_CREATION; 1910 ft_extattr->times[0] = birthtime; 1911 1912 udf_extattr_append_internal((union dscrptr *) fe, 1913 (struct extattr_entry *) ft_extattr); 1914 free(ft_extattr); 1915 1916 /* record fidlength information */ 1917 fe->inf_len = udf_rw64(0); 1918 fe->l_ad = udf_rw32(0); 1919 fe->logblks_rec = udf_rw64(0); /* intern */ 1920 1921 crclen = sizeof(struct file_entry) - 1 - UDF_DESC_TAG_LENGTH; 1922 crclen += udf_rw32(fe->l_ea); 1923 1924 /* make sure the header sums stays correct */ 1925 fe->tag.desc_crc_len = udf_rw16(crclen); 1926 udf_validate_tag_and_crc_sums((union dscrptr *) fe); 1927 1928 *fep = fe; 1929 return 0; 1930 } 1931 1932 1933 int 1934 udf_create_new_efe(struct extfile_entry **efep, int file_type, struct stat *st) 1935 { 1936 struct extfile_entry *efe; 1937 struct icb_tag *icb; 1938 uint32_t crclen; /* XXX: should be 16; need to detect overflow */ 1939 uint16_t icbflags; 1940 1941 *efep = NULL; 1942 efe = calloc(1, context.sector_size); 1943 if (efe == NULL) 1944 return ENOMEM; 1945 1946 udf_inittag(&efe->tag, TAGID_EXTFENTRY, /* loc */ 0); 1947 icb = &efe->icbtag; 1948 1949 /* 1950 * Always use strategy type 4 unless on WORM wich we don't support 1951 * (yet). Fill in defaults and set for internal allocation of data. 1952 */ 1953 icb->strat_type = udf_rw16(4); 1954 icb->max_num_entries = udf_rw16(1); 1955 icb->file_type = file_type; /* 8 bit */ 1956 icb->flags = udf_rw16(UDF_ICB_INTERN_ALLOC); 1957 1958 efe->perm = udf_rw32(0x7fff); /* all is allowed */ 1959 efe->link_cnt = udf_rw16(0); /* explicit setting */ 1960 1961 efe->ckpoint = udf_rw32(1); /* user supplied file version */ 1962 1963 udf_set_timestamp_now(&efe->ctime); 1964 udf_set_timestamp_now(&efe->atime); 1965 udf_set_timestamp_now(&efe->attrtime); 1966 udf_set_timestamp_now(&efe->mtime); 1967 1968 /* set attributes */ 1969 if (st) { 1970 #if !HAVE_NBTOOL_CONFIG_H 1971 udf_set_timestamp(&efe->ctime, st->st_birthtime); 1972 #else 1973 udf_set_timestamp(&efe->ctime, 0); 1974 #endif 1975 udf_set_timestamp(&efe->atime, st->st_atime); 1976 udf_set_timestamp(&efe->attrtime, st->st_ctime); 1977 udf_set_timestamp(&efe->mtime, st->st_mtime); 1978 efe->uid = udf_rw32(st->st_uid); 1979 efe->gid = udf_rw32(st->st_gid); 1980 1981 efe->perm = unix_mode_to_udf_perm(st->st_mode); 1982 1983 icbflags = udf_rw16(efe->icbtag.flags); 1984 icbflags &= ~UDF_ICB_TAG_FLAGS_SETUID; 1985 icbflags &= ~UDF_ICB_TAG_FLAGS_SETGID; 1986 icbflags &= ~UDF_ICB_TAG_FLAGS_STICKY; 1987 if (st->st_mode & S_ISUID) 1988 icbflags |= UDF_ICB_TAG_FLAGS_SETUID; 1989 if (st->st_mode & S_ISGID) 1990 icbflags |= UDF_ICB_TAG_FLAGS_SETGID; 1991 if (st->st_mode & S_ISVTX) 1992 icbflags |= UDF_ICB_TAG_FLAGS_STICKY; 1993 efe->icbtag.flags = udf_rw16(icbflags); 1994 } 1995 1996 udf_set_regid(&efe->imp_id, context.impl_name); 1997 udf_add_impl_regid(&efe->imp_id); 1998 1999 efe->unique_id = udf_rw64(context.unique_id); 2000 udf_advance_uniqueid(); 2001 2002 /* record fidlength information */ 2003 efe->inf_len = udf_rw64(0); 2004 efe->obj_size = udf_rw64(0); 2005 efe->l_ad = udf_rw32(0); 2006 efe->logblks_rec = udf_rw64(0); 2007 2008 crclen = sizeof(struct extfile_entry) - 1 - UDF_DESC_TAG_LENGTH; 2009 2010 /* make sure the header sums stays correct */ 2011 efe->tag.desc_crc_len = udf_rw16(crclen); 2012 udf_validate_tag_and_crc_sums((union dscrptr *) efe); 2013 2014 *efep = efe; 2015 return 0; 2016 } 2017 2018 /* --------------------------------------------------------------------- */ 2019 2020 /* for METADATA file appending only */ 2021 static void 2022 udf_append_meta_mapping_part_to_efe(struct extfile_entry *efe, 2023 struct short_ad *mapping) 2024 { 2025 struct icb_tag *icb; 2026 uint64_t inf_len, obj_size, logblks_rec; 2027 uint32_t l_ad, l_ea; 2028 uint16_t crclen; 2029 uint8_t *bpos; 2030 2031 inf_len = udf_rw64(efe->inf_len); 2032 obj_size = udf_rw64(efe->obj_size); 2033 logblks_rec = udf_rw64(efe->logblks_rec); 2034 l_ad = udf_rw32(efe->l_ad); 2035 l_ea = udf_rw32(efe->l_ea); 2036 crclen = udf_rw16(efe->tag.desc_crc_len); 2037 icb = &efe->icbtag; 2038 2039 /* set our allocation to shorts if not already done */ 2040 icb->flags = udf_rw16(UDF_ICB_SHORT_ALLOC); 2041 2042 /* append short_ad */ 2043 bpos = (uint8_t *) efe->data + l_ea + l_ad; 2044 memcpy(bpos, mapping, sizeof(struct short_ad)); 2045 2046 l_ad += sizeof(struct short_ad); 2047 crclen += sizeof(struct short_ad); 2048 inf_len += UDF_EXT_LEN(udf_rw32(mapping->len)); 2049 obj_size += UDF_EXT_LEN(udf_rw32(mapping->len)); 2050 logblks_rec = UDF_ROUNDUP(inf_len, context.sector_size) / 2051 context.sector_size; 2052 2053 efe->l_ad = udf_rw32(l_ad); 2054 efe->inf_len = udf_rw64(inf_len); 2055 efe->obj_size = udf_rw64(obj_size); 2056 efe->logblks_rec = udf_rw64(logblks_rec); 2057 efe->tag.desc_crc_len = udf_rw16(crclen); 2058 } 2059 2060 2061 /* for METADATA file appending only */ 2062 static void 2063 udf_append_meta_mapping_to_efe(struct extfile_entry *efe, 2064 uint16_t partnr, uint32_t lb_num, 2065 uint64_t len) 2066 { 2067 struct short_ad mapping; 2068 uint64_t max_len, part_len; 2069 2070 /* calculate max length meta allocation sizes */ 2071 max_len = UDF_EXT_MAXLEN / context.sector_size; /* in sectors */ 2072 max_len = (max_len / layout.meta_blockingnr) * layout.meta_blockingnr; 2073 max_len = max_len * context.sector_size; 2074 2075 memset(&mapping, 0, sizeof(mapping)); 2076 while (len) { 2077 part_len = MIN(len, max_len); 2078 mapping.lb_num = udf_rw32(lb_num); 2079 mapping.len = udf_rw32(part_len); 2080 2081 udf_append_meta_mapping_part_to_efe(efe, &mapping); 2082 2083 lb_num += part_len / context.sector_size; 2084 len -= part_len; 2085 } 2086 } 2087 2088 2089 int 2090 udf_create_meta_files(void) 2091 { 2092 struct extfile_entry *efe; 2093 struct long_ad meta_icb; 2094 uint64_t bytes; 2095 uint32_t sector_size; 2096 int filetype, error; 2097 2098 sector_size = context.sector_size; 2099 2100 memset(&meta_icb, 0, sizeof(meta_icb)); 2101 meta_icb.len = udf_rw32(sector_size); 2102 meta_icb.loc.part_num = udf_rw16(context.data_part); 2103 2104 /* create metadata file */ 2105 meta_icb.loc.lb_num = udf_rw32(layout.meta_file); 2106 filetype = UDF_ICB_FILETYPE_META_MAIN; 2107 error = udf_create_new_efe(&efe, filetype, NULL); 2108 if (error) 2109 return error; 2110 context.meta_file = efe; 2111 2112 /* create metadata mirror file */ 2113 meta_icb.loc.lb_num = udf_rw32(layout.meta_mirror); 2114 filetype = UDF_ICB_FILETYPE_META_MIRROR; 2115 error = udf_create_new_efe(&efe, filetype, NULL); 2116 if (error) 2117 return error; 2118 context.meta_mirror = efe; 2119 2120 /* create metadata bitmap file */ 2121 meta_icb.loc.lb_num = udf_rw32(layout.meta_bitmap); 2122 filetype = UDF_ICB_FILETYPE_META_BITMAP; 2123 error = udf_create_new_efe(&efe, filetype, NULL); 2124 if (error) 2125 return error; 2126 context.meta_bitmap = efe; 2127 2128 /* patch up files */ 2129 context.meta_file->unique_id = udf_rw64(0); 2130 context.meta_mirror->unique_id = udf_rw64(0); 2131 context.meta_bitmap->unique_id = udf_rw64(0); 2132 2133 /* restart unique id */ 2134 context.unique_id = 0x10; 2135 2136 /* XXX no support for metadata mirroring yet */ 2137 /* insert extents */ 2138 efe = context.meta_file; 2139 udf_append_meta_mapping_to_efe(efe, context.data_part, 2140 layout.meta_part_start_lba, 2141 (uint64_t) layout.meta_part_size_lba * sector_size); 2142 2143 efe = context.meta_mirror; 2144 udf_append_meta_mapping_to_efe(efe, context.data_part, 2145 layout.meta_part_start_lba, 2146 (uint64_t) layout.meta_part_size_lba * sector_size); 2147 2148 efe = context.meta_bitmap; 2149 bytes = udf_space_bitmap_len(layout.meta_part_size_lba); 2150 udf_append_meta_mapping_to_efe(efe, context.data_part, 2151 layout.meta_bitmap_space, bytes); 2152 2153 return 0; 2154 } 2155 2156 2157 /* --------------------------------------------------------------------- */ 2158 2159 int 2160 udf_create_new_rootdir(union dscrptr **dscr) 2161 { 2162 struct file_entry *fe; 2163 struct extfile_entry *efe; 2164 struct long_ad root_icb; 2165 int filetype, error; 2166 2167 #if defined(__minix) 2168 /* LSC: -Werror=maybe-uninitialized when compiling with -O3 */ 2169 fe = NULL; 2170 #endif /*defined(__minix) */ 2171 memset(&root_icb, 0, sizeof(root_icb)); 2172 root_icb.len = udf_rw32(context.sector_size); 2173 root_icb.loc.lb_num = udf_rw32(layout.rootdir); 2174 root_icb.loc.part_num = udf_rw16(context.metadata_part); 2175 2176 filetype = UDF_ICB_FILETYPE_DIRECTORY; 2177 if (context.dscrver == 2) { 2178 error = udf_create_new_fe(&fe, filetype, NULL); 2179 *dscr = (union dscrptr *) fe; 2180 } else { 2181 error = udf_create_new_efe(&efe, filetype, NULL); 2182 *dscr = (union dscrptr *) efe; 2183 } 2184 if (error) 2185 return error; 2186 2187 /* append '..' */ 2188 udf_append_parentfid(*dscr, &root_icb); 2189 2190 /* rootdir has explicit only one link on creation; '..' is no link */ 2191 if (context.dscrver == 2) { 2192 fe->link_cnt = udf_rw16(1); 2193 } else { 2194 efe->link_cnt = udf_rw16(1); 2195 } 2196 2197 context.num_directories++; 2198 assert(context.num_directories == 1); 2199 2200 return 0; 2201 } 2202 2203 2204 void 2205 udf_prepend_VAT_file(void) 2206 { 2207 /* old style VAT has no prepend */ 2208 if (context.dscrver == 2) { 2209 context.vat_start = 0; 2210 context.vat_size = 0; 2211 return; 2212 } 2213 2214 context.vat_start = offsetof(struct udf_vat, data); 2215 context.vat_size = offsetof(struct udf_vat, data); 2216 } 2217 2218 2219 void 2220 udf_vat_update(uint32_t virt, uint32_t phys) 2221 { 2222 uint32_t *vatpos; 2223 uint32_t new_size; 2224 2225 if (context.vtop_tp[context.metadata_part] != UDF_VTOP_TYPE_VIRT) 2226 return; 2227 2228 new_size = MAX(context.vat_size, 2229 (context.vat_start + (virt+1)*sizeof(uint32_t))); 2230 2231 if (new_size > context.vat_allocated) { 2232 context.vat_allocated = 2233 UDF_ROUNDUP(new_size, context.sector_size); 2234 context.vat_contents = realloc(context.vat_contents, 2235 context.vat_allocated); 2236 assert(context.vat_contents); 2237 /* XXX could also report error */ 2238 } 2239 vatpos = (uint32_t *) (context.vat_contents + context.vat_start); 2240 vatpos[virt] = udf_rw32(phys); 2241 2242 context.vat_size = MAX(context.vat_size, 2243 (context.vat_start + (virt+1)*sizeof(uint32_t))); 2244 } 2245 2246 2247 int 2248 udf_append_VAT_file(void) 2249 { 2250 struct udf_oldvat_tail *oldvat_tail; 2251 struct udf_vat *vathdr; 2252 int32_t len_diff; 2253 2254 /* new style VAT has VAT LVInt analog in front */ 2255 if (context.dscrver == 3) { 2256 /* set up VATv2 descriptor */ 2257 vathdr = (struct udf_vat *) context.vat_contents; 2258 vathdr->header_len = udf_rw16(sizeof(struct udf_vat) - 1); 2259 vathdr->impl_use_len = udf_rw16(0); 2260 memcpy(vathdr->logvol_id, context.logical_vol->logvol_id, 128); 2261 vathdr->prev_vat = udf_rw32(UDF_NO_PREV_VAT); 2262 vathdr->num_files = udf_rw32(context.num_files); 2263 vathdr->num_directories = udf_rw32(context.num_directories); 2264 2265 vathdr->min_udf_readver = udf_rw16(context.min_udf); 2266 vathdr->min_udf_writever = udf_rw16(context.min_udf); 2267 vathdr->max_udf_writever = udf_rw16(context.max_udf); 2268 2269 return 0; 2270 } 2271 2272 /* old style VAT has identifier appended */ 2273 2274 /* append "*UDF Virtual Alloc Tbl" id and prev. VAT location */ 2275 len_diff = context.vat_allocated - context.vat_size; 2276 assert(len_diff >= 0); 2277 if (len_diff < (int32_t) sizeof(struct udf_oldvat_tail)) { 2278 context.vat_allocated += context.sector_size; 2279 context.vat_contents = realloc(context.vat_contents, 2280 context.vat_allocated); 2281 assert(context.vat_contents); 2282 /* XXX could also report error */ 2283 } 2284 2285 oldvat_tail = (struct udf_oldvat_tail *) (context.vat_contents + 2286 context.vat_size); 2287 2288 udf_set_regid(&oldvat_tail->id, "*UDF Virtual Alloc Tbl"); 2289 udf_add_udf_regid(&oldvat_tail->id); 2290 oldvat_tail->prev_vat = udf_rw32(UDF_NO_PREV_VAT); 2291 2292 context.vat_size += sizeof(struct udf_oldvat_tail); 2293 2294 return 0; 2295 } 2296 2297 2298 int 2299 udf_create_VAT(union dscrptr **vat_dscr) 2300 { 2301 struct file_entry *fe; 2302 struct extfile_entry *efe; 2303 struct impl_extattr_entry *implext; 2304 struct vatlvext_extattr_entry *vatlvext; 2305 struct long_ad dataloc, *allocpos; 2306 uint8_t *bpos, *extattr; 2307 uint32_t ea_len, inf_len, vat_len, blks; 2308 int filetype; 2309 int error; 2310 2311 assert((layout.rootdir < 2) && (layout.fsd < 2)); 2312 2313 memset(&dataloc, 0, sizeof(dataloc)); 2314 dataloc.len = udf_rw32(context.vat_size); 2315 dataloc.loc.part_num = udf_rw16(context.data_part); 2316 dataloc.loc.lb_num = udf_rw32(layout.vat); 2317 2318 if (context.dscrver == 2) { 2319 /* old style VAT */ 2320 filetype = UDF_ICB_FILETYPE_UNKNOWN; 2321 error = udf_create_new_fe(&fe, filetype, NULL); 2322 if (error) 2323 return error; 2324 2325 /* append VAT LVExtension attribute */ 2326 ea_len = sizeof(struct impl_extattr_entry) - 1 + 2327 sizeof(struct vatlvext_extattr_entry) + 4; 2328 2329 extattr = calloc(1, ea_len); 2330 2331 implext = (struct impl_extattr_entry *) extattr; 2332 implext->hdr.type = udf_rw32(2048); /* [4/48.10.8] */ 2333 implext->hdr.subtype = 1; /* [4/48.10.8.2] */ 2334 implext->hdr.a_l = udf_rw32(ea_len); /* VAT LVext EA size */ 2335 /* use 4 bytes of imp use for UDF checksum [UDF 3.3.4.5] */ 2336 implext->iu_l = udf_rw32(4); 2337 udf_set_regid(&implext->imp_id, "*UDF VAT LVExtension"); 2338 udf_add_udf_regid(&implext->imp_id); 2339 2340 /* VAT LVExtension data follows UDF IU space */ 2341 bpos = ((uint8_t *) implext->data) + 4; 2342 vatlvext = (struct vatlvext_extattr_entry *) bpos; 2343 2344 vatlvext->unique_id_chk = udf_rw64(fe->unique_id); 2345 vatlvext->num_files = udf_rw32(context.num_files); 2346 vatlvext->num_directories = udf_rw32(context.num_directories); 2347 memcpy(vatlvext->logvol_id, context.logical_vol->logvol_id,128); 2348 2349 udf_extattr_append_internal((union dscrptr *) fe, 2350 (struct extattr_entry *) extattr); 2351 2352 free(extattr); 2353 2354 fe->icbtag.flags = udf_rw16(UDF_ICB_LONG_ALLOC); 2355 2356 allocpos = (struct long_ad *) (fe->data + udf_rw32(fe->l_ea)); 2357 *allocpos = dataloc; 2358 2359 /* set length */ 2360 inf_len = context.vat_size; 2361 fe->inf_len = udf_rw64(inf_len); 2362 fe->l_ad = udf_rw32(sizeof(struct long_ad)); 2363 blks = UDF_ROUNDUP(inf_len, context.sector_size) / 2364 context.sector_size; 2365 fe->logblks_rec = udf_rw32(blks); 2366 2367 /* update vat descriptor's CRC length */ 2368 vat_len = sizeof(struct file_entry) - 1 - UDF_DESC_TAG_LENGTH; 2369 vat_len += udf_rw32(fe->l_ad) + udf_rw32(fe->l_ea); 2370 fe->tag.desc_crc_len = udf_rw16(vat_len); 2371 2372 *vat_dscr = (union dscrptr *) fe; 2373 } else { 2374 /* new style VAT */ 2375 filetype = UDF_ICB_FILETYPE_VAT; 2376 error = udf_create_new_efe(&efe, filetype, NULL); 2377 if (error) 2378 return error; 2379 2380 efe->icbtag.flags = udf_rw16(UDF_ICB_LONG_ALLOC); 2381 2382 allocpos = (struct long_ad *) efe->data; 2383 *allocpos = dataloc; 2384 2385 /* set length */ 2386 inf_len = context.vat_size; 2387 efe->inf_len = udf_rw64(inf_len); 2388 efe->obj_size = udf_rw64(inf_len); 2389 efe->l_ad = udf_rw32(sizeof(struct long_ad)); 2390 blks = UDF_ROUNDUP(inf_len, context.sector_size) / 2391 context.sector_size; 2392 efe->logblks_rec = udf_rw32(blks); 2393 2394 vat_len = sizeof(struct extfile_entry)-1 - UDF_DESC_TAG_LENGTH; 2395 vat_len += udf_rw32(efe->l_ad); 2396 efe->tag.desc_crc_len = udf_rw16(vat_len); 2397 2398 *vat_dscr = (union dscrptr *) efe; 2399 } 2400 2401 return 0; 2402 } 2403 2404