📄 write.c
字号:
return strcmp(rr->self->isorec.name, ll->self->isorec.name); } /* compare_paths(... */static int generate_path_tables(){ struct directory_entry * de; struct directory * dpnt; int fix; int i; int j; int namelen; char * npnt; char * npnt1; int tablesize; /* * First allocate memory for the tables and initialize the memory */ tablesize = path_blocks << 11; path_table_m = (char *) e_malloc(tablesize); path_table_l = (char *) e_malloc(tablesize); memset(path_table_l, 0, tablesize); memset(path_table_m, 0, tablesize); /* * Now start filling in the path tables. Start with root directory */ if( next_path_index > 0xffff ) { fprintf(stderr, "Unable to generate sane path tables - too many directories (%d)\n", next_path_index); exit(1); } path_table_index = 0; pathlist = (struct directory **) e_malloc(sizeof(struct directory *) * next_path_index); memset(pathlist, 0, sizeof(struct directory *) * next_path_index); build_pathlist(root); do { fix = 0;#ifdef __STDC__ qsort(&pathlist[1], next_path_index-1, sizeof(struct directory *), (int (*)(const void *, const void *))compare_paths);#else qsort(&pathlist[1], next_path_index-1, sizeof(struct directory *), compare_paths);#endif for(j=1; j<next_path_index; j++) { if(pathlist[j]->path_index != j) { pathlist[j]->path_index = j; fix++; } } } while(fix); for(j=1; j<next_path_index; j++) { dpnt = pathlist[j]; if(!dpnt) { fprintf(stderr,"Entry %d not in path tables\n", j); exit(1); } npnt = dpnt->de_name; /* * So the root comes out OK */ if( (*npnt == 0) || (dpnt == root) ) { npnt = "."; } npnt1 = strrchr(npnt, PATH_SEPARATOR); if(npnt1) { npnt = npnt1 + 1; } de = dpnt->self; if(!de) { fprintf(stderr,"Fatal goof\n"); exit(1); } namelen = de->isorec.name_len[0]; path_table_l[path_table_index] = namelen; path_table_m[path_table_index] = namelen; path_table_index += 2; set_731(path_table_l + path_table_index, dpnt->extent); set_732(path_table_m + path_table_index, dpnt->extent); path_table_index += 4; set_721(path_table_l + path_table_index, dpnt->parent->path_index); set_722(path_table_m + path_table_index, dpnt->parent->path_index); path_table_index += 2; for(i =0; i<namelen; i++) { path_table_l[path_table_index] = de->isorec.name[i]; path_table_m[path_table_index] = de->isorec.name[i]; path_table_index++; } if(path_table_index & 1) { path_table_index++; /* For odd lengths we pad */ } } free(pathlist); if(path_table_index != path_table_size) { fprintf(stderr,"Path table lengths do not match %d %d\n", path_table_index, path_table_size); } return 0;} /* generate_path_tables(... */voidFDECL3(memcpy_max, char *, to, char *, from, int, max){ int n = strlen(from); if (n > max) { n = max; } memcpy(to, from, n);} /* memcpy_max(... */void FDECL1(outputlist_insert, struct output_fragment *, frag){ if( out_tail == NULL ) { out_list = out_tail = frag; } else { out_tail->of_next = frag; out_tail = frag; }}static int FDECL1(file_write, FILE *, outfile){ int should_write; /* * OK, all done with that crap. Now write out the directories. * This is where the fur starts to fly, because we need to keep track of * each file as we find it and keep track of where we put it. */ should_write = last_extent - session_start; if( print_size > 0 ) { fprintf(stderr,"Total extents scheduled to be written = %d\n", last_extent - session_start); exit(0); } if( verbose > 2 ) {#ifdef DBG_ISO fprintf(stderr,"Total directory extents being written = %d\n", last_extent);#endif fprintf(stderr,"Total extents scheduled to be written = %d\n", last_extent - session_start); } /* * Now write all of the files that we need. */ write_files(outfile); /* * The rest is just fluff. */ if( verbose == 0 ) { return 0; } fprintf(stderr,"Total extents actually written = %d\n", last_extent_written - session_start); /* * Hard links throw us off here */ if(should_write != last_extent - session_start) { fprintf(stderr,"Number of extents written not what was predicted. Please fix.\n"); fprintf(stderr,"Predicted = %d, written = %d\n", should_write, last_extent); } fprintf(stderr,"Total translation table size: %d\n", table_size); fprintf(stderr,"Total rockridge attributes bytes: %d\n", rockridge_size); fprintf(stderr,"Total directory bytes: %d\n", total_dir_size); fprintf(stderr,"Path table size(bytes): %d\n", path_table_size);#ifdef DEBUG fprintf(stderr, "next extent, last_extent, last_extent_written %d %d %d\n", next_extent, last_extent, last_extent_written);#endif return 0;} /* iso_write(... *//* * Function to write the PVD for the disc. */static int FDECL1(pvd_write, FILE *, outfile){ char iso_time[17]; int should_write; struct tm local; struct tm gmt; time(&begun); local = *localtime(&begun); gmt = *gmtime(&begun); /* * This will break in the year 2000, I supose, but there is no good way * to get the top two digits of the year. */ sprintf(iso_time, "%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d00", 1900 + local.tm_year, local.tm_mon+1, local.tm_mday, local.tm_hour, local.tm_min, local.tm_sec); local.tm_min -= gmt.tm_min; local.tm_hour -= gmt.tm_hour; local.tm_yday -= gmt.tm_yday; iso_time[16] = (local.tm_min + 60*(local.tm_hour + 24*local.tm_yday)) / 15; /* * Next we write out the primary descriptor for the disc */ memset(&vol_desc, 0, sizeof(vol_desc)); vol_desc.type[0] = ISO_VD_PRIMARY; memcpy(vol_desc.id, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID)); vol_desc.version[0] = 1; memset(vol_desc.system_id, ' ', sizeof(vol_desc.system_id)); memcpy_max(vol_desc.system_id, system_id, strlen(system_id)); memset(vol_desc.volume_id, ' ', sizeof(vol_desc.volume_id)); memcpy_max(vol_desc.volume_id, volume_id, strlen(volume_id)); should_write = last_extent - session_start; set_733((char *) vol_desc.volume_space_size, should_write); set_723(vol_desc.volume_set_size, volume_set_size); set_723(vol_desc.volume_sequence_number, volume_sequence_number); set_723(vol_desc.logical_block_size, 2048); /* * The path tables are used by DOS based machines to cache directory * locations */ set_733((char *) vol_desc.path_table_size, path_table_size); set_731(vol_desc.type_l_path_table, path_table[0]); set_731(vol_desc.opt_type_l_path_table, path_table[1]); set_732(vol_desc.type_m_path_table, path_table[2]); set_732(vol_desc.opt_type_m_path_table, path_table[3]); /* * Now we copy the actual root directory record */ memcpy(vol_desc.root_directory_record, &root_record, sizeof(struct iso_directory_record) + 1); /* * The rest is just fluff. It looks nice to fill in many of these fields, * though. */ FILL_SPACE(volume_set_id); if(volset_id) memcpy_max(vol_desc.volume_set_id, volset_id, strlen(volset_id)); FILL_SPACE(publisher_id); if(publisher) memcpy_max(vol_desc.publisher_id, publisher, strlen(publisher)); FILL_SPACE(preparer_id); if(preparer) memcpy_max(vol_desc.preparer_id, preparer, strlen(preparer)); FILL_SPACE(application_id); if(appid) memcpy_max(vol_desc.application_id, appid, strlen(appid)); FILL_SPACE(copyright_file_id); if(copyright) memcpy_max(vol_desc.copyright_file_id, copyright, strlen(copyright)); FILL_SPACE(abstract_file_id); if(abstract) memcpy_max(vol_desc.abstract_file_id, abstract, strlen(abstract)); FILL_SPACE(bibliographic_file_id); if(biblio) memcpy_max(vol_desc.bibliographic_file_id, biblio, strlen(biblio)); FILL_SPACE(creation_date); FILL_SPACE(modification_date); FILL_SPACE(expiration_date); FILL_SPACE(effective_date); vol_desc.file_structure_version[0] = 1; FILL_SPACE(application_data); memcpy(vol_desc.creation_date, iso_time, 17); memcpy(vol_desc.modification_date, iso_time, 17); memcpy(vol_desc.expiration_date, "0000000000000000", 17); memcpy(vol_desc.effective_date, iso_time, 17); /* * if not a bootable cd do it the old way */ xfwrite(&vol_desc, 1, 2048, outfile); last_extent_written++; return 0;}/* * Function to write the EVD for the disc. */static int FDECL1(evd_write, FILE *, outfile){ struct iso_primary_descriptor evol_desc; /* * Now write the end volume descriptor. Much simpler than the other one */ memset(&evol_desc, 0, sizeof(evol_desc)); evol_desc.type[0] = ISO_VD_END; memcpy(evol_desc.id, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID)); evol_desc.version[0] = 1; xfwrite(&evol_desc, 1, 2048, outfile); last_extent_written += 1; return 0;}/* * Function to write the EVD for the disc. */static int FDECL1(pathtab_write, FILE *, outfile){ /* * Next we write the path tables */ xfwrite(path_table_l, 1, path_blocks << 11, outfile); xfwrite(path_table_m, 1, path_blocks << 11, outfile); last_extent_written += 2*path_blocks; free(path_table_l); free(path_table_m); path_table_l = NULL; path_table_m = NULL; return 0;}static int FDECL1(exten_write, FILE *, outfile){ xfwrite(extension_record, 1, SECTOR_SIZE, outfile); last_extent_written++; return 0;}/* * Functions to describe padding block at the start of the disc. */int FDECL1(oneblock_size, int, starting_extent){ last_extent++; return 0;}/* * Functions to describe padding block at the start of the disc. */static int FDECL1(pathtab_size, int, starting_extent){ path_table[0] = starting_extent; path_table[1] = 0; path_table[2] = path_table[0] + path_blocks; path_table[3] = 0; last_extent += 2*path_blocks; return 0;}static int FDECL1(padblock_size, int, starting_extent){ last_extent += 16; return 0;}static int file_gen(){ assign_file_addresses(root); return 0;}static int dirtree_dump(){ if (verbose > 2) { dump_tree(root); } return 0;}static int FDECL1(dirtree_fixup, int, starting_extent){ if (use_RockRidge && reloc_dir) finish_cl_pl_entries(); if (use_RockRidge ) update_nlink_field(root); return 0;}static int FDECL1(dirtree_size, int, starting_extent){ assign_directory_addresses(root); return 0;}static int FDECL1(ext_size, int, starting_extent){ extern int extension_record_size; struct directory_entry * s_entry; extension_record_extent = starting_extent; s_entry = root->contents; set_733((char *) s_entry->rr_attributes + s_entry->rr_attr_size - 24, extension_record_extent); set_733((char *) s_entry->rr_attributes + s_entry->rr_attr_size - 8, extension_record_size); last_extent++; return 0;}static int FDECL1(dirtree_write, FILE *, outfile){ generate_iso9660_directories(root, outfile); return 0;}static int FDECL1(dirtree_cleanup, FILE *, outfile){ free_directories(root); return 0;}static int FDECL1(padblock_write, FILE *, outfile){ char buffer[2048]; int i; memset(buffer, 0, sizeof(buffer)); for(i=0; i<16; i++) { xfwrite(buffer, 1, sizeof(buffer), outfile); } last_extent_written += 16; return 0;}struct output_fragment padblock_desc = {NULL, padblock_size, NULL, padblock_write};struct output_fragment voldesc_desc = {NULL, oneblock_size, root_gen, pvd_write};struct output_fragment end_vol = {NULL, oneblock_size, NULL, evd_write};struct output_fragment pathtable_desc = {NULL, pathtab_size, generate_path_tables, pathtab_write};struct output_fragment dirtree_desc = {NULL, dirtree_size, NULL, dirtree_write};struct output_fragment dirtree_clean = {NULL, dirtree_fixup, dirtree_dump, dirtree_cleanup};struct output_fragment extension_desc = {NULL, ext_size, NULL, exten_write};struct output_fragment files_desc = {NULL, NULL, file_gen, file_write};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -