⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 write.c

📁 创建一个符合iso-9660标准的iso文件系统
💻 C
📖 第 1 页 / 共 4 页
字号:
				~(SECTOR_SIZE - 1);		}		memcpy(directory_buffer + dir_index, &s_entry->isorec,			offsetof(struct iso_directory_record, name[0]) +			s_entry->isorec.name_len[0]);		dir_index += offsetof(struct iso_directory_record, name[0]) +			s_entry->isorec.name_len[0];		/* Add the Rock Ridge attributes, if present */		if (s_entry->rr_attr_size) {			if (dir_index & 1) {				directory_buffer[dir_index++] = 0;			}			/*			 * If the RR attributes were too long, then write the			 * CE records, as required.			 */			if (s_entry->rr_attr_size != s_entry->total_rr_attr_size) {				unsigned char	*pnt;				int		len,						nbytes;				/*				 * Go through the entire record and fix up the				 * CE entries so that the extent and offset				 * are correct				 */				pnt = s_entry->rr_attributes;				len = s_entry->total_rr_attr_size;				while (len > 3) {#ifdef DEBUG					if (ce_size <= 0) {						fprintf(stderr,						"Warning: ce_index(%d) && ce_address(%d) not initialized\n",							ce_index, ce_address);					}#endif					if (pnt[0] == 'C' && pnt[1] == 'E') {						nbytes = get_733((char *) pnt + 20);						if ((ce_index & (SECTOR_SIZE - 1)) + nbytes >=							SECTOR_SIZE) {							ce_index = ISO_ROUND_UP(ce_index);						}						set_733((char *) pnt + 4,							(ce_address + ce_index) >> 11);						set_733((char *) pnt + 12,							(ce_address + ce_index) & (SECTOR_SIZE - 1));						/*						 * Now store the block in the						 * ce buffer						 */						memcpy(ce_buffer + ce_index,							pnt + pnt[2], nbytes);						ce_index += nbytes;						if (ce_index & 1) {							ce_index++;						}					}					len -= pnt[2];					pnt += pnt[2];				}			}			rockridge_size += s_entry->total_rr_attr_size;			memcpy(directory_buffer + dir_index,				s_entry->rr_attributes,				s_entry->rr_attr_size);			dir_index += s_entry->rr_attr_size;		}		if (dir_index & 1) {			directory_buffer[dir_index++] = 0;		}		s_entry_d = s_entry;		s_entry = s_entry->next;		/*		 * Joliet doesn't use the Rock Ridge attributes, so we free		 * it here.		 */		if (s_entry_d->rr_attributes) {			free(s_entry_d->rr_attributes);			s_entry_d->rr_attributes = NULL;		}	}	if (dpnt->size != dir_index) {#ifdef	USE_LIBSCHILY		errmsgno(EX_BAD,			"Unexpected directory length %d expected: %d '%s'\n",			dpnt->size,			dir_index, dpnt->de_name);#else		fprintf(stderr,			"Unexpected directory length %d expected: %d '%s'\n",			dpnt->size,			dir_index, dpnt->de_name);#endif	}	xfwrite(directory_buffer, 1, total_size, outfile);	last_extent_written += total_size >> 11;	free(directory_buffer);	directory_buffer = NULL;	if (ce_size > 0) {		if (ce_index != dpnt->ce_bytes) {#ifdef	USE_LIBSCHILY			errmsgno(EX_BAD,			"Continuation entry record length mismatch %d expected: %d.\n",				ce_index, dpnt->ce_bytes);#else			fprintf(stderr,			"Continuation entry record length mismatch %d expected: %d.\n",				ce_index, dpnt->ce_bytes);#endif		}		xfwrite(ce_buffer, 1, ce_size, outfile);		last_extent_written += ce_size >> 11;		free(ce_buffer);		ce_buffer = NULL;	}}/* generate_one_directory(... */static voidbuild_pathlist(node)	struct directory	*node;{	struct directory *dpnt;	dpnt = node;	while (dpnt) {		/* skip if it's hidden */		if ((dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) == 0)			pathlist[dpnt->path_index] = dpnt;		if (dpnt->subdir)			build_pathlist(dpnt->subdir);		dpnt = dpnt->next;	}}/* build_pathlist(... */static intcompare_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;	if (rr->parent->path_index < ll->parent->path_index) {		return -1;	}	if (rr->parent->path_index > ll->parent->path_index) {		return 1;	}	return strcmp(rr->self->isorec.name, ll->self->isorec.name);}/* compare_paths(... */static intgenerate_path_tables(){	struct directory_entry *de = NULL;	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) {#ifdef	USE_LIBSCHILY		comerrno(EX_BAD,		"Unable to generate sane path tables - too many directories (%d)\n",			next_path_index);#else		fprintf(stderr,		"Unable to generate sane path tables - too many directories (%d)\n",			next_path_index);		exit(1);#endif	}	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) {#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;		/* 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) {#ifdef	USE_LIBSCHILY			comerrno(EX_BAD,			"Fatal ISO9660 goof - directory has amnesia\n");#else			fprintf(stderr,			"Fatal ISO9660 goof - directory has amnesia\n");			exit(1);#endif		}		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);	pathlist = NULL;	if (path_table_index != path_table_size) {#ifdef	USE_LIBSCHILY		errmsgno(EX_BAD,			"Path table lengths do not match %d expected: %d\n",			path_table_index,			path_table_size);#else		fprintf(stderr,			"Path table lengths do not match %d expected: %d\n",			path_table_index,			path_table_size);#endif	}	return 0;}/* generate_path_tables(... */voidmemcpy_max(to, from, max)	char	*to;	char	*from;	int	max;{	int	n = strlen(from);	if (n > max) {		n = max;	}	memcpy(to, from, n);}/* memcpy_max(... */voidoutputlist_insert(frag)	struct output_fragment *frag;{	if (out_tail == NULL) {		out_list = out_tail = frag;	} else {		out_tail->of_next = frag;		out_tail = frag;	}}static intfile_write(outfile)	FILE	*outfile;{	int	should_write;#ifdef APPLE_HYB	char	buffer[SECTOR_SIZE];	memset(buffer, 0, sizeof(buffer));	if (apple_hyb) {		int	i;		/*		 * write out padding to round up to HFS allocation block		 */		for (i = 0; i < hfs_pad; i++)			xfwrite(buffer, 1, sizeof(buffer), outfile);		last_extent_written += hfs_pad;	}#endif	/* APPLE_HYB */ /* 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 (verbose > 2) {#ifdef DBG_ISO		fprintf(stderr,			"Total directory extents being written = %d\n",							last_extent);#endif#ifdef APPLE_HYB		if (apple_hyb)			fprintf(stderr,			"Total extents scheduled to be written (inc HFS) = %d\n",				last_extent - session_start);		else#endif	/* APPLE_HYB */			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);#ifdef APPLE_HYB	/* write out extents/catalog/dt file */	if (apple_hyb) {		xfwrite(hce->hfs_ce, hce->hfs_tot_size, HFS_BLOCKSZ, outfile);		/* round up to a whole CD block */		if (HFS_ROUND_UP(hce->hfs_tot_size) -					hce->hfs_tot_size * HFS_BLOCKSZ) {			xfwrite(buffer, 1,				HFS_ROUND_UP(hce->hfs_tot_size) -				hce->hfs_tot_size * HFS_BLOCKSZ, outfile);		}		last_extent_written += ISO_ROUND_UP(hce->hfs_tot_size *						HFS_BLOCKSZ) / SECTOR_SIZE;		/* write out HFS boot block */		if (mac_boot.name)			write_one_file(mac_boot.name, mac_boot.size, outfile,								mac_boot.off);	}#endif	/* APPLE_HYB */	/* The rest is just fluff. */	if (verbose == 0) {		return 0;	}#ifdef APPLE_HYB	if (apple_hyb) {		fprintf(stderr,			"Total extents actually written (inc HFS) = %d\n",			last_extent_written - session_start);		fprintf(stderr, "(Size of ISO volume = %d, HFS extra = %d)\n",			last_extent_written - session_start - hfs_extra,			hfs_extra);	} else#else	fprintf(stderr, "Total extents actually written = %d\n",		last_extent_written - session_start);#endif	/* APPLE_HYB */	/* 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 intpvd_write(outfile)	FILE	*outfile;{	char		iso_time[17];	int		should_write;	struct tm	local;	struct tm	gmt;	time(&begun);	local = *localtime(&begun);	gmt = *gmtime(&begun);	/*	 * There was a comment here about breaking in the year 2000.	 * That's not true, in 2000 tm_year == 100, so 1900+tm_year == 2000.	 */	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, SECTOR_SIZE);	/*	 * 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,		offsetof(struct iso_directory_record, name[0]) + 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, SECTOR_SIZE, outfile);	last_extent_written++;	return 0;}/* * Function to write the EVD for the disc. */static intevd_write(outfile)	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] = (unsigned char) ISO_VD_END;	memcpy(evol_desc.id, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID));	evol_desc.version[0] = 1;	xfwrite(&evol_desc, 1, SECTOR_SIZE, outfile);	last_extent_written += 1;	return 0;}/* * Function to write the version information for the disc. */static intvers_write(outfile)	FILE	*outfile;{	char		vers[SECTOR_SIZE];	int		X_ac;	char		**X_av;	char		*cp;	int		i;	int		idx = 4;	int		len;	extern char	version_string[];	/* Now write the version descriptor. */	memset(vers, 0, sizeof(vers));	strcpy(vers, "MKI ");	cp = vers;	X_ac = saved_ac();	X_av = saved_av();	strcpy(&cp[idx], ctime(&begun));	idx += 25;	strcpy(&cp[idx], version_string);	idx += strlen(version_string);	for (i = 1; i < X_ac; i++) {		len = strlen(X_av[i]);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -