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

📄 write.c

📁 一款功能很强的光盘镜象制作工具
💻 C
📖 第 1 页 / 共 5 页
字号:
}#endifstatic intcompare_dirs(rr, ll)	const void	*rr;	const void	*ll;{	char		*rpnt,			*lpnt;	struct directory_entry **r,			**l;	r = (struct directory_entry **) rr;	l = (struct directory_entry **) ll;	rpnt = (*r)->isorec.name;	lpnt = (*l)->isorec.name;#ifdef APPLE_HYB	/*	 * resource fork MUST (not sure if this is true for HFS volumes) be	 * before the data fork - so force it here	 */	if ((*r)->assoc && (*r)->assoc == (*l))		return 1;	if ((*l)->assoc && (*l)->assoc == (*r))		return -1;#endif	/* APPLE_HYB */	/* If the entries are the same, this is an error. */	if (strcmp(rpnt, lpnt) == 0) {#ifdef	USE_LIBSCHILY		errmsgno(EX_BAD,			"Error: '%s' and '%s' have the same ISO9660 name '%s'.\n",			(*r)->whole_name, (*l)->whole_name,			rpnt);#else		fprintf(stderr,			"Error: '%s' and '%s' have the same ISO9660 name '%s'.\n",			(*r)->whole_name, (*l)->whole_name,			rpnt);#endif		sort_goof++;	}	/* Check we don't have the same RR name */	if (use_RockRidge && !is_rr_dir) {		/*		 * entries *can* have the same RR name in the "rr_moved"		 * directory so skip checks if we're in reloc_dir		 */		if (!(strcmp((*r)->name, (*l)->name))) {#ifdef	USE_LIBSCHILY			errmsgno(EX_BAD,			"Error: '%s' and '%s' have the same Rock Ridge name '%s'.\n",				(*r)->whole_name, (*l)->whole_name,				(*r)->name);#else			fprintf(stderr,			"Error: '%s' and '%s' have the same Rock Ridge name '%s'.\n",				(*r)->whole_name, (*l)->whole_name,				(*r)->name);#endif			sort_goof++;		}	}	/*	 * Put the '.' and '..' entries on the head of the sorted list. For	 * normal ASCII, this always happens to be the case, but out of band	 * characters cause this not to be the case sometimes.	 * FIXME(eric) - these tests seem redundant, in that the name is never	 * assigned these values.  It will instead be \000 or \001, and thus	 * should always be sorted correctly.   I need to figure out why I	 * thought I needed this in the first place.	 */#if 0	if (strcmp(rpnt, ".") == 0)		return -1;	if (strcmp(lpnt, ".") == 0)		return 1;	if (strcmp(rpnt, "..") == 0)		return -1;	if (strcmp(lpnt, "..") == 0)		return 1;#else	/*	 * The code above is wrong (as explained in Eric's comment), leading to	 * incorrect sort order iff the -L option ("allow leading dots") is in	 * effect and a directory contains entries that start with a dot.	 *  (TF, Tue Dec 29 13:49:24 CET 1998)	 */	if ((*r)->isorec.name_len[0] == 1 && *rpnt == 0)		return -1;	/* '.' */	if ((*l)->isorec.name_len[0] == 1 && *lpnt == 0)		return 1;	if ((*r)->isorec.name_len[0] == 1 && *rpnt == 1)		return -1;	/* '..' */	if ((*l)->isorec.name_len[0] == 1 && *lpnt == 1)		return 1;#endif	while (*rpnt && *lpnt) {		if (*rpnt == ';' && *lpnt != ';')			return -1;		if (*rpnt != ';' && *lpnt == ';')			return 1;		if (*rpnt == ';' && *lpnt == ';')			return 0;		if (*rpnt == '.' && *lpnt != '.')			return -1;		if (*rpnt != '.' && *lpnt == '.')			return 1;		if ((unsigned char) *rpnt < (unsigned char) *lpnt)			return -1;		if ((unsigned char) *rpnt > (unsigned char) *lpnt)			return 1;		rpnt++;		lpnt++;	}	if (*rpnt)		return 1;	if (*lpnt)		return -1;	return 0;}/* * Function:		sort_directory * * Purpose:		Sort the directory in the appropriate ISO9660 *			order. * * Notes:		Returns 0 if OK, returns > 0 if an error occurred. */intsort_directory(sort_dir, rr)	struct directory_entry **sort_dir;	int		rr;{	int		dcount = 0;	int		xcount = 0;	int		j;	int		i,			len;	struct directory_entry *s_entry;	struct directory_entry **sortlist;	/* need to keep a count of how many entries are hidden */	s_entry = *sort_dir;	while (s_entry) {		if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY)			xcount++;		dcount++;		s_entry = s_entry->next;	}	if (dcount == 0) {		return 0;	}	/* OK, now we know how many there are.  Build a vector for sorting. */	sortlist = (struct directory_entry **)		e_malloc(sizeof(struct directory_entry *) * dcount);	j = dcount - 1;	dcount = 0;	s_entry = *sort_dir;	while (s_entry) {		if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) {			/* put any hidden entries at the end of the vector */			sortlist[j--] = s_entry;		} else {			sortlist[dcount] = s_entry;			dcount++;		}		len = s_entry->isorec.name_len[0];		s_entry->isorec.name[len] = 0;		s_entry = s_entry->next;	}	/* Each directory is required to contain at least . and .. */	if (dcount < 2) {#ifdef	USE_LIBSCHILY		errmsgno(EX_BAD,			"Directory size too small (. or .. missing ???)\n");#else		fprintf(stderr,			"Directory size too small (. or .. missing ???)\n");#endif		sort_goof = 1;	} else {		/* only sort the non-hidden entries */		sort_goof = 0;		is_rr_dir = rr;#ifdef __STDC__		qsort(sortlist, dcount, sizeof(struct directory_entry *),			(int (*) (const void *, const void *)) compare_dirs);#else		qsort(sortlist, dcount, sizeof(struct directory_entry *),			compare_dirs);#endif		/*		 * Now reassemble the linked list in the proper sorted order		 * We still need the hidden entries, as they may be used in		 * the Joliet tree.		 */		for (i = 0; i < dcount + xcount - 1; i++) {			sortlist[i]->next = sortlist[i + 1];		}		sortlist[dcount + xcount - 1]->next = NULL;		*sort_dir = sortlist[0];	}	free(sortlist);	sortlist = NULL;	return sort_goof;}static introot_gen(){	init_fstatbuf();	root_record.length[0] = 1 +			offsetof(struct iso_directory_record, name[0]);	root_record.ext_attr_length[0] = 0;	set_733((char *) root_record.extent, root->extent);	set_733((char *) root_record.size, ISO_ROUND_UP(root->size));	iso9660_date(root_record.date, root_statbuf.st_mtime);	root_record.flags[0] = ISO_DIRECTORY;	root_record.file_unit_size[0] = 0;	root_record.interleave[0] = 0;	set_723(root_record.volume_sequence_number, volume_sequence_number);	root_record.name_len[0] = 1;	return 0;}#ifdef SORTING/*  *	sorts deferred_write entries based on the sort weight */static intcompare_sort(rr, ll)	const void	*rr;	const void	*ll;{	struct deferred_write	**r;	struct deferred_write	**l;	int			r_sort;	int			l_sort;	r = (struct deferred_write **) rr;	l = (struct deferred_write **) ll;	r_sort = (*r)->s_entry->sort;	l_sort = (*l)->s_entry->sort;	if (r_sort != l_sort)		return (r_sort < l_sort ? 1 : -1);	else		return (*r)->extent - (*l)->extent;}/* *	reassign start extents to files that are "hard links" to *	files that may have been sorted */static voidreassign_link_addresses(dpnt)	struct directory	*dpnt;{	struct directory_entry	*s_entry;	struct file_hash	*s_hash;	while (dpnt) {		s_entry = dpnt->contents;		for(s_entry = dpnt->contents; s_entry; s_entry = s_entry->next) {			/* link files have already been given the weight NOT_SORTED */			if (s_entry->sort != NOT_SORTED)				continue;			/* update the start extent */			s_hash = find_hash(s_entry->dev, s_entry->inode);			if (s_hash) {				set_733((char *) s_entry->isorec.extent, s_hash->starting_block);				s_entry->starting_block = s_hash->starting_block;			}		}		if (dpnt->subdir) {			reassign_link_addresses(dpnt->subdir);		}		dpnt = dpnt->next;	}}/* *	sort files in order of the given sort weight */static intsort_file_addresses(){	struct deferred_write	*dwpnt;	struct deferred_write	**sortlist;	struct directory_entry	*s_entry;	int			start_extent;	int			num = 0;	int			i;	/* need to store start extents for linked files */	flush_hash();	/* find out how many files we have */	dwpnt = dw_head;	while (dwpnt) {		num++;		dwpnt = dwpnt->next;	}	/* return if we have none */	if (num == 0) {		return (1);	}	/* save the start extent of the first file */	start_extent = dw_head->extent;	/* set up vector to store entries */	sortlist = (struct deferred_write **)		e_malloc(sizeof(struct deferred_write *) * num);	for (i=0, dwpnt=dw_head; i<num; i++, dwpnt=dwpnt->next)		sortlist[i] = dwpnt;	/* sort the list */#ifdef __STDC__	qsort(sortlist, num, sizeof(struct deferred_write *),		(int (*)(const void *, const void *))compare_sort);#else	qsort(sortlist, num, sizeof(struct deferred_write *), compare_sort);#endif	/* reconstruct the linked list */	for(i=0; i<num-1; i++) {		sortlist[i]->next = sortlist[i+1];	}	sortlist[num-1]->next = NULL;	dw_head = sortlist[0];	free(sortlist);	/* set the new start extents for the sorted list */	for (i=0, dwpnt=dw_head; i<num; i++, dwpnt=dwpnt->next) {		s_entry = dwpnt->s_entry;		dwpnt->extent = s_entry->starting_block = start_extent;		set_733((char *) s_entry->isorec.extent, start_extent);		start_extent += ISO_BLOCKS(s_entry->size);#ifdef DVD_VIDEO		/*		 * Shouldn't this be done for every type of sort? Otherwise		 * we will loose every pad info we add if we sort the files		 */		if (dvd_video) {			start_extent += dwpnt->pad;		}#endif /*DVD_VIDEO*/		/* cache start extents for any linked files */		add_hash(s_entry);	}	return (0);}#endif /* SORTING */static voidassign_file_addresses(dpnt)	struct directory	*dpnt;{	struct directory *finddir;	struct directory_entry *s_entry;	struct file_hash *s_hash;	struct deferred_write *dwpnt;	char		whole_path[PATH_MAX];        char   tempbuf[255];        char   md5result[33];        int    i, j;#ifdef DVD_VIDEO	char		dvd_path[PATH_MAX];	title_set_info_t * title_set_info=NULL;#endif#ifdef DVD_VIDEO	if (dvd_video && (strstr(dpnt->whole_name, "VIDEO_TS") != 0)) {		int	maxlen = strlen(dpnt->whole_name)-8;		if (maxlen > (sizeof(dvd_path)-1))			maxlen = sizeof(dvd_path)-1;		strncpy(dvd_path, dpnt->whole_name, maxlen);		dvd_path[maxlen] = '\0'; #ifdef DEBUG		fprintf(stderr, "Found it the path is %s \n", dvd_path);#endif		title_set_info = DVDGetFileSet(dvd_path);		if (title_set_info == 0) {			dvd_video = 0;			errmsgno(EX_BAD, "Unable to make a DVD-Video image.\n");		}	}#endif /*DVD_VIDEO*/	while (dpnt) {		s_entry = dpnt->contents;		for (s_entry = dpnt->contents; s_entry;						s_entry = s_entry->next) {			/*			 * If we already have an  extent for this entry, then			 * don't assign a new one.  It must have come from a			 * previous session on the disc.  Note that we don't			 * end up scheduling the thing for writing either.			 */			if (isonum_733((unsigned char *)						s_entry->isorec.extent) != 0) {				continue;			}			/*			 * This saves some space if there are symlinks present			 */			s_hash = find_hash(s_entry->dev, s_entry->inode);			if (s_hash) {				if (verbose > 2) {					fprintf(stderr, "Cache hit for '%s%s%s'\n", s_entry->filedir->de_name,						SPATH_SEPARATOR,						s_entry->name);				}				set_733((char *) s_entry->isorec.extent,						s_hash->starting_block);				set_733((char *) s_entry->isorec.size,						s_hash->size);#ifdef SORTING				/* check for non-directory files */				if (do_sort && ((s_entry->isorec.flags[0] & ISO_DIRECTORY) == 0)) {					/* make sure the real file has the highest weighting */					s_hash->de->sort = MAX(s_entry->sort, s_hash->de->sort);					/* flag this as a potential non-sorted file */					s_entry->sort = NOT_SORTED;				}#endif /* SORTING */				continue;			}			/*			 * If this is for a directory that is not a . or			 * a .. entry, then look up the information for the			 * entry.  We have already assigned extents for			 * directories, so we just need to fill in the blanks			 * here.			 */			if (strcmp(s_entry->name, ".") != 0 &&					strcmp(s_entry->name, "..") != 0 &&					s_entry->isorec.flags[0] & ISO_DIRECTORY) {				finddir = dpnt->subdir;				while (1 == 1) {					if (finddir->self == s_entry)						break;					finddir = finddir->next;					if (!finddir) {#ifdef	USE_LIBSCHILY#ifdef	DVD_VIDEO						if (title_set_info != 0) {							DVDFreeFileSet(title_set_info);						}#endif						comerrno(EX_BAD,							"Fatal goof - could not find dir entry for '%s'\n",							s_entry->name);#else						fprintf(stderr,							"Fatal goof - could not find dir entry for '%s'\n",							s_entry->name);#ifdef DVD_VIDEO						if (title_set_info != 0) {							DVDFreeFileSet(title_set_info);						}#endif						exit(1);#endif					}				}				set_733((char *) s_entry->isorec.extent,						finddir->extent);				s_entry->starting_block = finddir->extent;				s_entry->size = ISO_ROUND_UP(finddir->size);				total_dir_size += s_entry->size;				add_hash(s_entry);				set_733((char *) s_entry->isorec.size,						ISO_ROUND_UP(finddir->size));				continue;			}			/*			 * If this is . or .., then look up the relevant info			 * from the tables.			 */			if (strcmp(s_entry->name, ".") == 0) {				set_733((char *) s_entry->isorec.extent,								dpnt->extent);				/*				 * Set these so that the hash table has the				 * correct information				 */				s_entry->starting_block = dpnt->extent;				s_entry->size = ISO_ROUND_UP(dpnt->size);				add_hash(s_entry);				s_entry->starting_block = dpnt->extent;				set_733((char *) s_entry->isorec.size,						ISO_ROUND_UP(dpnt->size));				continue;			}			if (strcmp(s_entry->name, "..") == 0) {				if (dpnt == root) {					total_dir_size += root->size;				}				set_733((char *) s_entry->isorec.extent,							dpnt->parent->extent);				/*				 * Set these so that the hash table has the				 * correct information				 */				s_entry->starting_block = dpnt->parent->extent;				s_entry->size =					ISO_ROUND_UP(dpnt->parent->size);

⌨️ 快捷键说明

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