1 /* $NetBSD: udf_create.c,v 1.24 2013/10/19 01:09:59 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.24 2013/10/19 01:09:59 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\n"); 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 assert(l_ad == 0); 1747 /* create empty extended attribute header */ 1748 exthdr_len = sizeof(struct extattrhdr_desc); 1749 1750 udf_inittag(&extattrhdr->tag, TAGID_EXTATTR_HDR, /* loc */ 0); 1751 extattrhdr->impl_attr_loc = udf_rw32(exthdr_len); 1752 extattrhdr->appl_attr_loc = udf_rw32(exthdr_len); 1753 extattrhdr->tag.desc_crc_len = udf_rw16(8); 1754 1755 /* record extended attribute header length */ 1756 l_ea = exthdr_len; 1757 *l_eap = udf_rw32(l_ea); 1758 } 1759 1760 /* extract locations */ 1761 impl_attr_loc = udf_rw32(extattrhdr->impl_attr_loc); 1762 appl_attr_loc = udf_rw32(extattrhdr->appl_attr_loc); 1763 if (impl_attr_loc == UDF_IMPL_ATTR_LOC_NOT_PRESENT) 1764 impl_attr_loc = l_ea; 1765 if (appl_attr_loc == UDF_IMPL_ATTR_LOC_NOT_PRESENT) 1766 appl_attr_loc = l_ea; 1767 1768 /* Ecma 167 EAs */ 1769 if (udf_rw32(extattr->type) < 2048) { 1770 assert(impl_attr_loc == l_ea); 1771 assert(appl_attr_loc == l_ea); 1772 } 1773 1774 /* implementation use extended attributes */ 1775 if (udf_rw32(extattr->type) == 2048) { 1776 assert(appl_attr_loc == l_ea); 1777 1778 /* calculate and write extended attribute header checksum */ 1779 implext = (struct impl_extattr_entry *) extattr; 1780 assert(udf_rw32(implext->iu_l) == 4); /* [UDF 3.3.4.5] */ 1781 spos = (uint16_t *) implext->data; 1782 *spos = udf_rw16(udf_ea_cksum((uint8_t *) implext)); 1783 } 1784 1785 /* application use extended attributes */ 1786 assert(udf_rw32(extattr->type) != 65536); 1787 assert(appl_attr_loc == l_ea); 1788 1789 /* append the attribute at the end of the current space */ 1790 bpos = data + udf_rw32(*l_eap); 1791 a_l = udf_rw32(extattr->a_l); 1792 1793 /* update impl. attribute locations */ 1794 if (udf_rw32(extattr->type) < 2048) { 1795 impl_attr_loc = l_ea + a_l; 1796 appl_attr_loc = l_ea + a_l; 1797 } 1798 if (udf_rw32(extattr->type) == 2048) { 1799 appl_attr_loc = l_ea + a_l; 1800 } 1801 1802 /* copy and advance */ 1803 memcpy(bpos, extattr, a_l); 1804 l_ea += a_l; 1805 *l_eap = udf_rw32(l_ea); 1806 1807 /* do the `dance` again backwards */ 1808 if (context.dscrver != 2) { 1809 if (impl_attr_loc == l_ea) 1810 impl_attr_loc = UDF_IMPL_ATTR_LOC_NOT_PRESENT; 1811 if (appl_attr_loc == l_ea) 1812 appl_attr_loc = UDF_APPL_ATTR_LOC_NOT_PRESENT; 1813 } 1814 1815 /* store offsets */ 1816 extattrhdr->impl_attr_loc = udf_rw32(impl_attr_loc); 1817 extattrhdr->appl_attr_loc = udf_rw32(appl_attr_loc); 1818 1819 /* make sure the header sums stays correct */ 1820 udf_validate_tag_and_crc_sums((union dscrptr *) extattrhdr); 1821 } 1822 1823 1824 int 1825 udf_create_new_fe(struct file_entry **fep, int file_type, struct stat *st) 1826 { 1827 struct file_entry *fe; 1828 struct icb_tag *icb; 1829 struct timestamp birthtime; 1830 struct filetimes_extattr_entry *ft_extattr; 1831 uint32_t crclen; /* XXX: should be 16; need to detect overflow */ 1832 uint16_t icbflags; 1833 1834 *fep = NULL; 1835 fe = calloc(1, context.sector_size); 1836 if (fe == NULL) 1837 return ENOMEM; 1838 1839 udf_inittag(&fe->tag, TAGID_FENTRY, /* loc */ 0); 1840 icb = &fe->icbtag; 1841 1842 /* 1843 * Always use strategy type 4 unless on WORM wich we don't support 1844 * (yet). Fill in defaults and set for internal allocation of data. 1845 */ 1846 icb->strat_type = udf_rw16(4); 1847 icb->max_num_entries = udf_rw16(1); 1848 icb->file_type = file_type; /* 8 bit */ 1849 icb->flags = udf_rw16(UDF_ICB_INTERN_ALLOC); 1850 1851 fe->perm = udf_rw32(0x7fff); /* all is allowed */ 1852 fe->link_cnt = udf_rw16(0); /* explicit setting */ 1853 1854 fe->ckpoint = udf_rw32(1); /* user supplied file version */ 1855 1856 udf_set_timestamp_now(&birthtime); 1857 udf_set_timestamp_now(&fe->atime); 1858 udf_set_timestamp_now(&fe->attrtime); 1859 udf_set_timestamp_now(&fe->mtime); 1860 1861 /* set attributes */ 1862 if (st) { 1863 #if !HAVE_NBTOOL_CONFIG_H 1864 udf_set_timestamp(&birthtime, st->st_birthtime); 1865 #else 1866 udf_set_timestamp(&birthtime, 0); 1867 #endif 1868 udf_set_timestamp(&fe->atime, st->st_atime); 1869 udf_set_timestamp(&fe->attrtime, st->st_ctime); 1870 udf_set_timestamp(&fe->mtime, st->st_mtime); 1871 fe->uid = udf_rw32(st->st_uid); 1872 fe->gid = udf_rw32(st->st_gid); 1873 1874 fe->perm = unix_mode_to_udf_perm(st->st_mode); 1875 1876 icbflags = udf_rw16(fe->icbtag.flags); 1877 icbflags &= ~UDF_ICB_TAG_FLAGS_SETUID; 1878 icbflags &= ~UDF_ICB_TAG_FLAGS_SETGID; 1879 icbflags &= ~UDF_ICB_TAG_FLAGS_STICKY; 1880 if (st->st_mode & S_ISUID) 1881 icbflags |= UDF_ICB_TAG_FLAGS_SETUID; 1882 if (st->st_mode & S_ISGID) 1883 icbflags |= UDF_ICB_TAG_FLAGS_SETGID; 1884 if (st->st_mode & S_ISVTX) 1885 icbflags |= UDF_ICB_TAG_FLAGS_STICKY; 1886 fe->icbtag.flags = udf_rw16(icbflags); 1887 } 1888 1889 udf_set_regid(&fe->imp_id, context.impl_name); 1890 udf_add_impl_regid(&fe->imp_id); 1891 fe->unique_id = udf_rw64(context.unique_id); 1892 udf_advance_uniqueid(); 1893 1894 fe->l_ea = udf_rw32(0); 1895 1896 /* create extended attribute to record our creation time */ 1897 ft_extattr = calloc(1, UDF_FILETIMES_ATTR_SIZE(1)); 1898 ft_extattr->hdr.type = udf_rw32(UDF_FILETIMES_ATTR_NO); 1899 ft_extattr->hdr.subtype = 1; /* [4/48.10.5] */ 1900 ft_extattr->hdr.a_l = udf_rw32(UDF_FILETIMES_ATTR_SIZE(1)); 1901 ft_extattr->d_l = udf_rw32(UDF_TIMESTAMP_SIZE); /* one item */ 1902 ft_extattr->existence = UDF_FILETIMES_FILE_CREATION; 1903 ft_extattr->times[0] = birthtime; 1904 1905 udf_extattr_append_internal((union dscrptr *) fe, 1906 (struct extattr_entry *) ft_extattr); 1907 free(ft_extattr); 1908 1909 /* record fidlength information */ 1910 fe->inf_len = udf_rw64(0); 1911 fe->l_ad = udf_rw32(0); 1912 fe->logblks_rec = udf_rw64(0); /* intern */ 1913 1914 crclen = sizeof(struct file_entry) - 1 - UDF_DESC_TAG_LENGTH; 1915 crclen += udf_rw32(fe->l_ea); 1916 1917 /* make sure the header sums stays correct */ 1918 fe->tag.desc_crc_len = udf_rw16(crclen); 1919 udf_validate_tag_and_crc_sums((union dscrptr *) fe); 1920 1921 *fep = fe; 1922 return 0; 1923 } 1924 1925 1926 int 1927 udf_create_new_efe(struct extfile_entry **efep, int file_type, struct stat *st) 1928 { 1929 struct extfile_entry *efe; 1930 struct icb_tag *icb; 1931 uint32_t crclen; /* XXX: should be 16; need to detect overflow */ 1932 uint16_t icbflags; 1933 1934 *efep = NULL; 1935 efe = calloc(1, context.sector_size); 1936 if (efe == NULL) 1937 return ENOMEM; 1938 1939 udf_inittag(&efe->tag, TAGID_EXTFENTRY, /* loc */ 0); 1940 icb = &efe->icbtag; 1941 1942 /* 1943 * Always use strategy type 4 unless on WORM wich we don't support 1944 * (yet). Fill in defaults and set for internal allocation of data. 1945 */ 1946 icb->strat_type = udf_rw16(4); 1947 icb->max_num_entries = udf_rw16(1); 1948 icb->file_type = file_type; /* 8 bit */ 1949 icb->flags = udf_rw16(UDF_ICB_INTERN_ALLOC); 1950 1951 efe->perm = udf_rw32(0x7fff); /* all is allowed */ 1952 efe->link_cnt = udf_rw16(0); /* explicit setting */ 1953 1954 efe->ckpoint = udf_rw32(1); /* user supplied file version */ 1955 1956 udf_set_timestamp_now(&efe->ctime); 1957 udf_set_timestamp_now(&efe->atime); 1958 udf_set_timestamp_now(&efe->attrtime); 1959 udf_set_timestamp_now(&efe->mtime); 1960 1961 /* set attributes */ 1962 if (st) { 1963 #if !HAVE_NBTOOL_CONFIG_H 1964 udf_set_timestamp(&efe->ctime, st->st_birthtime); 1965 #else 1966 udf_set_timestamp(&efe->ctime, 0); 1967 #endif 1968 udf_set_timestamp(&efe->atime, st->st_atime); 1969 udf_set_timestamp(&efe->attrtime, st->st_ctime); 1970 udf_set_timestamp(&efe->mtime, st->st_mtime); 1971 efe->uid = udf_rw32(st->st_uid); 1972 efe->gid = udf_rw32(st->st_gid); 1973 1974 efe->perm = unix_mode_to_udf_perm(st->st_mode); 1975 1976 icbflags = udf_rw16(efe->icbtag.flags); 1977 icbflags &= ~UDF_ICB_TAG_FLAGS_SETUID; 1978 icbflags &= ~UDF_ICB_TAG_FLAGS_SETGID; 1979 icbflags &= ~UDF_ICB_TAG_FLAGS_STICKY; 1980 if (st->st_mode & S_ISUID) 1981 icbflags |= UDF_ICB_TAG_FLAGS_SETUID; 1982 if (st->st_mode & S_ISGID) 1983 icbflags |= UDF_ICB_TAG_FLAGS_SETGID; 1984 if (st->st_mode & S_ISVTX) 1985 icbflags |= UDF_ICB_TAG_FLAGS_STICKY; 1986 efe->icbtag.flags = udf_rw16(icbflags); 1987 } 1988 1989 udf_set_regid(&efe->imp_id, context.impl_name); 1990 udf_add_impl_regid(&efe->imp_id); 1991 1992 efe->unique_id = udf_rw64(context.unique_id); 1993 udf_advance_uniqueid(); 1994 1995 /* record fidlength information */ 1996 efe->inf_len = udf_rw64(0); 1997 efe->obj_size = udf_rw64(0); 1998 efe->l_ad = udf_rw32(0); 1999 efe->logblks_rec = udf_rw64(0); 2000 2001 crclen = sizeof(struct extfile_entry) - 1 - UDF_DESC_TAG_LENGTH; 2002 2003 /* make sure the header sums stays correct */ 2004 efe->tag.desc_crc_len = udf_rw16(crclen); 2005 udf_validate_tag_and_crc_sums((union dscrptr *) efe); 2006 2007 *efep = efe; 2008 return 0; 2009 } 2010 2011 /* --------------------------------------------------------------------- */ 2012 2013 /* for METADATA file appending only */ 2014 static void 2015 udf_append_meta_mapping_part_to_efe(struct extfile_entry *efe, 2016 struct short_ad *mapping) 2017 { 2018 struct icb_tag *icb; 2019 uint64_t inf_len, obj_size, logblks_rec; 2020 uint32_t l_ad, l_ea; 2021 uint16_t crclen; 2022 uint8_t *bpos; 2023 2024 inf_len = udf_rw64(efe->inf_len); 2025 obj_size = udf_rw64(efe->obj_size); 2026 logblks_rec = udf_rw64(efe->logblks_rec); 2027 l_ad = udf_rw32(efe->l_ad); 2028 l_ea = udf_rw32(efe->l_ea); 2029 crclen = udf_rw16(efe->tag.desc_crc_len); 2030 icb = &efe->icbtag; 2031 2032 /* set our allocation to shorts if not already done */ 2033 icb->flags = udf_rw16(UDF_ICB_SHORT_ALLOC); 2034 2035 /* append short_ad */ 2036 bpos = (uint8_t *) efe->data + l_ea + l_ad; 2037 memcpy(bpos, mapping, sizeof(struct short_ad)); 2038 2039 l_ad += sizeof(struct short_ad); 2040 crclen += sizeof(struct short_ad); 2041 inf_len += UDF_EXT_LEN(udf_rw32(mapping->len)); 2042 obj_size += UDF_EXT_LEN(udf_rw32(mapping->len)); 2043 logblks_rec = UDF_ROUNDUP(inf_len, context.sector_size) / 2044 context.sector_size; 2045 2046 efe->l_ad = udf_rw32(l_ad); 2047 efe->inf_len = udf_rw64(inf_len); 2048 efe->obj_size = udf_rw64(obj_size); 2049 efe->logblks_rec = udf_rw64(logblks_rec); 2050 efe->tag.desc_crc_len = udf_rw16(crclen); 2051 } 2052 2053 2054 /* for METADATA file appending only */ 2055 static void 2056 udf_append_meta_mapping_to_efe(struct extfile_entry *efe, 2057 uint16_t partnr, uint32_t lb_num, 2058 uint64_t len) 2059 { 2060 struct short_ad mapping; 2061 uint64_t max_len, part_len; 2062 2063 /* calculate max length meta allocation sizes */ 2064 max_len = UDF_EXT_MAXLEN / context.sector_size; /* in sectors */ 2065 max_len = (max_len / layout.meta_blockingnr) * layout.meta_blockingnr; 2066 max_len = max_len * context.sector_size; 2067 2068 memset(&mapping, 0, sizeof(mapping)); 2069 while (len) { 2070 part_len = MIN(len, max_len); 2071 mapping.lb_num = udf_rw32(lb_num); 2072 mapping.len = udf_rw32(part_len); 2073 2074 udf_append_meta_mapping_part_to_efe(efe, &mapping); 2075 2076 lb_num += part_len / context.sector_size; 2077 len -= part_len; 2078 } 2079 } 2080 2081 2082 int 2083 udf_create_meta_files(void) 2084 { 2085 struct extfile_entry *efe; 2086 struct long_ad meta_icb; 2087 uint64_t bytes; 2088 uint32_t sector_size; 2089 int filetype, error; 2090 2091 sector_size = context.sector_size; 2092 2093 memset(&meta_icb, 0, sizeof(meta_icb)); 2094 meta_icb.len = udf_rw32(sector_size); 2095 meta_icb.loc.part_num = udf_rw16(context.data_part); 2096 2097 /* create metadata file */ 2098 meta_icb.loc.lb_num = udf_rw32(layout.meta_file); 2099 filetype = UDF_ICB_FILETYPE_META_MAIN; 2100 error = udf_create_new_efe(&efe, filetype, NULL); 2101 if (error) 2102 return error; 2103 context.meta_file = efe; 2104 2105 /* create metadata mirror file */ 2106 meta_icb.loc.lb_num = udf_rw32(layout.meta_mirror); 2107 filetype = UDF_ICB_FILETYPE_META_MIRROR; 2108 error = udf_create_new_efe(&efe, filetype, NULL); 2109 if (error) 2110 return error; 2111 context.meta_mirror = efe; 2112 2113 /* create metadata bitmap file */ 2114 meta_icb.loc.lb_num = udf_rw32(layout.meta_bitmap); 2115 filetype = UDF_ICB_FILETYPE_META_BITMAP; 2116 error = udf_create_new_efe(&efe, filetype, NULL); 2117 if (error) 2118 return error; 2119 context.meta_bitmap = efe; 2120 2121 /* patch up files */ 2122 context.meta_file->unique_id = udf_rw64(0); 2123 context.meta_mirror->unique_id = udf_rw64(0); 2124 context.meta_bitmap->unique_id = udf_rw64(0); 2125 2126 /* restart unique id */ 2127 context.unique_id = 0x10; 2128 2129 /* XXX no support for metadata mirroring yet */ 2130 /* insert extents */ 2131 efe = context.meta_file; 2132 udf_append_meta_mapping_to_efe(efe, context.data_part, 2133 layout.meta_part_start_lba, 2134 (uint64_t) layout.meta_part_size_lba * sector_size); 2135 2136 efe = context.meta_mirror; 2137 udf_append_meta_mapping_to_efe(efe, context.data_part, 2138 layout.meta_part_start_lba, 2139 (uint64_t) layout.meta_part_size_lba * sector_size); 2140 2141 efe = context.meta_bitmap; 2142 bytes = udf_space_bitmap_len(layout.meta_part_size_lba); 2143 udf_append_meta_mapping_to_efe(efe, context.data_part, 2144 layout.meta_bitmap_space, bytes); 2145 2146 return 0; 2147 } 2148 2149 2150 /* --------------------------------------------------------------------- */ 2151 2152 int 2153 udf_create_new_rootdir(union dscrptr **dscr) 2154 { 2155 struct file_entry *fe; 2156 struct extfile_entry *efe; 2157 struct long_ad root_icb; 2158 int filetype, error; 2159 2160 memset(&root_icb, 0, sizeof(root_icb)); 2161 root_icb.len = udf_rw32(context.sector_size); 2162 root_icb.loc.lb_num = udf_rw32(layout.rootdir); 2163 root_icb.loc.part_num = udf_rw16(context.metadata_part); 2164 2165 filetype = UDF_ICB_FILETYPE_DIRECTORY; 2166 if (context.dscrver == 2) { 2167 error = udf_create_new_fe(&fe, filetype, NULL); 2168 *dscr = (union dscrptr *) fe; 2169 } else { 2170 error = udf_create_new_efe(&efe, filetype, NULL); 2171 *dscr = (union dscrptr *) efe; 2172 } 2173 if (error) 2174 return error; 2175 2176 /* append '..' */ 2177 udf_append_parentfid(*dscr, &root_icb); 2178 2179 /* rootdir has explicit only one link on creation; '..' is no link */ 2180 if (context.dscrver == 2) { 2181 fe->link_cnt = udf_rw16(1); 2182 } else { 2183 efe->link_cnt = udf_rw16(1); 2184 } 2185 2186 context.num_directories++; 2187 assert(context.num_directories == 1); 2188 2189 return 0; 2190 } 2191 2192 2193 void 2194 udf_prepend_VAT_file(void) 2195 { 2196 /* old style VAT has no prepend */ 2197 if (context.dscrver == 2) { 2198 context.vat_start = 0; 2199 context.vat_size = 0; 2200 return; 2201 } 2202 2203 context.vat_start = offsetof(struct udf_vat, data); 2204 context.vat_size = offsetof(struct udf_vat, data); 2205 } 2206 2207 2208 void 2209 udf_vat_update(uint32_t virt, uint32_t phys) 2210 { 2211 uint32_t *vatpos; 2212 uint32_t new_size; 2213 2214 if (context.vtop_tp[context.metadata_part] != UDF_VTOP_TYPE_VIRT) 2215 return; 2216 2217 new_size = MAX(context.vat_size, 2218 (context.vat_start + (virt+1)*sizeof(uint32_t))); 2219 2220 if (new_size > context.vat_allocated) { 2221 context.vat_allocated = 2222 UDF_ROUNDUP(new_size, context.sector_size); 2223 context.vat_contents = realloc(context.vat_contents, 2224 context.vat_allocated); 2225 assert(context.vat_contents); 2226 /* XXX could also report error */ 2227 } 2228 vatpos = (uint32_t *) (context.vat_contents + context.vat_start); 2229 vatpos[virt] = udf_rw32(phys); 2230 2231 context.vat_size = MAX(context.vat_size, 2232 (context.vat_start + (virt+1)*sizeof(uint32_t))); 2233 } 2234 2235 2236 int 2237 udf_append_VAT_file(void) 2238 { 2239 struct udf_oldvat_tail *oldvat_tail; 2240 struct udf_vat *vathdr; 2241 int32_t len_diff; 2242 2243 /* new style VAT has VAT LVInt analog in front */ 2244 if (context.dscrver == 3) { 2245 /* set up VATv2 descriptor */ 2246 vathdr = (struct udf_vat *) context.vat_contents; 2247 vathdr->header_len = udf_rw16(sizeof(struct udf_vat) - 1); 2248 vathdr->impl_use_len = udf_rw16(0); 2249 memcpy(vathdr->logvol_id, context.logical_vol->logvol_id, 128); 2250 vathdr->prev_vat = udf_rw32(UDF_NO_PREV_VAT); 2251 vathdr->num_files = udf_rw32(context.num_files); 2252 vathdr->num_directories = udf_rw32(context.num_directories); 2253 2254 vathdr->min_udf_readver = udf_rw16(context.min_udf); 2255 vathdr->min_udf_writever = udf_rw16(context.min_udf); 2256 vathdr->max_udf_writever = udf_rw16(context.max_udf); 2257 2258 return 0; 2259 } 2260 2261 /* old style VAT has identifier appended */ 2262 2263 /* append "*UDF Virtual Alloc Tbl" id and prev. VAT location */ 2264 len_diff = context.vat_allocated - context.vat_size; 2265 assert(len_diff >= 0); 2266 if (len_diff < (int32_t) sizeof(struct udf_oldvat_tail)) { 2267 context.vat_allocated += context.sector_size; 2268 context.vat_contents = realloc(context.vat_contents, 2269 context.vat_allocated); 2270 assert(context.vat_contents); 2271 /* XXX could also report error */ 2272 } 2273 2274 oldvat_tail = (struct udf_oldvat_tail *) (context.vat_contents + 2275 context.vat_size); 2276 2277 udf_set_regid(&oldvat_tail->id, "*UDF Virtual Alloc Tbl"); 2278 udf_add_udf_regid(&oldvat_tail->id); 2279 oldvat_tail->prev_vat = udf_rw32(UDF_NO_PREV_VAT); 2280 2281 context.vat_size += sizeof(struct udf_oldvat_tail); 2282 2283 return 0; 2284 } 2285 2286 2287 int 2288 udf_create_VAT(union dscrptr **vat_dscr) 2289 { 2290 struct file_entry *fe; 2291 struct extfile_entry *efe; 2292 struct impl_extattr_entry *implext; 2293 struct vatlvext_extattr_entry *vatlvext; 2294 struct long_ad dataloc, *allocpos; 2295 uint8_t *bpos, *extattr; 2296 uint32_t ea_len, inf_len, vat_len, blks; 2297 int filetype; 2298 int error; 2299 2300 assert((layout.rootdir < 2) && (layout.fsd < 2)); 2301 2302 memset(&dataloc, 0, sizeof(dataloc)); 2303 dataloc.len = udf_rw32(context.vat_size); 2304 dataloc.loc.part_num = udf_rw16(context.data_part); 2305 dataloc.loc.lb_num = udf_rw32(layout.vat); 2306 2307 if (context.dscrver == 2) { 2308 /* old style VAT */ 2309 filetype = UDF_ICB_FILETYPE_UNKNOWN; 2310 error = udf_create_new_fe(&fe, filetype, NULL); 2311 if (error) 2312 return error; 2313 2314 /* append VAT LVExtension attribute */ 2315 ea_len = sizeof(struct impl_extattr_entry) - 1 + 2316 sizeof(struct vatlvext_extattr_entry) + 4; 2317 2318 extattr = calloc(1, ea_len); 2319 2320 implext = (struct impl_extattr_entry *) extattr; 2321 implext->hdr.type = udf_rw32(2048); /* [4/48.10.8] */ 2322 implext->hdr.subtype = 1; /* [4/48.10.8.2] */ 2323 implext->hdr.a_l = udf_rw32(ea_len); /* VAT LVext EA size */ 2324 /* use 4 bytes of imp use for UDF checksum [UDF 3.3.4.5] */ 2325 implext->iu_l = udf_rw32(4); 2326 udf_set_regid(&implext->imp_id, "*UDF VAT LVExtension"); 2327 udf_add_udf_regid(&implext->imp_id); 2328 2329 /* VAT LVExtension data follows UDF IU space */ 2330 bpos = ((uint8_t *) implext->data) + 4; 2331 vatlvext = (struct vatlvext_extattr_entry *) bpos; 2332 2333 vatlvext->unique_id_chk = udf_rw64(fe->unique_id); 2334 vatlvext->num_files = udf_rw32(context.num_files); 2335 vatlvext->num_directories = udf_rw32(context.num_directories); 2336 memcpy(vatlvext->logvol_id, context.logical_vol->logvol_id,128); 2337 2338 udf_extattr_append_internal((union dscrptr *) fe, 2339 (struct extattr_entry *) extattr); 2340 2341 free(extattr); 2342 2343 fe->icbtag.flags = udf_rw16(UDF_ICB_LONG_ALLOC); 2344 2345 allocpos = (struct long_ad *) (fe->data + udf_rw32(fe->l_ea)); 2346 *allocpos = dataloc; 2347 2348 /* set length */ 2349 inf_len = context.vat_size; 2350 fe->inf_len = udf_rw64(inf_len); 2351 fe->l_ad = udf_rw32(sizeof(struct long_ad)); 2352 blks = UDF_ROUNDUP(inf_len, context.sector_size) / 2353 context.sector_size; 2354 fe->logblks_rec = udf_rw32(blks); 2355 2356 /* update vat descriptor's CRC length */ 2357 vat_len = sizeof(struct file_entry) - 1 - UDF_DESC_TAG_LENGTH; 2358 vat_len += udf_rw32(fe->l_ad) + udf_rw32(fe->l_ea); 2359 fe->tag.desc_crc_len = udf_rw16(vat_len); 2360 2361 *vat_dscr = (union dscrptr *) fe; 2362 } else { 2363 /* new style VAT */ 2364 filetype = UDF_ICB_FILETYPE_VAT; 2365 error = udf_create_new_efe(&efe, filetype, NULL); 2366 if (error) 2367 return error; 2368 2369 efe->icbtag.flags = udf_rw16(UDF_ICB_LONG_ALLOC); 2370 2371 allocpos = (struct long_ad *) efe->data; 2372 *allocpos = dataloc; 2373 2374 /* set length */ 2375 inf_len = context.vat_size; 2376 efe->inf_len = udf_rw64(inf_len); 2377 efe->obj_size = udf_rw64(inf_len); 2378 efe->l_ad = udf_rw32(sizeof(struct long_ad)); 2379 blks = UDF_ROUNDUP(inf_len, context.sector_size) / 2380 context.sector_size; 2381 efe->logblks_rec = udf_rw32(blks); 2382 2383 vat_len = sizeof(struct extfile_entry)-1 - UDF_DESC_TAG_LENGTH; 2384 vat_len += udf_rw32(efe->l_ad); 2385 efe->tag.desc_crc_len = udf_rw16(vat_len); 2386 2387 *vat_dscr = (union dscrptr *) efe; 2388 } 2389 2390 return 0; 2391 } 2392 2393