📄 joliet.c
字号:
dir_size = ISO_BLOCKS(dpnt->jsize); last_extent += dir_size; } } /* skip if hidden - but not for the rr_moved dir */ if (dpnt->subdir && (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir)) { assign_joliet_directory_addresses(dpnt->subdir); } dpnt = dpnt->next; }}static voidbuild_jpathlist(node) struct directory *node;{ struct directory *dpnt; dpnt = node; while (dpnt) { if ((dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0) { jpathlist[dpnt->jpath_index] = dpnt; } if (dpnt->subdir) build_jpathlist(dpnt->subdir); dpnt = dpnt->next; }}/* build_jpathlist(... */static intjoliet_compare_paths(r, l) void const *r; void const *l;{ struct directory const *ll = *(struct directory * const *) l; struct directory const *rr = *(struct directory * const *) r; int rparent, lparent; char *rpnt, *lpnt; unsigned char rtmp[2], ltmp[2]; struct nls_table *rinls, *linls; /* make sure root directory is first */ if (rr == root) return -1; if (ll == root) return 1; rparent = rr->parent->jpath_index; lparent = ll->parent->jpath_index; if (rr->parent == reloc_dir) { rparent = rr->self->parent_rec->filedir->jpath_index; } if (ll->parent == reloc_dir) { lparent = ll->self->parent_rec->filedir->jpath_index; } if (rparent < lparent) { return -1; } if (rparent > lparent) { return 1; }#ifdef APPLE_HYB /* * we may be using the HFS name - so select the correct input * charset */ if (USE_MAC_NAME(rr->self)) { rpnt = rr->self->hfs_ent->name; rinls = hfs_inls; } else { rpnt = rr->self->name; rinls = in_nls; } if (USE_MAC_NAME(ll->self)) { lpnt = ll->self->hfs_ent->name; linls = hfs_inls; } else { lpnt = ll->self->name; linls = in_nls; }#else rpnt = rr->self->name; lpnt = ll->self->name; linls = rinls = in_nls;#endif /* APPLE_HYB */ /* compare the Unicode names */ while (*rpnt && *lpnt) { 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;}/* compare_paths(... */static intgenerate_joliet_path_tables(){ struct directory_entry *de; struct directory *dpnt; int fix; int j; int namelen; char *npnt; char *npnt1; int tablesize; /* First allocate memory for the tables and initialize the memory */ tablesize = jpath_blocks << 11; jpath_table_m = (char *) e_malloc(tablesize); jpath_table_l = (char *) e_malloc(tablesize); memset(jpath_table_l, 0, tablesize); memset(jpath_table_m, 0, tablesize); /* Now start filling in the path tables. Start with root directory */ jpath_table_index = 0; jpathlist = (struct directory **) e_malloc(sizeof(struct directory *) * next_jpath_index); memset(jpathlist, 0, sizeof(struct directory *) * next_jpath_index); build_jpathlist(root); do { fix = 0;#ifdef __STDC__ qsort(&jpathlist[1], next_jpath_index - 1, sizeof(struct directory *), (int (*) (const void *, const void *)) joliet_compare_paths);#else qsort(&jpathlist[1], next_jpath_index - 1, sizeof(struct directory *), joliet_compare_paths);#endif for (j = 1; j < next_jpath_index; j++) { if (jpathlist[j]->jpath_index != j) { jpathlist[j]->jpath_index = j; fix++; } } } while (fix); for (j = 1; j < next_jpath_index; j++) { dpnt = jpathlist[j]; if (!dpnt) {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Entry %d not in path tables\n", j);#else fprintf(stderr, "Entry %d not in path tables\n", j); exit(1);#endif } npnt = dpnt->de_name; npnt1 = strrchr(npnt, PATH_SEPARATOR); if (npnt1) { npnt = npnt1 + 1; } de = dpnt->self; if (!de) {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Fatal Joliet goof - directory has amnesia\n");#else fprintf(stderr, "Fatal Joliet goof - directory has amnesia\n"); exit(1);#endif }#ifdef APPLE_HYB if (USE_MAC_NAME(de)) namelen = joliet_strlen(de->hfs_ent->name, gbk4win_filenames); else#endif /* APPLE_HYB */ namelen = joliet_strlen(de->name, gbk4win_filenames); if (dpnt == root) { jpath_table_l[jpath_table_index] = 1; jpath_table_m[jpath_table_index] = 1; } else { jpath_table_l[jpath_table_index] = namelen; jpath_table_m[jpath_table_index] = namelen; } jpath_table_index += 2; set_731(jpath_table_l + jpath_table_index, dpnt->jextent); set_732(jpath_table_m + jpath_table_index, dpnt->jextent); jpath_table_index += 4; if (dpnt->parent->jpath_index > 0xffff) {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Unable to generate sane path tables - too many directories (%d)\n", dpnt->parent->jpath_index);#else fprintf(stderr, "Unable to generate sane path tables - too many directories (%d)\n", dpnt->parent->jpath_index); exit(1);#endif } if (dpnt->parent != reloc_dir) { set_721(jpath_table_l + jpath_table_index, dpnt->parent->jpath_index); set_722(jpath_table_m + jpath_table_index, dpnt->parent->jpath_index); } else { set_721(jpath_table_l + jpath_table_index, dpnt->self->parent_rec->filedir->jpath_index); set_722(jpath_table_m + jpath_table_index, dpnt->self->parent_rec->filedir->jpath_index); } jpath_table_index += 2; /* * The root directory is still represented in non-unicode * fashion. */ if (dpnt == root) { jpath_table_l[jpath_table_index] = 0; jpath_table_m[jpath_table_index] = 0; jpath_table_index++; } else {#ifdef APPLE_HYB if (USE_MAC_NAME(de)) { convert_to_unicode((Uchar *) jpath_table_l + jpath_table_index, namelen, de->hfs_ent->name, hfs_inls, gbk4win_filenames); convert_to_unicode((Uchar *) jpath_table_m + jpath_table_index, namelen, de->hfs_ent->name, hfs_inls, gbk4win_filenames); } else {#endif /* APPLE_HYB */ convert_to_unicode((Uchar *) jpath_table_l + jpath_table_index, namelen, de->name, in_nls, gbk4win_filenames); convert_to_unicode((Uchar *) jpath_table_m + jpath_table_index, namelen, de->name, in_nls, gbk4win_filenames);#ifdef APPLE_HYB }#endif /* APPLE_HYB */ jpath_table_index += namelen; } if (jpath_table_index & 1) { jpath_table_index++; /* For odd lengths we pad */ } } free(jpathlist); if (jpath_table_index != jpath_table_size) {#ifdef USE_LIBSCHILY errmsgno(EX_BAD, "Joliet path table lengths do not match %d expected: %d\n", jpath_table_index, jpath_table_size);#else fprintf(stderr, "Joliet path table lengths do not match %d expected: %d\n", jpath_table_index, jpath_table_size);#endif } return 0;}/* generate_path_tables(... */static voidgenerate_one_joliet_directory(dpnt, outfile) struct directory *dpnt; FILE *outfile;{ unsigned int dir_index; char *directory_buffer; int new_reclen; struct directory_entry *s_entry; struct directory_entry *s_entry1; struct iso_directory_record jrec; unsigned int total_size; int cvt_len; struct directory *finddir; total_size = ISO_ROUND_UP(dpnt->jsize); directory_buffer = (char *) e_malloc(total_size); memset(directory_buffer, 0, total_size); dir_index = 0; s_entry = dpnt->jcontents; while (s_entry) { if (s_entry->de_flags & INHIBIT_JOLIET_ENTRY) { s_entry = s_entry->jnext; continue; } /* * If this entry was a directory that was relocated, * we have a bit of trouble here. We need to dig out the real * thing and put it back here. In the Joliet tree, there is * no relocated rock ridge, as there are no depth limits to a * directory tree. */ if ((s_entry->de_flags & RELOCATED_DIRECTORY) != 0) { for (s_entry1 = reloc_dir->contents; s_entry1; s_entry1 = s_entry1->next) { if (s_entry1->parent_rec == s_entry) { break; } } if (s_entry1 == NULL) { /* We got trouble. */#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Unable to locate relocated directory\n");#else fprintf(stderr, "Unable to locate relocated directory\n"); exit(1);#endif } } else { s_entry1 = s_entry; } /* * We do not allow directory entries to cross sector * boundaries. Simply pad, and then start the next entry at * the next sector */ new_reclen = s_entry1->jreclen; if ((dir_index & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE) { dir_index = ISO_ROUND_UP(dir_index); } memcpy(&jrec, &s_entry1->isorec, offsetof(struct iso_directory_record, name[0]));#ifdef APPLE_HYB /* Use the HFS name if it exists */ if (USE_MAC_NAME(s_entry1)) cvt_len = joliet_strlen(s_entry1->hfs_ent->name, gbk4win_filenames); else#endif /* APPLE_HYB */ cvt_len = joliet_strlen(s_entry1->name, gbk4win_filenames); /* * Fix the record length * - this was the non-Joliet version we were seeing. */ jrec.name_len[0] = cvt_len; jrec.length[0] = s_entry1->jreclen; /* * If this is a directory, * fix the correct size and extent number. */ if ((jrec.flags[0] & ISO_DIRECTORY) != 0) { if (strcmp(s_entry1->name, ".") == 0) { jrec.name_len[0] = 1; set_733((char *) jrec.extent, dpnt->jextent); set_733((char *) jrec.size, ISO_ROUND_UP(dpnt->jsize)); } else if (strcmp(s_entry1->name, "..") == 0) { jrec.name_len[0] = 1; if (dpnt->parent == reloc_dir) { set_733((char *)jrec.extent, dpnt->self->parent_rec->filedir->jextent); set_733((char *)jrec.size, ISO_ROUND_UP(dpnt->self->parent_rec->filedir->jsize)); } else { set_733((char *)jrec.extent, dpnt->parent->jextent); set_733((char *)jrec.size, ISO_ROUND_UP(dpnt->parent->jsize)); } } else { if ((s_entry->de_flags & RELOCATED_DIRECTORY) != 0) { finddir = reloc_dir->subdir; } else { finddir = dpnt->subdir; } while (1 == 1) { if (finddir->self == s_entry1) break; finddir = finddir->next; if (!finddir) {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Fatal goof - unable to find directory location\n");#else fprintf(stderr, "Fatal goof - unable to find directory location\n"); exit(1);#endif } } set_733((char *)jrec.extent, finddir->jextent); set_733((char *)jrec.size, ISO_ROUND_UP(finddir->jsize)); } } memcpy(directory_buffer + dir_index, &jrec, offsetof(struct iso_directory_record, name[0])); dir_index += offsetof(struct iso_directory_record, name[0]); /* * Finally dump the Unicode version of the filename. * Note - . and .. are the same as with non-Joliet discs. */ if ((jrec.flags[0] & ISO_DIRECTORY) != 0 && strcmp(s_entry1->name, ".") == 0) { directory_buffer[dir_index++] = 0; } else if ((jrec.flags[0] & ISO_DIRECTORY) != 0 && strcmp(s_entry1->name, "..") == 0) { directory_buffer[dir_index++] = 1; } else {#ifdef APPLE_HYB if (USE_MAC_NAME(s_entry1)) { /* Use the HFS name if it exists */ convert_to_unicode( (Uchar *) directory_buffer+dir_index, cvt_len, s_entry1->hfs_ent->name, hfs_inls, gbk4win_filenames); } else #endif /* APPLE_HYB */ convert_to_unicode( (Uchar *) directory_buffer+dir_index, cvt_len, s_entry1->name, in_nls, gbk4win_filenames); dir_index += cvt_len; } if (dir_index & 1) { directory_buffer[dir_index++] = 0; } s_entry = s_entry->jnext; } if (dpnt->jsize != dir_index) {#ifdef USE_LIBSCHILY errmsgno(EX_BAD, "Unexpected joliet directory length %d expected: %d '%s'\n", dpnt->jsize, dir_index, dpnt->de_name);#else fprintf(stderr, "Unexpected joliet directory length %d expected: %d '%s'\n", dpnt->jsize, dir_index, dpnt->de_name);#endif } xfwrite(directory_buffer, 1, total_size, outfile); last_extent_written += total_size >> 11;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -