📄 joliet.c
字号:
free(directory_buffer);}/* generate_one_joliet_directory(... */static intjoliet_sort_n_finish(this_dir) struct directory *this_dir;{ struct directory_entry *s_entry; int status = 0; /* * don't want to skip this directory if it's the reloc_dir * at the moment */ if (this_dir != reloc_dir && this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) { return 0; } for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { /* skip hidden entries */ if ((s_entry->de_flags & INHIBIT_JOLIET_ENTRY) != 0) { continue; } /* * First update the path table sizes for directories. * * Finally, set the length of the directory entry if Joliet is * used. The name is longer, but no Rock Ridge is ever used * here, so depending upon the options the entry size might * turn out to be about the same. The Unicode name is always * a multiple of 2 bytes, so we always add 1 to make it an * even number. */ if (s_entry->isorec.flags[0] & ISO_DIRECTORY) { if (strcmp(s_entry->name, ".") != 0 && strcmp(s_entry->name, "..") != 0) {#ifdef APPLE_HYB if (USE_MAC_NAME(s_entry)) /* Use the HFS name if it exists */ jpath_table_size += joliet_strlen(s_entry->hfs_ent->name, gbk4win_filenames) + offsetof(struct iso_path_table, name[0]); else#endif /* APPLE_HYB */ jpath_table_size += joliet_strlen(s_entry->name, gbk4win_filenames) + offsetof(struct iso_path_table, name[0]); if (jpath_table_size & 1) { jpath_table_size++; } } else { if (this_dir == root && strlen(s_entry->name) == 1) { jpath_table_size += 1 + offsetof(struct iso_path_table, name[0]); if (jpath_table_size & 1) jpath_table_size++; } } } if (strcmp(s_entry->name, ".") != 0 && strcmp(s_entry->name, "..") != 0) {#ifdef APPLE_HYB if (USE_MAC_NAME(s_entry)) /* Use the HFS name if it exists */ s_entry->jreclen = offsetof(struct iso_directory_record, name[0]) + joliet_strlen(s_entry->hfs_ent->name, gbk4win_filenames) + 1; else#endif /* APPLE_HYB */ s_entry->jreclen = offsetof(struct iso_directory_record, name[0]) + joliet_strlen(s_entry->name, gbk4win_filenames) + 1; } else { /* * Special - for '.' and '..' we generate the same * records we did for non-Joliet discs. */ s_entry->jreclen = offsetof(struct iso_directory_record, name[0]) + 1; } } if ((this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) != 0) { return 0; } this_dir->jcontents = this_dir->contents; status = joliet_sort_directory(&this_dir->jcontents); /* * Now go through the directory and figure out how large this one will * be. Do not split a directory entry across a sector boundary */ s_entry = this_dir->jcontents; /* * XXX Is it ok to comment this out? *//*XXX JS this_dir->ce_bytes = 0;*/ for (s_entry = this_dir->jcontents; s_entry; s_entry = s_entry->jnext) { int jreclen; if ((s_entry->de_flags & INHIBIT_JOLIET_ENTRY) != 0) { continue; } jreclen = s_entry->jreclen; if ((this_dir->jsize & (SECTOR_SIZE - 1)) + jreclen >= SECTOR_SIZE) { this_dir->jsize = ISO_ROUND_UP(this_dir->jsize); } this_dir->jsize += jreclen; } return status;}/* * Similar to the iso9660 case, * except here we perform a full sort based upon the * regular name of the file, not the 8.3 version. */static intjoliet_compare_dirs(rr, ll) const void *rr; const void *ll;{ char *rpnt, *lpnt; struct directory_entry **r, **l; unsigned char rtmp[2], ltmp[2]; struct nls_table *linls, *rinls; r = (struct directory_entry **) rr; l = (struct directory_entry **) ll;#ifdef APPLE_HYB /* * we may be using the HFS name - so select the correct input * charset */ if (USE_MAC_NAME(*r)) { rpnt = (*r)->hfs_ent->name; rinls = hfs_inls; } else { rpnt = (*r)->name; rinls = in_nls; } if (USE_MAC_NAME(*l)) { lpnt = (*l)->hfs_ent->name; linls = hfs_inls; } else { lpnt = (*l)->name; linls = in_nls; }#else rpnt = (*r)->name; lpnt = (*l)->name; rinls = linls = in_nls;#endif /* APPLE_HYB */ /* * If the entries are the same, this is an error. * Joliet specs allow for a maximum of 64 characters. */ if (strncmp(rpnt, lpnt, jlen) == 0) {#ifdef USE_LIBSCHILY errmsgno(EX_BAD, "Error: %s and %s have the same Joliet name\n", (*r)->whole_name, (*l)->whole_name);#else fprintf(stderr, "Error: %s and %s have the same Joliet name\n", (*r)->whole_name, (*l)->whole_name);#endif sort_goof++; } /* * Put the '.' and '..' entries on the head of the sorted list. * For normal ASCII, this always happens to be the case, but out of * band characters cause this not to be the case sometimes. */ if (strcmp(rpnt, ".") == 0) return -1; if (strcmp(lpnt, ".") == 0) return 1; if (strcmp(rpnt, "..") == 0) return -1; if (strcmp(lpnt, "..") == 0) return 1;#ifdef DVD_VIDEO /* * There're rumors claiming that some players assume VIDEO_TS.IFO * to be the first file in VIDEO_TS/ catalog. Well, it's basically * the only file a player has to actually look for, as the whole * video content can be "rolled down" from this file alone. * <appro@fy.chalmers.se> */ /* * XXX This code has to be moved from the Joliet implementation * XXX to the UDF implementation if we implement decent UDF support * XXX with a separate name space for the UDF file tree. */ if (dvd_video) { if (strcmp(rpnt, "VIDEO_TS.IFO") == 0) return (-1); if (strcmp(lpnt, "VIDEO_TS.IFO") == 0) return (1); }#endif while (*rpnt && *lpnt) { if (*rpnt == ';' && *lpnt != ';') return -1; if (*rpnt != ';' && *lpnt == ';') return 1; if (*rpnt == ';' && *lpnt == ';') return 0; /* * Extensions are not special here. * Don't treat the dot as something that must be bumped to * the start of the list. */#if 0 if (*rpnt == '.' && *lpnt != '.') return -1; if (*rpnt != '.' && *lpnt == '.') return 1;#endif convert_to_unicode(rtmp, 2, rpnt, rinls, gbk4win_filenames); convert_to_unicode(ltmp, 2, lpnt, linls, gbk4win_filenames); if (a_to_u_2_byte(rtmp) < a_to_u_2_byte(ltmp)) return -1; if (a_to_u_2_byte(rtmp) > a_to_u_2_byte(ltmp)) return 1; rpnt++; lpnt++; } if (*rpnt) return 1; if (*lpnt) return -1; return 0;}/* * Function: sort_directory * * Purpose: Sort the directory in the appropriate ISO9660 * order. * * Notes: Returns 0 if OK, returns > 0 if an error occurred. */static intjoliet_sort_directory(sort_dir) struct directory_entry **sort_dir;{ int dcount = 0; int i; struct directory_entry *s_entry; struct directory_entry **sortlist; s_entry = *sort_dir; while (s_entry) { /* skip hidden entries */ if (!(s_entry->de_flags & INHIBIT_JOLIET_ENTRY)) dcount++; s_entry = s_entry->next; } /* OK, now we know how many there are. Build a vector for sorting. */ sortlist = (struct directory_entry **) e_malloc(sizeof(struct directory_entry *) * dcount); dcount = 0; s_entry = *sort_dir; while (s_entry) { /* skip hidden entries */ if (!(s_entry->de_flags & INHIBIT_JOLIET_ENTRY)) { sortlist[dcount] = s_entry; dcount++; } s_entry = s_entry->next; } sort_goof = 0;#ifdef __STDC__ qsort(sortlist, dcount, sizeof(struct directory_entry *), (int (*) (const void *, const void *)) joliet_compare_dirs);#else qsort(sortlist, dcount, sizeof(struct directory_entry *), joliet_compare_dirs);#endif /* Now reassemble the linked list in the proper sorted order */ for (i = 0; i < dcount - 1; i++) { sortlist[i]->jnext = sortlist[i + 1]; } sortlist[dcount - 1]->jnext = NULL; *sort_dir = sortlist[0]; free(sortlist); return sort_goof;}intjoliet_sort_tree(node) struct directory *node;{ struct directory *dpnt; int ret = 0; dpnt = node; while (dpnt) { ret = joliet_sort_n_finish(dpnt); if (ret) { break; } if (dpnt->subdir) ret = joliet_sort_tree(dpnt->subdir); if (ret) { break; } dpnt = dpnt->next; } return ret;}static voidgenerate_joliet_directories(node, outfile) struct directory *node; FILE *outfile;{ struct directory *dpnt; dpnt = node; while (dpnt) { if ((dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0) { /* * In theory we should never reuse a directory, so this * doesn't make much sense. */ if (dpnt->jextent > session_start) { generate_one_joliet_directory(dpnt, outfile); } } /* skip if hidden - but not for the rr_moved dir */ if (dpnt->subdir && (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir)) { generate_joliet_directories(dpnt->subdir, outfile); } dpnt = dpnt->next; }}/* * Function to write the EVD for the disc. */static intjpathtab_write(outfile) FILE *outfile;{ /* Next we write the path tables */ xfwrite(jpath_table_l, 1, jpath_blocks << 11, outfile); xfwrite(jpath_table_m, 1, jpath_blocks << 11, outfile); last_extent_written += 2 * jpath_blocks; free(jpath_table_l); free(jpath_table_m); jpath_table_l = NULL; jpath_table_m = NULL; return 0;}static intjdirtree_size(starting_extent) int starting_extent;{ assign_joliet_directory_addresses(root); return 0;}static intjroot_gen(){ jroot_record.length[0] = 1 + offsetof(struct iso_directory_record, name[0]); jroot_record.ext_attr_length[0] = 0; set_733((char *) jroot_record.extent, root->jextent); set_733((char *) jroot_record.size, ISO_ROUND_UP(root->jsize)); iso9660_date(jroot_record.date, root_statbuf.st_mtime); jroot_record.flags[0] = ISO_DIRECTORY; jroot_record.file_unit_size[0] = 0; jroot_record.interleave[0] = 0; set_723(jroot_record.volume_sequence_number, volume_sequence_number); jroot_record.name_len[0] = 1; return 0;}static intjdirtree_write(outfile) FILE *outfile;{ generate_joliet_directories(root, outfile); return 0;}/* * Function to write the EVD for the disc. */static intjvd_write(outfile) FILE *outfile;{ struct iso_primary_descriptor jvol_desc; /* Next we write out the boot volume descriptor for the disc */ jvol_desc = vol_desc; get_joliet_vol_desc(&jvol_desc); xfwrite(&jvol_desc, 1, SECTOR_SIZE, outfile); last_extent_written++; return 0;}/* * Functions to describe padding block at the start of the disc. */static intjpathtab_size(starting_extent) int starting_extent;{ jpath_table[0] = starting_extent; jpath_table[1] = 0; jpath_table[2] = jpath_table[0] + jpath_blocks; jpath_table[3] = 0; last_extent += 2 * jpath_blocks; return 0;}struct output_fragment joliet_desc = {NULL, oneblock_size, jroot_gen, jvd_write, "Joliet Volume Descriptor" };struct output_fragment jpathtable_desc = {NULL, jpathtab_size, generate_joliet_path_tables, jpathtab_write, "Joliet path table" };struct output_fragment jdirtree_desc = {NULL, jdirtree_size, NULL, jdirtree_write, "Joliet directory tree" };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -