📄 tree.c
字号:
s_entry2->isorec.name_len[0] = s_entry1->isorec.name_len[0]; strcpy(s_entry2->isorec.name, s_entry1->isorec.name); s_entry2->isorec.length[0] = new_reclen; }#endif /* APPLE_HYB */ } add_file_hash(s_entry); s_entry = s_entry->next; } if (generate_tables && !find_file_hash(trans_tbl) && (reloc_dir != this_dir) && (this_dir->extent == 0)) { /* First we need to figure out how big this table is */ for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { if (strcmp(s_entry->name, ".") == 0 || strcmp(s_entry->name, "..") == 0) continue;#ifdef APPLE_HYB /* skip table entry for the resource fork */ if (apple_both && (s_entry->isorec.flags[0] & ISO_ASSOCIATED)) continue;#endif /* APPLE_HYB */ if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) continue; if (s_entry->table) { /* * Max namelen, a space before and a space * after the iso filename. */ tablesize += MAX_ISONAME + 2 + strlen(s_entry->table); } } } if (tablesize > 0) { table = (struct directory_entry *) e_malloc(sizeof(struct directory_entry)); memset(table, 0, sizeof(struct directory_entry)); table->table = NULL; table->next = this_dir->contents; this_dir->contents = table; table->filedir = root; table->isorec.flags[0] = ISO_FILE; table->priority = 32768; iso9660_date(table->isorec.date, fstatbuf.st_mtime); table->inode = TABLE_INODE; table->dev = (dev_t) UNCACHED_DEVICE; set_723(table->isorec.volume_sequence_number, volume_sequence_number); set_733((char *) table->isorec.size, tablesize); table->size = tablesize; table->filedir = this_dir; if (jhide_trans_tbl) table->de_flags |= INHIBIT_JOLIET_ENTRY;/* table->name = strdup("<translation table>");*/ table->name = strdup(trans_tbl); table->table = (char *) e_malloc(ISO_ROUND_UP(tablesize)); memset(table->table, 0, ISO_ROUND_UP(tablesize)); iso9660_file_length(trans_tbl, table, 0); if (use_RockRidge) { fstatbuf.st_mode = 0444 | S_IFREG; fstatbuf.st_nlink = 1; generate_rock_ridge_attributes("", trans_tbl, table, &fstatbuf, &fstatbuf, 0); } } /* * We have now chosen the 8.3 names and we should now know the length * of every entry in the directory. */ for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { /* skip if it's hidden */ if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { continue; } new_reclen = strlen(s_entry->isorec.name); /* First update the path table sizes for directories. */ if (s_entry->isorec.flags[0] & ISO_DIRECTORY) { if (strcmp(s_entry->name, ".") != 0 && strcmp(s_entry->name, "..") != 0) { path_table_size += new_reclen + offsetof(struct iso_path_table, name[0]); if (new_reclen & 1) path_table_size++; } else { new_reclen = 1; if (this_dir == root && strlen(s_entry->name) == 1) { path_table_size += new_reclen + offsetof(struct iso_path_table, name[0]); } } } if (path_table_size & 1) path_table_size++; /* For odd lengths we pad */ s_entry->isorec.name_len[0] = new_reclen; new_reclen += offsetof(struct iso_directory_record, name[0]); if (new_reclen & 1) new_reclen++; new_reclen += s_entry->rr_attr_size; if (new_reclen & 1) new_reclen++; if (new_reclen > 0xff) {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Fatal error - RR overflow for file %s\n", s_entry->name);#else fprintf(stderr, "Fatal error - RR overflow for file %s\n", s_entry->name); exit(1);#endif } s_entry->isorec.length[0] = new_reclen; } status = sort_directory(&this_dir->contents, (reloc_dir == this_dir)); if (status > 0) {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Unable to sort directory %s\n", this_dir->whole_name);#else fprintf(stderr, "Unable to sort directory %s\n", this_dir->whole_name); exit(1);#endif } /* * If we are filling out a TRANS.TBL, generate the entries that will * go in the thing. */ if (table) { count = 0; for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { if (s_entry == table) continue; if (!s_entry->table) continue; if (strcmp(s_entry->name, ".") == 0 || strcmp(s_entry->name, "..") == 0) continue;#ifdef APPLE_HYB /* skip table entry for the resource fork */ if (apple_both && (s_entry->isorec.flags[0] & ISO_ASSOCIATED)) continue;#endif /* APPLE_HYB */ if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) continue; /* * Warning: we cannot use the return value of sprintf * because old BSD based sprintf() implementations * will return a pointer to the result instead of a * count. * Old mkiofs introduced a spacee after the iso * filename to make parsing TRANS.TBL easier. */ sprintf(table->table + count, "%c %-*s%s", s_entry->table[0], MAX_ISONAME + 1, s_entry->isorec.name, s_entry->table + 1); count += strlen(table->table + count); free(s_entry->table); /* * for a memory file, set s_entry->table to the * correct data - which is stored in * s_entry->whole_name */ if (s_entry->de_flags & MEMORY_FILE) { s_entry->table = s_entry->whole_name; s_entry->whole_name = NULL; } else { s_entry->table = NULL; } } if (count != tablesize) {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Translation table size mismatch %d %d\n", count, tablesize);#else fprintf(stderr, "Translation table size mismatch %d %d\n", count, tablesize); exit(1);#endif } } /* * 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->contents; this_dir->ce_bytes = 0; while (s_entry) { /* skip if it's hidden */ if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { s_entry = s_entry->next; continue; } new_reclen = s_entry->isorec.length[0]; if ((this_dir->size & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE) this_dir->size = (this_dir->size + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1); this_dir->size += new_reclen; /* See if continuation entries were used on disc */ if (use_RockRidge && s_entry->rr_attr_size != s_entry->total_rr_attr_size) { unsigned char *pnt; int len; int nbytes; pnt = s_entry->rr_attributes; len = s_entry->total_rr_attr_size; pnt = parse_xa(pnt, &len, 0); /* * We make sure that each continuation entry record is * not split across sectors, but each file could in * theory have more than one CE, so we scan through * and figure out what we need. */ while (len > 3) { if (pnt[0] == 'C' && pnt[1] == 'E') { nbytes = get_733((char *) pnt + 20); if ((this_dir->ce_bytes & (SECTOR_SIZE - 1)) + nbytes >= SECTOR_SIZE) this_dir->ce_bytes = ISO_ROUND_UP(this_dir->ce_bytes); /* * Now store the block in the * ce buffer */ this_dir->ce_bytes += nbytes; if (this_dir->ce_bytes & 1) this_dir->ce_bytes++; } len -= pnt[2]; pnt += pnt[2]; } } s_entry = s_entry->next; } return status;}static voidgenerate_reloc_directory(){ time_t current_time; struct directory_entry *s_entry; /* Create an entry for our internal tree */ time(¤t_time); reloc_dir = (struct directory *) e_malloc(sizeof(struct directory)); memset(reloc_dir, 0, sizeof(struct directory)); reloc_dir->parent = root; reloc_dir->next = root->subdir; root->subdir = reloc_dir; reloc_dir->depth = 1; if (hide_rr_moved) { reloc_dir->whole_name = strdup("./.rr_moved"); reloc_dir->de_name = strdup(".rr_moved"); } else { reloc_dir->whole_name = strdup("./rr_moved"); reloc_dir->de_name = strdup("rr_moved"); } reloc_dir->extent = 0; /* Now create an actual directory entry */ s_entry = (struct directory_entry *) e_malloc(sizeof(struct directory_entry)); memset(s_entry, 0, sizeof(struct directory_entry)); s_entry->next = root->contents; reloc_dir->self = s_entry; /* The rr_moved entry will not appear in the Joliet tree. */ reloc_dir->dir_flags |= INHIBIT_JOLIET_ENTRY; s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; /* Hiding RR_MOVED seems not to be possible..... */#ifdef HIDE_RR reloc_dir->dir_flags |= INHIBIT_ISO9660_ENTRY; s_entry->de_flags |= INHIBIT_ISO9660_ENTRY;#endif root->contents = s_entry; root->contents->name = strdup(reloc_dir->de_name); root->contents->filedir = root; root->contents->isorec.flags[0] = ISO_DIRECTORY; root->contents->priority = 32768; iso9660_date(root->contents->isorec.date, current_time); root->contents->inode = UNCACHED_INODE; root->contents->dev = (dev_t) UNCACHED_DEVICE; set_723(root->contents->isorec.volume_sequence_number, volume_sequence_number); iso9660_file_length(reloc_dir->de_name, root->contents, 1); init_fstatbuf(); if (use_RockRidge) { fstatbuf.st_mode = 0555 | S_IFDIR; fstatbuf.st_nlink = 2; generate_rock_ridge_attributes("", hide_rr_moved ? ".rr_moved" : "rr_moved", s_entry, &fstatbuf, &fstatbuf, 0); }; /* Now create the . and .. entries in rr_moved */ /* Now create an actual directory entry */ attach_dot_entries(reloc_dir, &root_statbuf);}/* * Function: attach_dot_entries * * Purpose: Create . and .. entries for a new directory. * * Notes: Only used for artificial directories that * we are creating. */static voidattach_dot_entries(dirnode, parent_stat) struct directory *dirnode; struct stat *parent_stat;{ struct directory_entry *s_entry; struct directory_entry *orig_contents; int deep_flag = 0; init_fstatbuf(); orig_contents = dirnode->contents; if ((dirnode->dir_flags & DIR_HAS_DOTDOT) == 0) { s_entry = (struct directory_entry *) e_malloc(sizeof(struct directory_entry)); memcpy(s_entry, dirnode->self, sizeof(struct directory_entry)); s_entry->name = strdup(".."); s_entry->whole_name = NULL; s_entry->isorec.name_len[0] = 1; s_entry->isorec.flags[0] = ISO_DIRECTORY; iso9660_file_length("..", s_entry, 1); iso9660_date(s_entry->isorec.date, fstatbuf.st_mtime); set_723(s_entry->isorec.volume_sequence_number, volume_sequence_number); set_733(s_entry->isorec.size, SECTOR_SIZE); memset(s_entry->isorec.extent, 0, 8); s_entry->filedir = dirnode->parent; dirnode->contents = s_entry; dirnode->contents->next = orig_contents; orig_contents = s_entry; if (use_RockRidge) { if (parent_stat == NULL) { parent_stat = &fstatbuf; } generate_rock_ridge_attributes("", "..", s_entry, parent_stat, parent_stat, 0); } dirnode->dir_flags |= DIR_HAS_DOTDOT; } if ((dirnode->dir_flags & DIR_HAS_DOT) == 0) { s_entry = (struct directory_entry *) e_malloc(sizeof(struct directory_entry)); memcpy(s_entry, dirnode->self, sizeof(struct directory_entry)); s_entry->name = strdup("."); s_entry->whole_name = NULL; s_entry->isorec.name_len[0] = 1; s_entry->isorec.flags[0] = ISO_DIRECTORY; iso9660_file_length(".", s_entry, 1); iso9660_date(s_entry->isorec.date, fstatbuf.st_mtime); set_723(s_entry->isorec.volume_sequence_number, volume_sequence_number); set_733(s_entry->isorec.size, SECTOR_SIZE); memset(s_entry->isorec.extent, 0, 8); s_entry->filedir = dirnode; dirnode->contents = s_entry; dirnode->contents->next = orig_contents; if (use_RockRidge) { fstatbuf.st_mode = new_dir_mode | S_IFDIR; fstatbuf.st_nlink = 2; if (dirnode == root) { deep_flag |= NEED_CE | NEED_SP; /* For extension record */ } generate_rock_ridge_attributes("", ".", s_entry, &fstatbuf, &fstatbuf, deep_flag); } dirnode->dir_flags |= DIR_HAS_DOT; }}static voidupdate_nlink(s_entry, value) struct directory_entry *s_entry; int value;{ unsigned char *pnt; int len; pnt = s_entry->rr_attributes; len = s_entry->total_rr_attr_size; pnt = parse_xa(pnt, &len, 0); while (len > 0) { if (pnt[0] == 'P' && pnt[1] == 'X') { set_733((char *) pnt + 12, value); break; } len -= pnt[2]; pnt += pnt[2]; }}static voidincrement_nlink(s_entry) struct directory_entry *s_entry;{ unsigned char *pnt; int len, nlink; pnt = s_entry->rr_attributes; len = s_entry->total_rr_attr_size; pnt = parse_xa(pnt, &len, 0); while (len > 0) { if (pnt[0] == 'P' && pnt[1] == 'X') { nlink = get_733((char *) pnt + 12); set_733((char *) pnt + 12, nlink + 1); break; } len -= pnt[2]; pnt += pnt[2]; }}char *find_rr_attribute(pnt, len, attr_type) unsigned char *pnt; int len; char *attr_type;{ pnt = parse_xa(pnt, &len, 0); while (len >= 4) { if (pnt[3] != 1 && pnt[3] != 2) {#ifdef USE_LIBSCHILY errmsgno(EX_BAD, "**BAD RRVERSION (%d) for %c%c\n", pnt[3], pnt[0], pnt[1]);#else fprintf(stderr, "**BAD RRVERSION (%d) for %c%c\n", pnt[3], pnt[0], pnt[1]);#endif } if (strncmp((char *) pnt, attr_type, 2) == 0) return ((char *) pnt); else if (strncmp((char *) pnt, "ST", 2) == 0) return (NULL); len -= pnt[2]; pnt += pnt[2]; } return (NULL);}voidfinish_cl_pl_entries(){ struct directory_entry *s_entry, *s_entry1; struct directory *d_entry;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -