📄 udf.c
字号:
/* @(#)udf.c 1.6 02/11/24 Copyright 2001 J. Schilling */#ifndef lintstatic char sccsid[] = "@(#)udf.c 1.6 02/11/24 Copyright 2001 J. Schilling";#endif/* * udf.c - UDF support for mkisofs * * Written by Ben Rudiak-Gould (2001). * * Copyright 2001 J. Schilling. *//*@@C@@*//* * Some remaining issues: * * - UDF supports UNIX-style file permissions and uid/gid, but currently * this code just sets them to default values and ignores their Rock * Ridge counterparts. This would be easy to fix. * * - There's no support for symlinks, Mac type/creator, or Mac resource * forks. Hard links and followed symlinks may work, but if so, it's * only by accident. * * - The file system mirrors the Joliet file system, so files excluded * from Joliet will also be excluded from UDF, the -jcharset option * also applies to UDF, file names too long for Joliet will also be * truncated on UDF, and characters not allowed by Joliet will also * be translated on UDF. (Fortunately, Joliet is pretty lenient.) * * - convert_to_unicode is always called with in_nls, not hfs_nls. This * may lead to incorrect name conversion sometimes when using a Mac * filesystem. See joliet.c for an example of what's supposed to be * done. * * - DVD-Video discs are supposed to have Copyright Management Information * in both the ISO and UDF filesystems. This is not implemented in ISO, * and the code to do it in UDF is currently #ifdef'd out. I'm not sure * whether discs without this information are actually DVD-Video * compliant. The Copyright Management Information is described in ECMA * Technical Report TR/71. * * - Most of the space before sector 256 on the disc (~480K) is wasted, * because UDF Bridge requires a pointer block at sector 256. ISO 9660 * structures could be moved below sector 256 if they're small enough, but * this would be ugly to implement since it breaks the output_fragment * abstraction. * * - Each file must have a File Entry, and each File Entry seems to * require its own 2K sector. As a result, there is an overhead of more * than 2K *per file* when using UDF. I couldn't see any way to avoid * this. * * - Read performance would probably be improved by placing the File Entry * for each file just before the file itself, instead of at the beginning * of the disc. But this would not work for DVD-Video files, which have * to be stored contiguously. So there would have to be an override * mechanism to handle this case. I don't know if it's worth the trouble. */#ifdef UDF#include "config.h"#include "mkisofs.h"#include <timedefs.h>#include <schily.h>#include "udf.h"#include "udf_fs.h"extern struct directory *root;static unsigned lba_main_seq;static unsigned lba_main_seq_copy;static unsigned lba_integ_seq;static unsigned lba_udf_partition_start;static unsigned lba_last_file_entry;static unsigned lba_end_anchor_vol_desc;static unsigned num_udf_files;static unsigned num_udf_directories;static unsigned volume_set_id[2];#define UDF_MAIN_SEQ_LENGTH (16)#define UDF_INTEG_SEQ_LENGTH (2)/* only works for granularity a power of 2! */#define PAD(val,granularity) (((val)+(granularity)-1)&~((granularity)-1))#define read_733(field) ((0[field]&255)+(1[field]&255)*256+(2[field]&255)*65536+(3[field]&255)*16777216)/**************** SIZE ****************/static int set_file_ident_desc __PR((unsigned char *, unsigned, char *, int, unsigned, unsigned));static unsigned#ifdef PROTOTYPESdirectory_size(struct directory *dpnt)#elsedirectory_size(dpnt) struct directory *dpnt;#endif{ unsigned size_in_bytes; struct directory_entry *de; Uchar dummy_buf[SECTOR_SIZE]; /* parent directory */ size_in_bytes = set_file_ident_desc(dummy_buf, 0, 0, 0, 0, 0); /* directory contents */ for (de = dpnt->jcontents; de; de = de->jnext) { if (!(de->de_flags & INHIBIT_JOLIET_ENTRY)) { char *name = USE_MAC_NAME(de) ? de->hfs_ent->name : de->name; /* skip . and .. */ if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) continue; size_in_bytes += set_file_ident_desc(dummy_buf, 0, name, 0, 0, 0); } } return size_in_bytes;}static void#ifdef PROTOTYPESassign_udf_directory_addresses(struct directory *dpnt)#elseassign_udf_directory_addresses(dpnt) struct directory *dpnt;#endif{ if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY)) { dpnt->self->udf_file_entry_sector = last_extent; last_extent += 1 + ISO_BLOCKS(directory_size(dpnt)); ++num_udf_directories; } if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir) { for (dpnt = dpnt->subdir; dpnt; dpnt = dpnt->next) { assign_udf_directory_addresses(dpnt); } }}static void#ifdef PROTOTYPESassign_udf_file_entry_addresses(struct directory *dpnt)#elseassign_udf_file_entry_addresses(dpnt) struct directory *dpnt;#endif{ if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY)) { struct directory_entry *de; for (de = dpnt->jcontents; de; de = de->jnext) { if (!(de->de_flags & RELOCATED_DIRECTORY) && !(de->isorec.flags[0] & ISO_DIRECTORY)) { de->udf_file_entry_sector = last_extent++; ++num_udf_files; } } } if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir) { for (dpnt = dpnt->subdir; dpnt; dpnt = dpnt->next) { assign_udf_file_entry_addresses(dpnt); } }}/****************************/static int#ifdef PROTOTYPESudf_vol_recognition_area_size(int starting_extent)#elseudf_vol_recognition_area_size(starting_extent) int starting_extent;#endif{ last_extent = starting_extent+3; return 0;}static int#ifdef PROTOTYPESudf_main_seq_size(int starting_extent)#elseudf_main_seq_size(starting_extent) int starting_extent;#endif{ lba_main_seq = starting_extent; last_extent = starting_extent + UDF_MAIN_SEQ_LENGTH; return 0;}static int#ifdef PROTOTYPESudf_main_seq_copy_size(int starting_extent)#elseudf_main_seq_copy_size(starting_extent) int starting_extent;#endif{ lba_main_seq_copy = starting_extent; last_extent = starting_extent + UDF_MAIN_SEQ_LENGTH; return 0;}static int#ifdef PROTOTYPESudf_integ_seq_size(int starting_extent)#elseudf_integ_seq_size(starting_extent) int starting_extent;#endif{ lba_integ_seq = starting_extent; last_extent = starting_extent + UDF_INTEG_SEQ_LENGTH; return 0;}static int#ifdef PROTOTYPESudf_end_anchor_vol_desc_size(int starting_extent)#elseudf_end_anchor_vol_desc_size(starting_extent) int starting_extent;#endif{ lba_end_anchor_vol_desc = starting_extent; last_extent = starting_extent+1; return 0;}static int#ifdef PROTOTYPESudf_file_set_desc_size(int starting_extent)#elseudf_file_set_desc_size(starting_extent) int starting_extent;#endif{ lba_udf_partition_start = starting_extent; last_extent = starting_extent+2; return 0;}static int#ifdef PROTOTYPESudf_dirtree_size(int starting_extent)#elseudf_dirtree_size(starting_extent) int starting_extent;#endif{ num_udf_directories = 0; assign_udf_directory_addresses(root); return 0;}static int#ifdef PROTOTYPESudf_file_entries_size(int starting_extent)#elseudf_file_entries_size(starting_extent) int starting_extent;#endif{ num_udf_files = 0; assign_udf_file_entry_addresses(root); lba_last_file_entry = last_extent-1; return 0;}static int#ifdef PROTOTYPESudf_pad_to_sector_32_size(int starting_extent)#elseudf_pad_to_sector_32_size(starting_extent) int starting_extent;#endif{ if (last_extent < session_start+32) last_extent = session_start+32; return 0;}static int#ifdef PROTOTYPESudf_pad_to_sector_256_size(int starting_extent)#elseudf_pad_to_sector_256_size(starting_extent) int starting_extent;#endif{ if (last_extent < session_start+256) last_extent = session_start+256; return 0;}static int#ifdef PROTOTYPESudf_padend_avdp_size(int starting_extent)#elseudf_padend_avdp_size(starting_extent) int starting_extent;#endif{ lba_end_anchor_vol_desc = starting_extent; /* add at least 16 and at most 31 sectors, ending at a mult. of 16 */ last_extent = (starting_extent+31) & ~15; return 0;}extern int oneblock_size __PR((int));/**************** WRITE ****************/static unsigned#ifdef PROTOTYPEScrc_ccitt(unsigned char *buf, unsigned len)#elsecrc_ccitt(buf,len) unsigned char *buf; unsigned len;#endif{ const unsigned poly = 0x11021; static unsigned short lookup[256]; unsigned int r; unsigned int i; if (lookup[1] == 0) { unsigned int j,k; for (j = 0; j < 256; ++j) { unsigned int temp = j << 8; for (k = 0; k < 8; ++k) { unsigned int hibit = temp & 32768; temp <<= 1; if (hibit) temp ^= poly; } lookup[j] = temp; } } r = 0; for (i = 0; i < len; ++i) { r = (r << 8) ^ lookup[((r >> 8) ^ buf[i]) & 255]; } return r & 65535;}#define set8(dst,src) do{*(dst)=(src);}while(0)static void#ifdef PROTOTYPESset16(udf_Uint16 *dst, unsigned int src)#elseset16(dst,src) udf_Uint16 *dst; unsigned int src;#endif{ dst->l = (char)(src); dst->h = (char)(src>>8);}static void#ifdef PROTOTYPESset32(udf_Uint32 *dst, unsigned src)#elseset32(dst,src) udf_Uint32 *dst; unsigned src;#endif{ dst->l = (char)(src); dst->ml = (char)(src>>8); dst->mh = (char)(src>>16); dst->h = (char)(src>>24);}static void#ifdef PROTOTYPESset64(udf_Uint64 *dst, unsigned src)#elseset64(dst,src) udf_Uint64 *dst; unsigned src;#endif{ set32(&dst->l, src); /* * src>>32 actually does the wrong thing on x86 with at least * one compiler, because of x86's shift count masking. Since * we never pass more than 32 sig. bits to the function anyway, * and all the structures we fill in are zeroed beforehand, * just skip setting the high word. */ /*set32(&dst->h, src>>32);*/}static int#ifdef PROTOTYPESset_ostaunicode(unsigned char *dst, int dst_size, char *src)#elseset_ostaunicode(dst,dst_size,src) unsigned char *dst; int dst_size; char *src;#endif{ unsigned char buf[1024]; int i; int expanded_length; expanded_length = joliet_strlen(src, gbk4win_filenames); if (expanded_length > 1024) expanded_length = 1024; if (expanded_length > (dst_size-1)*2) expanded_length = (dst_size-1)*2; convert_to_unicode(buf, expanded_length, src, in_nls, gbk4win_filenames); dst[0] = 8; /* use 8-bit representation by default */ for (i = 0; i < (expanded_length>>1); ++i) { dst[i + 1] = buf[i*2+1]; if (buf[i*2] != 0) { /* * There's a Unicode character with value >=256. * Use 16-bit representation instead. */ int length_to_copy = (dst_size-1) & ~1; if (length_to_copy > expanded_length) length_to_copy = expanded_length; dst[0] = 16; memcpy(dst+1, buf, length_to_copy); return length_to_copy+1; } } return (expanded_length>>1) + 1;}static void#ifdef PROTOTYPESset_extent(udf_extent_ad *ext, unsigned lba, unsigned length_bytes)#elseset_extent(ext,lba,length_bytes) udf_extent_ad *ext; unsigned lba; unsigned length_bytes;#endif{ set32(&ext->extent_length, length_bytes); set32(&ext->extent_location, lba);}static void#ifdef PROTOTYPESset_dstring(udf_dstring *dst, char *src, int n)#elseset_dstring(dst,src,n) udf_dstring *dst; char *src; int n;#endif{ dst[n-1] = set_ostaunicode((Uchar *)dst, n-1, src);}static void#ifdef PROTOTYPESset_charspec(udf_charspec *dst)#elseset_charspec(dst) udf_charspec *dst;#endif{ /*set8(&dst->character_set_type, 0);*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -