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

📄 write.c

📁 一款功能很强的光盘镜象制作工具
💻 C
📖 第 1 页 / 共 5 页
字号:
/* @(#)write.c	1.63 02/10/04 joerg */#ifndef lintstatic	char sccsid[] =	"@(#)write.c	1.63 02/10/04 joerg";#endif/* * Program write.c - dump memory  structures to  file for iso9660 filesystem.   Written by Eric Youngdale (1993).   Copyright 1993 Yggdrasil Computing, Incorporated   Copyright (c) 1999,2000,2001 J. Schilling   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2, or (at your option)   any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  *//* APPLE_HYB James Pearson j.pearson@ge.ucl.ac.uk 23/2/2000 */#include <mconfig.h>#include "mkisofs.h"#include "foolhash.h"#include "md5.h"#include <timedefs.h>#include <fctldefs.h>#ifdef SORTING#include "match.h"#endif /* SORTING */#include <errno.h>#include <schily.h>#ifdef DVD_VIDEO#include "dvd_reader.h"#include "dvd_file.h"#include "ifo_read.h"#endif#ifdef APPLE_HYB#include <ctype.h>#endif#ifdef __SVR4extern char    *strdup	__PR((const char *));#endif#ifdef VMSextern char    *strdup	__PR((const char *));#endifextern struct hash_table *md5_hash;/* Max number of sectors we will write at  one time */#define NSECT 16/* Counters for statistics */static int	table_size = 0;static int	total_dir_size = 0;static int	rockridge_size = 0;static struct directory **pathlist;static int	next_path_index = 1;static int	sort_goof;static int	is_rr_dir = 0;static int      showcount = 0;struct output_fragment *out_tail;struct output_fragment *out_list;struct iso_primary_descriptor vol_desc;	void	set_721		__PR((char *pnt, unsigned int i));	void	set_722		__PR((char *pnt, unsigned int i));	void	set_723		__PR((char *pnt, unsigned int i));	void	set_731		__PR((char *pnt, unsigned int i));	void	set_732		__PR((char *pnt, unsigned int i));	void	set_733		__PR((char *pnt, unsigned int i));	int	get_731		__PR((char *p));	int	get_732		__PR((char *p));	int	get_733		__PR((char *p));	void	xfwrite		__PR((void *buffer, int count, int size,						FILE *file));static	int	assign_directory_addresses __PR((struct directory *node));#ifdef APPLE_HYBstatic	void	write_one_file	__PR((char *filename, unsigned int size,					FILE *outfile, off_t off));#elsestatic	void	write_one_file	__PR((char *filename, unsigned int size,					FILE *outfile));#endifstatic	void	write_files	__PR((FILE *outfile));#if 0static	void	dump_filelist	__PR((void));#endifstatic	int	compare_dirs	__PR((const void *rr, const void *ll));	int	sort_directory	__PR((struct directory_entry **sort_dir,						int rr));static	int	root_gen	__PR((void));static	void	assign_file_addresses __PR((struct directory *dpnt));static	void	free_one_directory  __PR((struct directory *dpnt));static	void	free_directories __PR((struct directory *dpnt));	void	generate_one_directory __PR((struct directory *dpnt,						FILE *outfile));static	void	build_pathlist	__PR((struct directory *node));static	int	compare_paths	__PR((void const *r, void const *l));static	int	generate_path_tables __PR((void));	void	memcpy_max	__PR((char *to, char *from, int max));	void	outputlist_insert __PR((struct output_fragment *frag));static	int	file_write	__PR((FILE *outfile));static	int	pvd_write	__PR((FILE *outfile));static	int	evd_write	__PR((FILE *outfile));static	int	vers_write	__PR((FILE *outfile));static	int	graftcp		__PR((char *to, char *from, char *ep));static	int	pathcp		__PR((char *to, char *from, char *ep));static	int	pathtab_write	__PR((FILE *outfile));static	int	exten_write	__PR((FILE *outfile));	int	oneblock_size	__PR((int starting_extent));static	int	pathtab_size	__PR((int starting_extent));static	int	padblock_size	__PR((int starting_extent));static	int	padend_size	__PR((int starting_extent));static	int	file_gen	__PR((void));static	int	dirtree_dump	__PR((void));static	int	dirtree_fixup	__PR((int starting_extent));static	int	dirtree_size	__PR((int starting_extent));static	int	ext_size	__PR((int starting_extent));static	int	dirtree_write	__PR((FILE *outfile));static	int	dirtree_cleanup	__PR((FILE *outfile));static	int	padblock_write	__PR((FILE *outfile));static	int	padend_write	__PR((FILE *outfile));#ifdef APPLE_HYBstatic	int	hfs_pad;static	int	hfs_get_parms	__PR((char * key));static	void	hfs_file_gen	__PR((int start_extent));static	void	gen_prepboot	__PR((void));	Ulong	get_adj_size	__PR((int Csize));	int	adj_size	__PR((int Csize, int start_extent, int extra));	void	adj_size_other	__PR((struct directory *dpnt));static	int	hfs_hce_write	__PR((FILE * outfile));	int	insert_padding_file __PR((int size));#endif	/* APPLE_HYB */#ifdef SORTINGstatic	int	compare_sort	__PR((const void * rr, const void * ll));static	void	reassign_link_addresses	__PR((struct directory * dpnt));static	int	sort_file_addresses __PR((void));#endif /* SORTING *//* * Routines to actually write the disc.  We write sequentially so that * we could write a tape, or write the disc directly  */#define FILL_SPACE(X)	memset(vol_desc.X, ' ', sizeof(vol_desc.X))voidset_721(pnt, i)	char		*pnt;	unsigned int	i;{	pnt[0] = i & 0xff;	pnt[1] = (i >> 8) & 0xff;}voidset_722(pnt, i)	char		*pnt;	unsigned int	i;{	pnt[0] = (i >> 8) & 0xff;	pnt[1] = i & 0xff;}voidset_723(pnt, i)	char		*pnt;	unsigned int	i;{	pnt[3] = pnt[0] = i & 0xff;	pnt[2] = pnt[1] = (i >> 8) & 0xff;}voidset_731(pnt, i)	char		*pnt;	unsigned int	i;{	pnt[0] = i & 0xff;	pnt[1] = (i >> 8) & 0xff;	pnt[2] = (i >> 16) & 0xff;	pnt[3] = (i >> 24) & 0xff;}voidset_732(pnt, i)	char		*pnt;	unsigned int	i;{	pnt[3] = i & 0xff;	pnt[2] = (i >> 8) & 0xff;	pnt[1] = (i >> 16) & 0xff;	pnt[0] = (i >> 24) & 0xff;}voidset_733(pnt, i)	char		*pnt;	unsigned int	i;{	pnt[7] = pnt[0] = i & 0xff;	pnt[6] = pnt[1] = (i >> 8) & 0xff;	pnt[5] = pnt[2] = (i >> 16) & 0xff;	pnt[4] = pnt[3] = (i >> 24) & 0xff;}intget_731(p)	char	*p;{	return ((p[0] & 0xff)		| ((p[1] & 0xff) << 8)		| ((p[2] & 0xff) << 16)		| ((p[3] & 0xff) << 24));}intget_732(p)	char	*p;{	return ((p[3] & 0xff)		| ((p[2] & 0xff) << 8)		| ((p[1] & 0xff) << 16)		| ((p[0] & 0xff) << 24));}intget_733(p)	char	*p;{	return ((p[0] & 0xff)		| ((p[1] & 0xff) << 8)		| ((p[2] & 0xff) << 16)		| ((p[3] & 0xff) << 24));}voidxfwrite(buffer, count, size, file)	void	*buffer;	int	count;	int	size;	FILE	*file;{	/*	 * This is a hack that could be made better.	 * XXXIs this the only place?	 * It is definitely needed on Operating Systems that do not allow to	 * write files that are > 2GB. If the system is fast enough to be able	 * to feed 1400 KB/s writing speed of a DVD-R drive, use stdout.	 * If the system cannot do this reliable, you need to use this hacky	 * option.	 */	static int	idx = 0;	if (split_output != 0 &&		(idx == 0 || ftell(file) >= ((off_t)1024 * 1024 * 1024))) {		char		nbuf[512];		extern char	*outfile;		if (idx == 0)			unlink(outfile);		sprintf(nbuf, "%s_%02d", outfile, idx++);		file = freopen(nbuf, "wb", file);		if (file == NULL) {#ifdef	USE_LIBSCHILY			comerr("Cannot open '%s'.\n", nbuf);#else			fprintf(stderr, "Cannot open '%s'.\n", nbuf);			exit(1);#endif		}	}	while (count) {		int		got = fwrite(buffer, size, count, file);		if (got <= 0) {#ifdef	USE_LIBSCHILY			comerr("cannot fwrite %d*%d\n", size, count);#else			fprintf(stderr, "cannot fwrite %d*%d\n", size, count);			exit(1);#endif		}		count -= got, *(char **) &buffer += size * got;	}}#ifdef APPLE_HYB/* * use the deferred_write struct to store info about the hfs_boot_file */static struct deferred_write mac_boot;#endif	/* APPLE_HYB */static struct deferred_write	*dw_head = NULL,				*dw_tail = NULL;unsigned int	last_extent_written = 0;static Uint	path_table_index;static time_t	begun;/* * We recursively walk through all of the directories and assign extent * numbers to them.  We have already assigned extent numbers to everything that * goes in front of them */static intassign_directory_addresses(node)	struct directory	*node;{	int		dir_size;	struct directory *dpnt;	dpnt = node;	while (dpnt) {		/* skip if it's hidden */		if (dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) {			dpnt = dpnt->next;			continue;		}		/*		 * If we already have an extent for this (i.e. it came from a		 * multisession disc), then don't reassign a new extent.		 */		dpnt->path_index = next_path_index++;		if (dpnt->extent == 0) {			dpnt->extent = last_extent;			dir_size = ISO_BLOCKS(dpnt->size);			last_extent += dir_size;			/*			 * Leave room for the CE entries for this directory.			 * Keep them close to the reference directory so that			 * access will be quick.			 */			if (dpnt->ce_bytes) {				last_extent += ISO_BLOCKS(dpnt->ce_bytes);			}		}		if (dpnt->subdir) {			assign_directory_addresses(dpnt->subdir);		}		dpnt = dpnt->next;	}	return 0;}#ifdef APPLE_HYBstatic voidwrite_one_file(filename, size, outfile, off)	char		*filename;	unsigned int	size;	FILE		*outfile;	off_t		off;#elsestatic voidwrite_one_file(filename, size, outfile)	char		*filename;	unsigned int	size;	FILE		*outfile;#endif	/* APPLE_HYB */{	/*	 * It seems that there are still stone age C-compilers	 * around.	 * The Metrowerks C found on BeOS/PPC does not allow	 * more than 32kB of local vars.	 * As we do not need to call write_one_file() recursively	 * we make buffer static.	 */static	char		buffer[SECTOR_SIZE * NSECT];	FILE		*infile;	int		remain;	int	use;	if ((infile = fopen(filename, "rb")) == NULL) {#ifdef	USE_LIBSCHILY		comerr("cannot open '%s'\n", filename);#else#ifndef	HAVE_STRERROR		fprintf(stderr, "cannot open '%s': (%d)\n",				filename, errno);#else		fprintf(stderr, "cannot open '%s': %s\n",				filename, strerror(errno));#endif		exit(1);#endif	}#ifdef APPLE_HYB	fseek(infile, off, SEEK_SET);#endif	/* APPLE_HYB */	remain = size;	while (remain > 0) {		use = (remain > SECTOR_SIZE * NSECT - 1 ?				NSECT * SECTOR_SIZE : remain);		use = ISO_ROUND_UP(use);	/* Round up to nearest sector						   boundary */		memset(buffer, 0, use);		if (fread(buffer, 1, use, infile) == 0) {#ifdef	USE_LIBSCHILY			comerr("cannot read from '%s'\n", filename);#else			fprintf(stderr, "cannot read from '%s'\n", filename);			exit(1);#endif		}		xfwrite(buffer, 1, use, outfile);		last_extent_written += use / SECTOR_SIZE;#if 0		if ((last_extent_written % 1000) < use / SECTOR_SIZE) {			fprintf(stderr, "%d..", last_extent_written);		}#else		if (verbose > 0 &&			   (int)(last_extent_written % (gui ? 500 : 5000)) <							use / SECTOR_SIZE) {			time_t	now;			time_t	the_end;			double	frac;			time(&now);			frac = last_extent_written / (1.0 * last_extent);			the_end = begun + (now - begun) / frac;#ifndef NO_FLOATINGPOINT			fprintf(stderr, "%6.2f%% done, estimate finish %s",				frac * 100., ctime(&the_end));#else			fprintf(stderr, "%3d.%-02d%% done, estimate finish %s",				(int)(frac * 100.),				(int)((frac+.00005) * 10000.)%100,				ctime(&the_end));#endif			fflush(stderr);		}#endif		remain -= use;	}	fclose(infile);}/* write_one_file(... */static voidwrite_files(outfile)	FILE	*outfile;{	struct deferred_write	*dwpnt,				*dwnext;	dwpnt = dw_head;	while (dwpnt) {#ifdef DEBUG		fprintf(stderr,		"The file name is %s and pad is %d, size is %d and extent is %d\n",				dwpnt->name, dwpnt->pad,				dwpnt->size, dwpnt->extent);#endif		if (dwpnt->table) {			xfwrite(dwpnt->table, 1, ISO_ROUND_UP(dwpnt->size),								outfile);			last_extent_written += ISO_BLOCKS(dwpnt->size);			table_size += dwpnt->size;/*			fprintf(stderr, "Size %d ", dwpnt->size); */			free(dwpnt->table);			dwpnt->table = NULL;		} else {#ifdef VMS			vms_write_one_file(dwpnt->name, dwpnt->size, outfile);#else#ifdef APPLE_HYB			write_one_file(dwpnt->name, dwpnt->size, outfile,								dwpnt->off);#else			write_one_file(dwpnt->name, dwpnt->size, outfile);#endif	/* APPLE_HYB */#endif			free(dwpnt->name);			dwpnt->name = NULL;		}		#ifndef DVD_VIDEO#define	dvd_video	0#endif#ifndef APPLE_HYB#define	apple_hyb	0#endif #if	defined(APPLE_HYB) || defined(DVD_VIDEO)		if (apple_hyb || dvd_video) {			/*			 * we may have to pad out ISO files to work with HFS			 * clump sizes			 */			char	blk[SECTOR_SIZE];			Uint	i;			for (i = 0; i < dwpnt->pad; i++)				xfwrite(blk, 1, SECTOR_SIZE, outfile);			last_extent_written += dwpnt->pad;		}#endif	/* APPLE_HYB || DVD_VIDEO */		dwnext = dwpnt;		dwpnt = dwpnt->next;		free(dwnext);		dwnext = NULL;	}}/* write_files(... */#if 0static voiddump_filelist(){	struct deferred_write *dwpnt;	dwpnt = dw_head;	while (dwpnt) {		fprintf(stderr, "File %s\n", dwpnt->name);		dwpnt = dwpnt->next;	}	fprintf(stderr, "\n");

⌨️ 快捷键说明

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