/[debburn]/nonameyet/trunk/mkisofs/udf.c
ViewVC logotype

Contents of /nonameyet/trunk/mkisofs/udf.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 34 - (show annotations) (download)
Wed Aug 23 12:01:05 2006 UTC (6 years, 8 months ago) by blade
File MIME type: text/plain
File size: 41514 byte(s)
iconv support
1 /* @(#)udf.c 1.14 04/04/15 Copyright 2001 J. Schilling */
2 #ifndef lint
3 static char sccsid[] =
4 "@(#)udf.c 1.14 04/04/15 Copyright 2001 J. Schilling";
5 #endif
6 /*
7 * udf.c - UDF support for mkisofs
8 *
9 * Written by Ben Rudiak-Gould (2001).
10 *
11 * Copyright 2001 J. Schilling.
12 */
13 /*
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2
16 * as published by the Free Software Foundation.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License along with
24 * this program; see the file COPYING. If not, write to the Free Software
25 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */
27
28 /*
29 * Some remaining issues:
30 *
31 * - Do not forget to edit joliet.c and remove the VIDEO_TS lines after
32 * we did implement a decent own file name handling for UDF.
33 *
34 * - UDF supports UNIX-style file permissions and uid/gid, but currently
35 * this code just sets them to default values and ignores their Rock
36 * Ridge counterparts. This would be easy to fix.
37 *
38 * - There's no support for symlinks, Mac type/creator, or Mac resource
39 * forks. Hard links and followed symlinks may work, but if so, it's
40 * only by accident.
41 *
42 * - The file system mirrors the Joliet file system, so files excluded
43 * from Joliet will also be excluded from UDF, the -jcharset option
44 * also applies to UDF, file names too long for Joliet will also be
45 * truncated on UDF, and characters not allowed by Joliet will also
46 * be translated on UDF. (Fortunately, Joliet is pretty lenient.)
47 *
48 * - convert_to_unicode is always called with in_nls, not hfs_nls. This
49 * may lead to incorrect name conversion sometimes when using a Mac
50 * filesystem. See joliet.c for an example of what's supposed to be
51 * done.
52 *
53 * - DVD-Video discs are supposed to have Copyright Management Information
54 * in both the ISO and UDF filesystems. This is not implemented in ISO,
55 * and the code to do it in UDF is currently #ifdef'd out. I'm not sure
56 * whether discs without this information are actually DVD-Video
57 * compliant. The Copyright Management Information is described in ECMA
58 * Technical Report TR/71.
59 *
60 * - Most of the space before sector 256 on the disc (~480K) is wasted,
61 * because UDF Bridge requires a pointer block at sector 256. ISO 9660
62 * structures could be moved below sector 256 if they're small enough, but
63 * this would be ugly to implement since it breaks the output_fragment
64 * abstraction.
65 *
66 * - Each file must have a File Entry, and each File Entry seems to
67 * require its own 2K sector. As a result, there is an overhead of more
68 * than 2K *per file* when using UDF. I couldn't see any way to avoid
69 * this.
70 *
71 * - Read performance would probably be improved by placing the File Entry
72 * for each file just before the file itself, instead of at the beginning
73 * of the disc. But this would not work for DVD-Video files, which have
74 * to be stored contiguously. So there would have to be an override
75 * mechanism to handle this case. I don't know if it's worth the trouble.
76 */
77
78 #ifdef UDF
79
80 #include "config.h"
81 #include "mkisofs.h"
82 #include <timedefs.h>
83 #include <schily.h>
84
85 #include "udf.h"
86 #include "udf_fs.h"
87
88 extern int use_sparcboot;
89
90 extern struct directory *root;
91 extern time_t begun;
92
93 static unsigned lba_main_seq;
94 static unsigned lba_main_seq_copy;
95 static unsigned lba_integ_seq;
96 static unsigned lba_udf_partition_start;
97 static unsigned lba_last_file_entry;
98 static unsigned lba_end_anchor_vol_desc;
99
100 static unsigned num_udf_files;
101 static unsigned num_udf_directories;
102
103 static unsigned volume_set_id[2];
104
105 #define UDF_MAIN_SEQ_LENGTH (16)
106 #define UDF_INTEG_SEQ_LENGTH (2)
107
108 /* only works for granularity a power of 2! */
109 #define PAD(val, granularity) (((val)+(granularity)-1)&~((granularity)-1))
110
111 #define read_733(field) ((0[field]&255)+(1[field]&255)*256+(2[field]&255)*65536+(3[field]&255)*16777216)
112
113
114 /**************** SIZE ****************/
115
116 static int set_file_ident_desc __PR((unsigned char *, unsigned, char *, int, unsigned, unsigned));
117
118 static unsigned
119 #ifdef PROTOTYPES
120 directory_size(struct directory *dpnt)
121 #else
122 directory_size(dpnt)
123 struct directory *dpnt;
124 #endif
125 {
126 unsigned size_in_bytes;
127 struct directory_entry *de;
128 Uchar dummy_buf[SECTOR_SIZE];
129
130 /* parent directory */
131 size_in_bytes = set_file_ident_desc(dummy_buf, 0, 0, 0, 0, 0);
132
133 /* directory contents */
134 for (de = dpnt->jcontents; de; de = de->jnext) {
135 if (!(de->de_flags & INHIBIT_JOLIET_ENTRY)) {
136 char *name = USE_MAC_NAME(de) ? de->hfs_ent->name : de->name;
137 /* skip . and .. */
138 if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
139 continue;
140 size_in_bytes += set_file_ident_desc(dummy_buf, 0, name, 0, 0, 0);
141 }
142 }
143 return (size_in_bytes);
144 }
145
146 static void
147 #ifdef PROTOTYPES
148 assign_udf_directory_addresses(struct directory *dpnt)
149 #else
150 assign_udf_directory_addresses(dpnt)
151 struct directory *dpnt;
152 #endif
153 {
154 if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY)) {
155 dpnt->self->udf_file_entry_sector = last_extent;
156 last_extent += 1 + ISO_BLOCKS(directory_size(dpnt));
157 ++num_udf_directories;
158 }
159 if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir) {
160 for (dpnt = dpnt->subdir; dpnt; dpnt = dpnt->next) {
161 assign_udf_directory_addresses(dpnt);
162 }
163 }
164 }
165
166 static void
167 #ifdef PROTOTYPES
168 assign_udf_file_entry_addresses(struct directory *dpnt)
169 #else
170 assign_udf_file_entry_addresses(dpnt)
171 struct directory *dpnt;
172 #endif
173 {
174 if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY)) {
175 struct directory_entry *de;
176 for (de = dpnt->jcontents; de; de = de->jnext) {
177 if (!(de->de_flags & RELOCATED_DIRECTORY) &&
178 !(de->isorec.flags[0] & ISO_DIRECTORY)) {
179 de->udf_file_entry_sector = last_extent++;
180 ++num_udf_files;
181 }
182 }
183 }
184 if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir) {
185 for (dpnt = dpnt->subdir; dpnt; dpnt = dpnt->next) {
186 assign_udf_file_entry_addresses(dpnt);
187 }
188 }
189 }
190
191 /****************************/
192
193 static int
194 #ifdef PROTOTYPES
195 udf_vol_recognition_area_size(int starting_extent)
196 #else
197 udf_vol_recognition_area_size(starting_extent)
198 int starting_extent;
199 #endif
200 {
201 last_extent = starting_extent+3;
202 return (0);
203 }
204
205 static int
206 #ifdef PROTOTYPES
207 udf_main_seq_size(int starting_extent)
208 #else
209 udf_main_seq_size(starting_extent)
210 int starting_extent;
211 #endif
212 {
213 lba_main_seq = starting_extent;
214 last_extent = starting_extent + UDF_MAIN_SEQ_LENGTH;
215 return (0);
216 }
217
218 static int
219 #ifdef PROTOTYPES
220 udf_main_seq_copy_size(int starting_extent)
221 #else
222 udf_main_seq_copy_size(starting_extent)
223 int starting_extent;
224 #endif
225 {
226 lba_main_seq_copy = starting_extent;
227 last_extent = starting_extent + UDF_MAIN_SEQ_LENGTH;
228 return (0);
229 }
230
231 static int
232 #ifdef PROTOTYPES
233 udf_integ_seq_size(int starting_extent)
234 #else
235 udf_integ_seq_size(starting_extent)
236 int starting_extent;
237 #endif
238 {
239 lba_integ_seq = starting_extent;
240 last_extent = starting_extent + UDF_INTEG_SEQ_LENGTH;
241 return (0);
242 }
243
244 static int
245 #ifdef PROTOTYPES
246 udf_end_anchor_vol_desc_size(int starting_extent)
247 #else
248 udf_end_anchor_vol_desc_size(starting_extent)
249 int starting_extent;
250 #endif
251 {
252 lba_end_anchor_vol_desc = starting_extent;
253 last_extent = starting_extent+1;
254 return (0);
255 }
256
257 static int
258 #ifdef PROTOTYPES
259 udf_file_set_desc_size(int starting_extent)
260 #else
261 udf_file_set_desc_size(starting_extent)
262 int starting_extent;
263 #endif
264 {
265 lba_udf_partition_start = starting_extent;
266 last_extent = starting_extent+2;
267 return (0);
268 }
269
270 static int
271 #ifdef PROTOTYPES
272 udf_dirtree_size(int starting_extent)
273 #else
274 udf_dirtree_size(starting_extent)
275 int starting_extent;
276 #endif
277 {
278 num_udf_directories = 0;
279 assign_udf_directory_addresses(root);
280 return (0);
281 }
282
283 static int
284 #ifdef PROTOTYPES
285 udf_file_entries_size(int starting_extent)
286 #else
287 udf_file_entries_size(starting_extent)
288 int starting_extent;
289 #endif
290 {
291 num_udf_files = 0;
292 assign_udf_file_entry_addresses(root);
293 lba_last_file_entry = last_extent-1;
294 return (0);
295 }
296
297 static int
298 #ifdef PROTOTYPES
299 udf_pad_to_sector_32_size(int starting_extent)
300 #else
301 udf_pad_to_sector_32_size(starting_extent)
302 int starting_extent;
303 #endif
304 {
305 if (last_extent < session_start+32)
306 last_extent = session_start+32;
307 return (0);
308 }
309
310 static int
311 #ifdef PROTOTYPES
312 udf_pad_to_sector_256_size(int starting_extent)
313 #else
314 udf_pad_to_sector_256_size(starting_extent)
315 int starting_extent;
316 #endif
317 {
318 if (last_extent < session_start+256)
319 last_extent = session_start+256;
320 return (0);
321 }
322
323 static int
324 #ifdef PROTOTYPES
325 udf_padend_avdp_size(int starting_extent)
326 #else
327 udf_padend_avdp_size(starting_extent)
328 int starting_extent;
329 #endif
330 {
331 lba_end_anchor_vol_desc = starting_extent;
332
333 /* add at least 16 and at most 31 sectors, ending at a mult. of 16 */
334 last_extent = (starting_extent+31) & ~15;
335 if (!use_sparcboot)
336 last_extent = starting_extent + 150;
337 return (0);
338 }
339
340 extern int oneblock_size __PR((int));
341
342 /**************** WRITE ****************/
343
344 static unsigned
345 #ifdef PROTOTYPES
346 crc_ccitt(unsigned char *buf, unsigned len)
347 #else
348 crc_ccitt(buf, len)
349 unsigned char *buf;
350 unsigned len;
351 #endif
352 {
353 const unsigned poly = 0x11021;
354 static unsigned short lookup[256];
355 unsigned int r;
356 unsigned int i;
357
358 if (lookup[1] == 0) {
359 unsigned int j, k;
360 for (j = 0; j < 256; ++j) {
361 unsigned int temp = j << 8;
362 for (k = 0; k < 8; ++k) {
363 unsigned int hibit = temp & 32768;
364 temp <<= 1;
365 if (hibit)
366 temp ^= poly;
367 }
368 lookup[j] = temp;
369 }
370 }
371
372 r = 0;
373 for (i = 0; i < len; ++i) {
374 r = (r << 8) ^ lookup[((r >> 8) ^ buf[i]) & 255];
375 }
376
377 return (r & 65535);
378 }
379
380 #define set8(dst, src) do { *(dst) = (src); } while (0)
381
382 static void
383 #ifdef PROTOTYPES
384 set16(udf_Uint16 *dst, unsigned int src)
385 #else
386 set16(dst, src)
387 udf_Uint16 *dst;
388 unsigned int src;
389 #endif
390 {
391 dst->l = (char)(src);
392 dst->h = (char)(src>>8);
393 }
394
395 static void
396 #ifdef PROTOTYPES
397 set32(udf_Uint32 *dst, unsigned src)
398 #else
399 set32(dst, src)
400 udf_Uint32 *dst;
401 unsigned src;
402 #endif
403 {
404 dst->l = (char)(src);
405 dst->ml = (char)(src>>8);
406 dst->mh = (char)(src>>16);
407 dst->h = (char)(src>>24);
408 }
409
410 static void
411 #ifdef PROTOTYPES
412 set64(udf_Uint64 *dst, unsigned src)
413 #else
414 set64(dst, src)
415 udf_Uint64 *dst;
416 unsigned src;
417 #endif
418 {
419 set32(&dst->l, src);
420 /*
421 * src>>32 actually does the wrong thing on x86 with at least
422 * one compiler, because of x86's shift count masking. Since
423 * we never pass more than 32 sig. bits to the function anyway,
424 * and all the structures we fill in are zeroed beforehand,
425 * just skip setting the high word.
426 */
427 /*set32(&dst->h, src>>32);*/
428 }
429
430 static int
431 #ifdef PROTOTYPES
432 set_ostaunicode(unsigned char *dst, int dst_size, char *src)
433 #else
434 set_ostaunicode(dst, dst_size, src)
435 unsigned char *dst;
436 int dst_size;
437 char *src;
438 #endif
439 {
440 unsigned char buf[1024];
441 int i;
442 int expanded_length;
443
444 expanded_length = joliet_strlen(src, in_nls);
445 if (expanded_length > 1024)
446 expanded_length = 1024;
447 if (expanded_length > (dst_size-1)*2)
448 expanded_length = (dst_size-1)*2;
449
450 convert_to_unicode(buf, expanded_length, src, in_nls);
451 dst[0] = 8; /* use 8-bit representation by default */
452 for (i = 0; i < (expanded_length>>1); ++i) {
453 dst[i + 1] = buf[i*2+1];
454 if (buf[i*2] != 0) {
455 /*
456 * There's a Unicode character with value >=256.
457 * Use 16-bit representation instead.
458 */
459 int length_to_copy = (dst_size-1) & ~1;
460 if (length_to_copy > expanded_length)
461 length_to_copy = expanded_length;
462 dst[0] = 16;
463 memcpy(dst+1, buf, length_to_copy);
464 return (length_to_copy + 1);
465 }
466 }
467 return ((expanded_length>>1) + 1);
468 }
469
470 static void
471 #ifdef PROTOTYPES
472 set_extent(udf_extent_ad *ext, unsigned lba, unsigned length_bytes)
473 #else
474 set_extent(ext, lba, length_bytes)
475 udf_extent_ad *ext;
476 unsigned lba;
477 unsigned length_bytes;
478 #endif
479 {
480 set32(&ext->extent_length, length_bytes);
481 set32(&ext->extent_location, lba);
482 }
483
484 static void
485 #ifdef PROTOTYPES
486 set_dstring(udf_dstring *dst, char *src, int n)
487 #else
488 set_dstring(dst, src, n)
489 udf_dstring *dst;
490 char *src;
491 int n;
492 #endif
493 {
494 dst[n-1] = set_ostaunicode((Uchar *)dst, n-1, src);
495 }
496
497 static void
498 #ifdef PROTOTYPES
499 set_charspec(udf_charspec *dst)
500 #else
501 set_charspec(dst)
502 udf_charspec *dst;
503 #endif
504 {
505 /*set8(&dst->character_set_type, 0);*/
506 memcpy(dst->character_set_info, "OSTA Compressed Unicode", 23);
507 }
508
509 static void
510 #ifdef PROTOTYPES
511 set_impl_ident(udf_EntityID *ent)
512 #else
513 set_impl_ident(ent)
514 udf_EntityID *ent;
515 #endif
516 {
517 strcpy((char *)ent->ident, "*mkisofs");
518 }
519
520 static void
521 #ifdef PROTOTYPES
522 set_tag(udf_tag *t, unsigned tid, unsigned lba, int crc_length)
523 #else
524 set_tag(t, tid, lba, crc_length)
525 udf_tag *t;
526 unsigned tid;
527 unsigned lba;
528 int crc_length;
529 #endif
530 {
531 unsigned char checksum;
532 int i;
533
534 set16(&t->tag_ident, tid);
535 set16(&t->desc_version, 2);
536 set16(&t->desc_crc, crc_ccitt((unsigned char *)t+16, crc_length-16));
537 set16(&t->desc_crc_length, crc_length-16);
538 set32(&t->tag_location, lba);
539 set8(&t->tag_checksum, 0);
540 checksum = 0;
541 for (i = 0; i < 16; ++i)
542 checksum += ((unsigned char *)t)[i];
543 set8(&t->tag_checksum, checksum);
544 }
545
546 static void
547 #ifdef PROTOTYPES
548 set_timestamp_from_iso_date(udf_timestamp *ts, const char *iso_date_raw)
549 #else
550 set_timestamp_from_iso_date(ts, iso_date_raw)
551 udf_timestamp *ts;
552 const char *iso_date_raw;
553 #endif
554 {
555 struct {
556 unsigned char years_since_1900;
557 unsigned char month, day;
558 unsigned char hour, minute, second;
559 signed char offset_from_gmt;
560 } *iso_date = (void *)iso_date_raw;
561
562 set16(&ts->type_and_time_zone,
563 4096 + ((iso_date->offset_from_gmt * 15) & 4095));
564 set16(&ts->year, 1900 + iso_date->years_since_1900);
565 set8(&ts->month, iso_date->month);
566 set8(&ts->day, iso_date->day);
567 set8(&ts->hour, iso_date->hour);
568 set8(&ts->minute, iso_date->minute);
569 set8(&ts->second, iso_date->second);
570 /*set8(&ts->centiseconds, 0);*/
571 /*set8(&ts->hundreds_of_microseconds, 0);*/
572 /*set8(&ts->microseconds, 0);*/
573 }
574
575 static void
576 #ifdef PROTOTYPES
577 set_timestamp_from_time_t(udf_timestamp *ts, time_t t)
578 #else
579 set_timestamp_from_time_t(ts, t)
580 udf_timestamp *ts;
581 time_t t;
582 #endif
583 {
584 char iso_date[7];
585 iso9660_date(iso_date, t);
586 set_timestamp_from_iso_date(ts, iso_date);
587 }
588
589
590 static void
591 #ifdef PROTOTYPES
592 set_anchor_volume_desc_pointer(unsigned char *buf, unsigned lba)
593 #else
594 set_anchor_volume_desc_pointer(buf, lba)
595 unsigned char *buf;
596 unsigned lba;
597 #endif
598 {
599 udf_anchor_volume_desc_ptr *avdp = (udf_anchor_volume_desc_ptr *)buf;
600 set_extent(&avdp->main_volume_desc_seq_extent,
601 lba_main_seq, SECTOR_SIZE*UDF_MAIN_SEQ_LENGTH);
602 set_extent(&avdp->reserve_volume_desc_seq_extent,
603 lba_main_seq_copy, SECTOR_SIZE*UDF_MAIN_SEQ_LENGTH);
604 set_tag(&avdp->desc_tag, UDF_TAGID_ANCHOR_VOLUME_DESC_PTR, lba, 512);
605 }
606
607 static void
608 #ifdef PROTOTYPES
609 set_primary_vol_desc(unsigned char *buf, unsigned lba)
610 #else
611 set_primary_vol_desc(buf, lba)
612 unsigned char *buf;
613 unsigned lba;
614 #endif
615 {
616 char temp[17];
617
618 udf_primary_volume_desc *pvd = (udf_primary_volume_desc *)buf;
619 /*set32(&pvd->volume_desc_seq_number, 0);*/
620 /*set32(&pvd->primary_volume_desc_number, 0);*/
621 set_dstring(pvd->volume_ident, volume_id, sizeof (pvd->volume_ident));
622 set16(&pvd->volume_seq_number, 1);
623 set16(&pvd->maximum_volume_seq_number, 1);
624 set16(&pvd->interchange_level, 2);
625 set16(&pvd->maximum_interchange_level, 2);
626 set32(&pvd->character_set_list, 1);
627 set32(&pvd->maximum_character_set_list, 1);
628 sprintf(temp, "%08X%08X", volume_set_id[0], volume_set_id[1]);
629 set_dstring(pvd->volume_set_ident, temp,
630 sizeof (pvd->volume_set_ident));
631 set_charspec(&pvd->desc_character_set);
632 set_charspec(&pvd->explanatory_character_set);
633 /*pvd->volume_abstract;*/
634 /*pvd->volume_copyright_notice;*/
635 /*pvd->application_ident;*/
636 set_timestamp_from_time_t(&pvd->recording_date_and_time, begun);
637 set_impl_ident(&pvd->impl_ident);
638 set_tag(&pvd->desc_tag, UDF_TAGID_PRIMARY_VOLUME_DESC, lba, 512);
639 }
640
641 static void
642 #ifdef PROTOTYPES
643 set_impl_use_vol_desc(unsigned char *buf, unsigned lba)
644 #else
645 set_impl_use_vol_desc(buf, lba)
646 unsigned char *buf;
647 unsigned lba;
648 #endif
649 {
650 udf_impl_use_volume_desc *iuvd = (udf_impl_use_volume_desc *)buf;
651 set32(&iuvd->volume_desc_seq_number, 1);
652 strcpy((char *)iuvd->impl_ident.ident, "*UDF LV Info");
653 iuvd->impl_ident.ident_suffix[0] = 2;
654 iuvd->impl_ident.ident_suffix[1] = 1;
655 set_charspec(&iuvd->impl_use.lvi_charset);
656 set_dstring(iuvd->impl_use.logical_volume_ident, volume_id,
657 sizeof (iuvd->impl_use.logical_volume_ident));
658 /*set_dstring(iuvd->impl_use.lv_info1, "", sizeof (iuvd->impl_use.lv_info1));*/
659 /*set_dstring(iuvd->impl_use.lv_info2, "", sizeof (iuvd->impl_use.lv_info2));*/
660 /*set_dstring(iuvd->impl_use.lv_info3, "", sizeof (iuvd->impl_use.lv_info3));*/
661 set_impl_ident(&iuvd->impl_use.impl_id);
662 set_tag(&iuvd->desc_tag, UDF_TAGID_IMPL_USE_VOLUME_DESC, lba, 512);
663 }
664
665 static void
666 #ifdef PROTOTYPES
667 set_partition_desc(unsigned char *buf, unsigned lba)
668 #else
669 set_partition_desc(buf, lba)
670 unsigned char *buf;
671 unsigned lba;
672 #endif
673 {
674 udf_partition_desc *pd = (udf_partition_desc *)buf;
675 set32(&pd->volume_desc_seq_number, 2);
676 set16(&pd->partition_flags, UDF_PARTITION_FLAG_ALLOCATED);
677 /*set16(&pd->partition_number, 0);*/
678 set8(&pd->partition_contents.flags, UDF_ENTITYID_FLAG_PROTECTED); /*???*/
679 strcpy((char *)pd->partition_contents.ident, "+NSR02");
680 set32(&pd->access_type, UDF_ACCESSTYPE_READONLY);
681 set32(&pd->partition_starting_location, lba_udf_partition_start);
682 set32(&pd->partition_length,
683 lba_end_anchor_vol_desc - lba_udf_partition_start);
684 set_impl_ident(&pd->impl_ident);
685 set_tag(&pd->desc_tag, UDF_TAGID_PARTITION_DESC, lba, 512);
686 }
687
688 static void
689 #ifdef PROTOTYPES
690 set_domain_ident(udf_EntityID *ent)
691 #else
692 set_domain_ident(ent)
693 udf_EntityID *ent;
694 #endif
695 {
696 strcpy((char *)ent->ident, "*OSTA UDF Compliant");
697 memcpy(ent->ident_suffix, "\002\001\003", 3);
698 }
699
700 static void
701 #ifdef PROTOTYPES
702 set_logical_vol_desc(unsigned char *buf, unsigned lba)
703 #else
704 set_logical_vol_desc(buf, lba)
705 unsigned char *buf;
706 unsigned lba;
707 #endif
708 {
709 udf_logical_volume_desc *lvd = (udf_logical_volume_desc *)buf;
710 set32(&lvd->volume_desc_seq_number, 3);
711 set_charspec(&lvd->desc_character_set);
712 set_dstring(lvd->logical_volume_ident, volume_id,
713 sizeof (lvd->logical_volume_ident));
714 set32(&lvd->logical_block_size, SECTOR_SIZE);
715 set_domain_ident(&lvd->domain_ident);
716 set32(&lvd->logical_volume_contents_use.extent_length, 2*SECTOR_SIZE);
717 /*set32(&lvd->logical_volume_contents_use.extent_location.logical_block_number, 0);*/
718 /*set16(&lvd->logical_volume_contents_use.extent_location.partition_reference_number, 0);*/
719 set32(&lvd->map_table_length, 6);
720 set32(&lvd->number_of_partition_maps, 1);
721 set_impl_ident(&lvd->impl_ident);
722 set_extent(&lvd->integrity_seq_extent, lba_integ_seq,
723 SECTOR_SIZE*UDF_INTEG_SEQ_LENGTH);
724 set8(&lvd->partition_map[0].partition_map_type,
725 UDF_PARTITION_MAP_TYPE_1);
726 set8(&lvd->partition_map[0].partition_map_length, 6);
727 set16(&lvd->partition_map[0].volume_seq_number, 1);
728 /*set16(&lvd->partition_map[0].partition_number, 0);*/
729 set_tag(&lvd->desc_tag, UDF_TAGID_LOGICAL_VOLUME_DESC, lba, 446);
730 }
731
732 static void
733 #ifdef PROTOTYPES
734 set_unallocated_space_desc(unsigned char *buf, unsigned lba)
735 #else
736 set_unallocated_space_desc(buf, lba)
737 unsigned char *buf;
738 unsigned lba;
739 #endif
740 {
741 udf_unallocated_space_desc *usd = (udf_unallocated_space_desc *)buf;
742 set32(&usd->volume_desc_seq_number, 4);
743 /*set32(&usd->number_of_allocation_descs, 0);*/
744 set_tag(&usd->desc_tag, UDF_TAGID_UNALLOCATED_SPACE_DESC, lba, 24);
745 }
746
747 static void
748 #ifdef PROTOTYPES
749 set_terminating_desc(unsigned char *buf, unsigned lba)
750 #else
751 set_terminating_desc(buf, lba)
752 unsigned char *buf;
753 unsigned lba;
754 #endif
755 {
756 udf_terminating_desc *td = (udf_terminating_desc *)buf;
757 set_tag(&td->desc_tag, UDF_TAGID_TERMINATING_DESC, lba, 512);
758 }
759
760 static void
761 #ifdef PROTOTYPES
762 set_logical_vol_integrity_desc(unsigned char *buf, unsigned lba)
763 #else
764 set_logical_vol_integrity_desc(buf, lba)
765 unsigned char *buf;
766 unsigned lba;
767 #endif
768 {
769 udf_logical_volume_integrity_desc *lvid =
770 (udf_logical_volume_integrity_desc *)buf;
771
772 set_timestamp_from_time_t(&lvid->recording_date, begun);
773 set32(&lvid->integrity_type, UDF_INTEGRITY_TYPE_CLOSE);
774 /*lvid->next_integrity_extent;*/
775 set64(&lvid->logical_volume_contents_use.unique_id,
776 lba_last_file_entry+1);
777 set32(&lvid->number_of_partitions, 1);
778 set32(&lvid->length_of_impl_use, 46);
779 /*set32(&lvid->free_space_table, 0);*/
780 set32(&lvid->size_table,
781 lba_end_anchor_vol_desc - lba_udf_partition_start);
782 set_impl_ident(&lvid->impl_use.impl_id);
783 set32(&lvid->impl_use.number_of_files, num_udf_files);
784 set32(&lvid->impl_use.number_of_directories, num_udf_directories);
785 set16(&lvid->impl_use.minimum_udf_read_revision, 0x102);
786 set16(&lvid->impl_use.minimum_udf_write_revision, 0x102);
787 set16(&lvid->impl_use.maximum_udf_write_revision, 0x102);
788 set_tag(&lvid->desc_tag, UDF_TAGID_LOGICAL_VOLUME_INTEGRITY_DESC,
789 lba, 88+46);
790 }
791
792 static void
793 #ifdef PROTOTYPES
794 set_file_set_desc(unsigned char *buf, unsigned rba)
795 #else
796 set_file_set_desc(buf, rba)
797 unsigned char *buf;
798 unsigned rba;
799 #endif
800 {
801 udf_file_set_desc *fsd = (udf_file_set_desc *)buf;
802
803 set_timestamp_from_time_t(&fsd->recording_date_and_time, begun);
804 set16(&fsd->interchange_level, 3);
805 set16(&fsd->maximum_interchange_level, 3);
806 set32(&fsd->character_set_list, 1);
807 set32(&fsd->maximum_character_set_list, 1);
808 /*set32(&fsd->file_set_number, 0);*/
809 /*set32(&fsd->file_set_desc_number, 0);*/
810 set_charspec(&fsd->logical_volume_ident_character_set);
811 set_dstring(fsd->logical_volume_ident, volume_id,
812 sizeof (fsd->logical_volume_ident));
813 set_charspec(&fsd->file_set_character_set);
814 set_dstring(fsd->file_set_ident, volume_id,
815 sizeof (fsd->file_set_ident));
816 /*fsd->copyright_file_ident;*/
817 /*fsd->abstract_file_ident;*/
818 set32(&fsd->root_directory_icb.extent_length, SECTOR_SIZE);
819 set32(&fsd->root_directory_icb.extent_location.logical_block_number,
820 root->self->udf_file_entry_sector - lba_udf_partition_start);
821 set_domain_ident(&fsd->domain_ident);
822 /*fsd->next_extent;*/
823 set_tag(&fsd->desc_tag, UDF_TAGID_FILE_SET_DESC, rba, 512);
824 }
825
826 static int
827 #ifdef PROTOTYPES
828 set_file_ident_desc(unsigned char *buf, unsigned rba, char *name, int is_directory, unsigned file_entry_rba, unsigned unique_id)
829 #else
830 set_file_ident_desc(buf, rba, name, is_directory, file_entry_rba, unique_id)
831 unsigned char *buf;
832 unsigned rba;
833 char *name;
834 int is_directory;
835 unsigned file_entry_rba;
836 unsigned unique_id;
837 #endif
838 {
839 udf_file_ident_desc *fid = (udf_file_ident_desc *)buf;
840 int length_of_file_ident, length, padded_length;
841 set16(&fid->file_version_number, 1);
842 set8(&fid->file_characteristics,
843 (is_directory ? UDF_FILE_CHARACTERISTIC_DIRECTORY : 0)
844 + (name == 0) * UDF_FILE_CHARACTERISTIC_PARENT);
845 set32(&fid->icb.extent_length, SECTOR_SIZE);
846 set32(&fid->icb.extent_location.logical_block_number, file_entry_rba);
847 set16(&fid->icb.extent_location.partition_reference_number, 0);
848 set32(&fid->icb.impl_use.unique_id, unique_id);
849 set16(&fid->length_of_impl_use, 0);
850 if (name) {
851 length_of_file_ident =
852 set_ostaunicode((Uchar *)fid->file_ident, 512, name);
853 } else {
854 length_of_file_ident = 0;
855 }
856 set8(&fid->length_of_file_ident, length_of_file_ident);
857 length = 38 + length_of_file_ident;
858 padded_length = PAD(length, 4);
859 while (length < padded_length) {
860 buf[length++] = 0;
861 }
862 set_tag(&fid->desc_tag, UDF_TAGID_FILE_IDENT_DESC, rba, length);
863 return (length);
864 }
865
866 static void
867 #ifdef PROTOTYPES
868 set_file_entry(unsigned char *buf,
869 unsigned rba,
870 unsigned file_rba,
871 unsigned length,
872 const char *iso_date,
873 int is_directory,
874 unsigned link_count,
875 unsigned unique_id)
876 #else
877 set_file_entry(buf, rba, file_rba, length, iso_date, is_directory, link_count, unique_id)
878 unsigned char *buf;
879 unsigned rba;
880 unsigned file_rba;
881 unsigned length;
882 const char *iso_date;
883 int is_directory;
884 unsigned link_count;
885 unsigned unique_id;
886 #endif
887 {
888 udf_short_ad *allocation_desc;
889 unsigned chunk;
890
891 udf_file_entry *fe = (udf_file_entry *)buf;
892
893 /*set32(&fe->icb_tag.prior_recorded_number_of_direct_entries, 0);*/
894 set16(&fe->icb_tag.strategy_type, 4);
895 /*set16(&fe->icb_tag.strategy_parameter, 0);*/
896 set16(&fe->icb_tag.maximum_number_of_entries, 1);
897 set8(&fe->icb_tag.file_type, is_directory
898 ? UDF_ICBTAG_FILETYPE_DIRECTORY : UDF_ICBTAG_FILETYPE_BYTESEQ);
899 /*fe->icb_tag.parent_icb_location;*/
900 set16(&fe->icb_tag.flags, UDF_ICBTAG_FLAG_NONRELOCATABLE
901 | UDF_ICBTAG_FLAG_ARCHIVE | UDF_ICBTAG_FLAG_CONTIGUOUS);
902 if (rationalize_uid)
903 set32(&fe->uid, uid_to_use);
904 else
905 set32(&fe->uid, -1);
906 if (rationalize_gid)
907 set32(&fe->gid, gid_to_use);
908 else
909 set32(&fe->gid, -1);
910 if (is_directory) {
911 set32(&fe->permissions,
912 UDF_FILEENTRY_PERMISSION_OR | UDF_FILEENTRY_PERMISSION_OX |
913 UDF_FILEENTRY_PERMISSION_GR | UDF_FILEENTRY_PERMISSION_GX |
914 UDF_FILEENTRY_PERMISSION_UR | UDF_FILEENTRY_PERMISSION_UX);
915 } else {
916 set32(&fe->permissions, UDF_FILEENTRY_PERMISSION_OR
917 | UDF_FILEENTRY_PERMISSION_GR | UDF_FILEENTRY_PERMISSION_UR);
918 }
919 set16(&fe->file_link_count, link_count);
920 /*fe->record_format;*/
921 /*fe->record_display_attributes;*/
922 /*fe->record_length;*/
923 set64(&fe->info_length, length);
924 set64(&fe->logical_blocks_recorded, ISO_BLOCKS(length));
925 if (iso_date) {
926 set_timestamp_from_iso_date(&fe->access_time, iso_date);
927 fe->modification_time = fe->access_time;
928 fe->attribute_time = fe->access_time;
929 }
930 set32(&fe->checkpoint, 1);
931 /*fe->ext_attribute_icb;*/
932 set_impl_ident(&fe->impl_ident);
933 set64(&fe->unique_id, unique_id);
934 /*
935 * Extended attributes that may (?) be required for DVD-Video
936 * compliance
937 */
938 #if 0
939 set32(&fe->length_of_ext_attributes, 24+52+56);
940 set32(&fe->ext_attribute_header.impl_attributes_location, 24);
941 set32(&fe->ext_attribute_header.application_attributes_location,
942 24+52+56);
943 set_tag(&fe->ext_attribute_header.desc_tag,
944 UDF_TAGID_EXT_ATTRIBUTE_HEADER_DESC, rba, 24 /*???*/);
945 set32(&fe->ext_attribute_free_ea_space.attribute_type, SECTOR_SIZE);
946 set8(&fe->ext_attribute_free_ea_space.attribute_subtype, 1);
947 set32(&fe->ext_attribute_free_ea_space.attribute_length, 52);
948 set32(&fe->ext_attribute_free_ea_space.impl_use_length, 4);
949 strcpy((char *)fe->ext_attribute_free_ea_space.impl_ident.ident,
950 "*UDF FreeAppEASpace");
951 set32(&fe->ext_attribute_dvd_cgms_info.attribute_type, SECTOR_SIZE);
952 set8(&fe->ext_attribute_dvd_cgms_info.attribute_subtype, 1);
953 set32(&fe->ext_attribute_dvd_cgms_info.attribute_length, 56);
954 set32(&fe->ext_attribute_dvd_cgms_info.impl_use_length, 8);
955 strcpy((char *)fe->ext_attribute_free_ea_space.impl_ident.ident,
956 "*UDF DVD CGMS Info");
957 fe->ext_attribute_free_ea_space.impl_ident.ident_suffix[0] = 2;
958 fe->ext_attribute_free_ea_space.impl_ident.ident_suffix[1] = 1;
959 #else
960 /*set32(&fe->length_of_ext_attributes, 0);*/
961 #endif
962
963 allocation_desc = &fe->allocation_desc;
964 /*
965 * Only a file size less than 1GB can be expressed by a single
966 * AllocationDescriptor. When the size of a file is larger than 1GB,
967 * 2 or more AllocationDescriptors should be used. We don't know
968 * whether a singl 8-byte AllocationDescriptor should be written or no
969 * one should be written if the size of a file is 0 byte. - FIXME.
970 *
971 * XXX We get called with buf[2048]. This allows a max. file size of
972 * XXX 234 GB. With more we would cause a buffer overflow.
973 * XXX We need to check whether UDF would allow files > 234 GB.
974 */
975 for (; length > 0; length -= chunk) {
976 chunk = (length > 0x3ffff800) ? 0x3ffff800 : length;
977 set32(&allocation_desc->extent_length, chunk);
978 set32(&allocation_desc->extent_position, file_rba);
979 file_rba += chunk >> 11;
980 allocation_desc++;
981 }
982 set32(&fe->length_of_allocation_descs,
983 (unsigned char *) allocation_desc -
984 (unsigned char *) &fe->allocation_desc);
985 set_tag(&fe->desc_tag, UDF_TAGID_FILE_ENTRY, rba,
986 (unsigned char *) allocation_desc - buf);
987 }
988
989 static unsigned
990 #ifdef PROTOTYPES
991 directory_link_count(struct directory *dpnt)
992 #else
993 directory_link_count(dpnt)
994 struct directory *dpnt;
995 #endif
996 {
997 /*
998 * The link count is equal to 1 (for the parent) plus the
999 * number of subdirectories.
1000 */
1001 unsigned link_count = 1;
1002 struct directory_entry *de;
1003
1004 /* count relocated subdirectories */
1005 for (de = dpnt->jcontents; de; de = de->jnext) {
1006 if ((de->de_flags &
1007 (INHIBIT_JOLIET_ENTRY | RELOCATED_DIRECTORY)) ==
1008 RELOCATED_DIRECTORY) {
1009 link_count++;
1010 }
1011 }
1012 /* count ordinary subdirectories */
1013 for (dpnt = dpnt->subdir; dpnt; dpnt = dpnt->next) {
1014 if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY)) {
1015 link_count++;
1016 }
1017 }
1018 return (link_count);
1019 }
1020
1021 static void
1022 #ifdef PROTOTYPES
1023 write_one_udf_directory(struct directory *dpnt, FILE *outfile)
1024 #else
1025 write_one_udf_directory(dpnt, outfile)
1026 struct directory *dpnt;
1027 FILE *outfile;
1028 #endif
1029 {
1030 unsigned size_in_bytes, padded_size_in_bytes;
1031 struct directory_entry *de;
1032 unsigned ident_size;
1033 unsigned base_sector;
1034 struct directory *parent;
1035 Uchar buf[SECTOR_SIZE];
1036
1037 memset(buf, 0, SECTOR_SIZE);
1038 set_file_entry(
1039 buf,
1040 last_extent_written - lba_udf_partition_start,
1041 last_extent_written+1 - lba_udf_partition_start,
1042 directory_size(dpnt),
1043 dpnt->self->isorec.date,
1044 1, /* is_directory */
1045 directory_link_count(dpnt),
1046 (dpnt == root) ? 0 : dpnt->self->udf_file_entry_sector);
1047 xfwrite(buf, SECTOR_SIZE, 1, outfile, 0, FALSE);
1048 last_extent_written++;
1049
1050 base_sector = last_extent_written - lba_udf_partition_start;
1051
1052 /* parent directory */
1053 parent = dpnt->parent;
1054 if (parent == reloc_dir) {
1055 parent = dpnt->self->parent_rec->filedir;
1056 }
1057 ident_size = set_file_ident_desc(
1058 buf,
1059 base_sector,
1060 0,
1061 1,
1062 parent->self->udf_file_entry_sector - lba_udf_partition_start,
1063 (parent == root) ? 0 : parent->self->udf_file_entry_sector);
1064 xfwrite(buf, ident_size, 1, outfile, 0, FALSE);
1065 size_in_bytes = ident_size;
1066
1067 /* directory contents */
1068 for (de = dpnt->jcontents; de; de = de->jnext) {
1069 char *name;
1070 struct directory_entry *de1;
1071
1072 if (de->de_flags & INHIBIT_JOLIET_ENTRY)
1073 continue;
1074
1075 name = USE_MAC_NAME(de) ? de->hfs_ent->name : de->name;
1076
1077 /* skip . and .. */
1078 if (name[0] == '.' && (name[1] == 0 ||
1079 (name[1] == '.' && name[2] == 0)))
1080 continue;
1081
1082 /* look in RR_MOVED for relocated directories */
1083 de1 = de;
1084 if (de->de_flags & RELOCATED_DIRECTORY) {
1085 for (de1 = reloc_dir->contents; de1; de1 = de1->next) {
1086 if (de1->parent_rec == de) {
1087 break;
1088 }
1089 }
1090 if (!de1) {
1091 #ifdef USE_LIBSCHILY
1092 comerrno(EX_BAD,
1093 "Unable to locate relocated directory\n");
1094 #else
1095 fprintf(stderr,
1096 "Unable to locate relocated directory\n");
1097 exit(1);
1098 #endif
1099 }
1100 }
1101
1102 ident_size = set_file_ident_desc(
1103 buf,
1104 base_sector + (size_in_bytes / SECTOR_SIZE),
1105 name,
1106 !!(de1->isorec.flags[0] & ISO_DIRECTORY),
1107 de1->udf_file_entry_sector - lba_udf_partition_start,
1108 de1->udf_file_entry_sector);
1109 xfwrite(buf, ident_size, 1, outfile, 0, FALSE);
1110 size_in_bytes += ident_size;
1111 }
1112
1113 padded_size_in_bytes = PAD(size_in_bytes, SECTOR_SIZE);
1114 if (size_in_bytes < padded_size_in_bytes) {
1115 memset(buf, 0, padded_size_in_bytes - size_in_bytes);
1116 xfwrite(buf, padded_size_in_bytes - size_in_bytes, 1, outfile, 0, FALSE);
1117 }
1118
1119 last_extent_written += padded_size_in_bytes / SECTOR_SIZE;
1120 }
1121
1122 static void
1123 #ifdef PROTOTYPES
1124 write_udf_directories(struct directory *dpnt, FILE *outfile)
1125 #else
1126 write_udf_directories(dpnt, outfile)
1127 struct directory *dpnt;
1128 FILE *outfile;
1129 #endif
1130 {
1131 if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY)) {
1132 write_one_udf_directory(dpnt, outfile);
1133 }
1134 if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir) {
1135 for (dpnt = dpnt->subdir; dpnt; dpnt = dpnt->next) {
1136 write_udf_directories(dpnt, outfile);
1137 }
1138 }
1139 }
1140
1141 static void
1142 #ifdef PROTOTYPES
1143 write_udf_file_entries(struct directory *dpnt, FILE *outfile)
1144 #else
1145 write_udf_file_entries(dpnt, outfile)
1146 struct directory *dpnt;
1147 FILE *outfile;
1148 #endif
1149 {
1150 Uchar buf[SECTOR_SIZE];
1151
1152 memset(buf, 0, SECTOR_SIZE);
1153
1154 if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY)) {
1155 struct directory_entry *de;
1156 for (de = dpnt->jcontents; de; de = de->jnext) {
1157 if (!(de->de_flags & RELOCATED_DIRECTORY) &&
1158 !(de->isorec.flags[0] & ISO_DIRECTORY)) {
1159
1160 memset(buf, 0, 512);
1161 set_file_entry(
1162 buf,
1163 (last_extent_written++) - lba_udf_partition_start,
1164 read_733(de->isorec.extent) - lba_udf_partition_start,
1165 read_733(de->isorec.size),
1166 de->isorec.date,
1167 0, /* is_directory */
1168 1, /* link_count */
1169 de->udf_file_entry_sector);
1170 xfwrite(buf, SECTOR_SIZE, 1, outfile, 0, FALSE);
1171 }
1172 }
1173 }
1174 if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir) {
1175 for (dpnt = dpnt->subdir; dpnt; dpnt = dpnt->next) {
1176 write_udf_file_entries(dpnt, outfile);
1177 }
1178 }
1179 }
1180
1181 /****************************/
1182
1183 static int
1184 #ifdef PROTOTYPES
1185 udf_vol_recognition_area_write(FILE *out)
1186 #else
1187 udf_vol_recognition_area_write(out)
1188 FILE *out;
1189 #endif
1190 {
1191 static const char *identifiers[3] = { "BEA01", "NSR02", "TEA01" };
1192 int i;
1193 char buf[SECTOR_SIZE];
1194 udf_volume_recognition_desc *vsd = (udf_volume_recognition_desc *)buf;
1195
1196 memset(buf, 0, sizeof (buf));
1197 /*set8(&vsd->structure_type, 0);*/
1198 set8(&vsd->structure_version, 1);
1199 for (i = 0; i < 3; ++i) {
1200 memcpy(vsd->standard_identifier, identifiers[i], 5);
1201 xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
1202 }
1203 last_extent_written += 3;
1204 return (0);
1205 }
1206
1207 static int
1208 #ifdef PROTOTYPES
1209 udf_main_seq_write(FILE *out)
1210 #else
1211 udf_main_seq_write(out)
1212 FILE *out;
1213 #endif
1214 {
1215 Uchar buf[SECTOR_SIZE];
1216 int i;
1217
1218 /*
1219 * volume_set_id needs to be set to a (64-bit) "unique" number.
1220 * This will have to do for now.
1221 */
1222 volume_set_id[0] = begun;
1223 volume_set_id[1] = (unsigned)clock(); /* XXX Maybe non-portable */
1224
1225 memset(buf, 0, sizeof (buf));
1226 set_primary_vol_desc(buf, last_extent_written++);
1227 xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
1228
1229 memset(buf, 0, sizeof (buf));
1230 set_impl_use_vol_desc(buf, last_extent_written++);
1231 xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
1232
1233 memset(buf, 0, sizeof (buf));
1234 set_partition_desc(buf, last_extent_written++);
1235 xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
1236
1237 memset(buf, 0, sizeof (buf));
1238 set_logical_vol_desc(buf, last_extent_written++);
1239 xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
1240
1241 memset(buf, 0, sizeof (buf));
1242 set_unallocated_space_desc(buf, last_extent_written++);
1243 xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
1244
1245 memset(buf, 0, sizeof (buf));
1246 set_terminating_desc(buf, last_extent_written++);
1247 xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
1248
1249 memset(buf, 0, sizeof (buf));
1250 for (i = 6; i < UDF_MAIN_SEQ_LENGTH; ++i) {
1251 xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
1252 last_extent_written++;
1253 }
1254
1255 return (0);
1256 }
1257
1258 static int
1259 #ifdef PROTOTYPES
1260 udf_integ_seq_write(FILE *out)
1261 #else
1262 udf_integ_seq_write(out)
1263 FILE *out;
1264 #endif
1265 {
1266 Uchar buf[SECTOR_SIZE*UDF_INTEG_SEQ_LENGTH];
1267
1268 memset(buf, 0, sizeof (buf));
1269
1270 set_logical_vol_integrity_desc(buf+0*SECTOR_SIZE,
1271 last_extent_written++);
1272 set_terminating_desc(buf+1*SECTOR_SIZE, last_extent_written++);
1273
1274 xfwrite(buf, SECTOR_SIZE, UDF_INTEG_SEQ_LENGTH, out, 0, FALSE);
1275 return (0);
1276 }
1277
1278 static int
1279 #ifdef PROTOTYPES
1280 udf_anchor_vol_desc_write(FILE *out)
1281 #else
1282 udf_anchor_vol_desc_write(out)
1283 FILE *out;
1284 #endif
1285 {
1286 Uchar buf[SECTOR_SIZE];
1287
1288 memset(buf, 0, sizeof (buf));
1289 set_anchor_volume_desc_pointer(buf, last_extent_written++);
1290 xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
1291 return (0);
1292 }
1293
1294 static int
1295 #ifdef PROTOTYPES
1296 udf_file_set_desc_write(FILE *out)
1297 #else
1298 udf_file_set_desc_write(out)
1299 FILE *out;
1300 #endif
1301 {
1302 Uchar buf[SECTOR_SIZE*2];
1303
1304 memset(buf, 0, sizeof (buf));
1305
1306 set_file_set_desc(buf+0*SECTOR_SIZE,
1307 (last_extent_written++) - lba_udf_partition_start);
1308 set_terminating_desc(buf+1*SECTOR_SIZE,
1309 (last_extent_written++) - lba_udf_partition_start);
1310
1311 xfwrite(buf, SECTOR_SIZE, 2, out, 0, FALSE);
1312
1313 return (0);
1314 }
1315
1316 static int
1317 #ifdef PROTOTYPES
1318 udf_dirtree_write(FILE *out)
1319 #else
1320 udf_dirtree_write(out)
1321 FILE *out;
1322 #endif
1323 {
1324 write_udf_directories(root, out);
1325 return (0);
1326 }
1327
1328 static int
1329 #ifdef PROTOTYPES
1330 udf_file_entries_write(FILE *out)
1331 #else
1332 udf_file_entries_write(out)
1333 FILE *out;
1334 #endif
1335 {
1336 write_udf_file_entries(root, out);
1337 return (0);
1338 }
1339
1340 static int
1341 #ifdef PROTOTYPES
1342 pad_to(unsigned last_extent_to_write, FILE *out)
1343 #else
1344 pad_to(last_extent_to_write, out)
1345 unsigned last_extent_to_write;
1346 FILE *out;
1347 #endif
1348 {
1349 char buf[SECTOR_SIZE];
1350 memset(buf, 0, sizeof (buf));
1351 while (last_extent_written < last_extent_to_write) {
1352 xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
1353 ++last_extent_written;
1354 }
1355 return (0);
1356 }
1357
1358 static int
1359 #ifdef PROTOTYPES
1360 udf_pad_to_sector_32_write(FILE *out)
1361 #else
1362 udf_pad_to_sector_32_write(out)
1363 FILE *out;
1364 #endif
1365 {
1366 return (pad_to(session_start+32, out));
1367 }
1368
1369 static int
1370 #ifdef PROTOTYPES
1371 udf_pad_to_sector_256_write(FILE *out)
1372 #else
1373 udf_pad_to_sector_256_write(out)
1374 FILE *out;
1375 #endif
1376 {
1377 return (pad_to(session_start+256, out));
1378 }
1379
1380 static int
1381 #ifdef PROTOTYPES
1382 udf_padend_avdp_write(FILE *out)
1383 #else
1384 udf_padend_avdp_write(out)
1385 FILE *out;
1386 #endif
1387 {
1388 Uchar buf[SECTOR_SIZE];
1389 unsigned last_extent_to_write = (last_extent_written+31) & ~15;
1390
1391 if (!use_sparcboot)
1392 last_extent_to_write = last_extent_written + 150;
1393
1394 memset(buf, 0, sizeof (buf));
1395 while (last_extent_written < last_extent_to_write) {
1396 set_anchor_volume_desc_pointer(buf, last_extent_written++);
1397 xfwrite(buf, SECTOR_SIZE, 1, out, 0, FALSE);
1398 }
1399 return (0);
1400 }
1401
1402
1403 struct output_fragment udf_vol_recognition_area_frag = { NULL, udf_vol_recognition_area_size, NULL, udf_vol_recognition_area_write, "UDF volume recognition area" };
1404 struct output_fragment udf_main_seq_frag = { NULL, udf_main_seq_size, NULL, udf_main_seq_write, "UDF main seq" };
1405 struct output_fragment udf_main_seq_copy_frag = { NULL, udf_main_seq_copy_size, NULL, udf_main_seq_write, "UDF second seq" };
1406 struct output_fragment udf_integ_seq_frag = { NULL, udf_integ_seq_size, NULL, udf_integ_seq_write, "UDF integ seq" };
1407 struct output_fragment udf_anchor_vol_desc_frag = { NULL, oneblock_size, NULL, udf_anchor_vol_desc_write, "UDF Anchor volume" };
1408 struct output_fragment udf_file_set_desc_frag = { NULL, udf_file_set_desc_size, NULL, udf_file_set_desc_write, "UDF file set" };
1409 struct output_fragment udf_dirtree_frag = { NULL, udf_dirtree_size, NULL, udf_dirtree_write, "UDF directory tree" };
1410 struct output_fragment udf_file_entries_frag = { NULL, udf_file_entries_size, NULL, udf_file_entries_write, "UDF file entries" };
1411 struct output_fragment udf_end_anchor_vol_desc_frag = { NULL, udf_end_anchor_vol_desc_size, NULL, udf_anchor_vol_desc_write, "UDF Anchor end volume" };
1412
1413 struct output_fragment udf_pad_to_sector_32_frag = { NULL, udf_pad_to_sector_32_size, NULL, udf_pad_to_sector_32_write, "UDF pad to sector 32" };
1414 struct output_fragment udf_pad_to_sector_256_frag = { NULL, udf_pad_to_sector_256_size, NULL, udf_pad_to_sector_256_write, "UDF pad to sector 256" };
1415 struct output_fragment udf_padend_avdp_frag = { NULL, udf_padend_avdp_size, NULL, udf_padend_avdp_write, "UDF Pad end" };
1416
1417 /*
1418 * This function assigns weights as follows:
1419 *
1420 * /VIDEO_TS/VIDEO_TS.IFO 11199
1421 * /VIDEO_TS/VIDEO_TS.VOB 11198
1422 * /VIDEO_TS/VIDEO_TS.BUP 11188
1423 * /VIDEO_TS/VTS_01_0.IFO 11187
1424 * /VIDEO_TS/VTS_01_0.VOB 11186
1425 * : :
1426 * /VIDEO_TS/VTS_01_9.VOB 11177
1427 * /VIDEO_TS/VTS_01_0.BUP 11176
1428 * : :
1429 * /VIDEO_TS/VTS_99_0.BUP 10000
1430 *
1431 * This ensures that DVD-Video files are laid out properly on the disc.
1432 * The same thing is done for AUDIO_TS files, except in the 20000 range
1433 * instead of the 10000 range.
1434 *
1435 * Question: what about JACKET_P files?
1436 *
1437 * Answer: At least as far as I know :)
1438 * JACKET_P files are still images (single frame mpeg video .i.e mp2
1439 * format). The DVD Jacket pictures will be displayed on the TV screen
1440 * when the player is in a stop/resume mode.
1441 * The location is not dependent on IFO information and the only must
1442 * as far as I know is that they are in upper case (both dir and files).
1443 * This sparce information makes me conclude that they don't need any
1444 * weight. This obviously needs to be tested.
1445 */
1446 int
1447 #ifdef PROTOTYPES
1448 assign_dvd_weights(char *name, struct directory *this_dir, int val)
1449 #else
1450 assign_dvd_weights(name, this_dir, val)
1451 char *name;
1452 struct directory *this_dir;
1453 int val;
1454 #endif
1455 {
1456 int ts_number;
1457 int segment;
1458 int audio;
1459
1460 if (name[0] != 'A' && name[0] != 'V')
1461 return (val);
1462
1463 if (memcmp(name, "VIDEO_TS", 8) == 0) {
1464 ts_number = 0;
1465 audio = 0;
1466 } else if (memcmp(name, "VTS_", 4) == 0) {
1467 ts_number = 1;
1468 audio = 0;
1469 } else if (memcmp(name, "AUDIO_TS", 8) == 0) {
1470 ts_number = 0;
1471 audio = 1;
1472 } else if (memcmp(name, "ATS_", 4) == 0) {
1473 ts_number = 1;
1474 audio = 1;
1475 } else {
1476 return (val);
1477 }
1478
1479 if (this_dir->parent != root ||
1480 strcmp(this_dir->de_name, "VIDEO_TS") != 0)
1481 return (val);
1482
1483 if (ts_number == 0) {
1484 segment = 0;
1485 } else {
1486 if (name[4] >= '0' && name[4] <= '9' &&
1487 name[5] >= '0' && name[5] <= '9' &&
1488 name[6] == '_' &&
1489 name[7] >= '0' && name[7] <= '9') {
1490 ts_number = name[4] * 10 + name[5] - ('0' * 11);
1491 segment = name[7] - '0';
1492 } else {
1493 return (val);
1494 }
1495 }
1496
1497 if (strcmp(name+8, audio ? ".AOB" : ".VOB") == 0) {
1498 return (audio * 10000 - ts_number * 12 - segment + 11198);
1499 } else if (strcmp(name+8, ".IFO") == 0) {
1500 return (audio * 10000 - ts_number * 12 + 11199);
1501 } else if (strcmp(name+8, ".BUP") == 0) {
1502 return (audio * 10000 - ts_number * 12 + 11188);
1503 } else {
1504 return (val);
1505 }
1506 }
1507
1508 #endif /* UDF */

  ViewVC Help
Powered by ViewVC 1.1.5