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

📄 write.c

📁 一款功能很强的光盘镜象制作工具
💻 C
📖 第 1 页 / 共 5 页
字号:
				add_hash(s_entry);				s_entry->starting_block = dpnt->parent->extent;				set_733((char *) s_entry->isorec.size,					ISO_ROUND_UP(dpnt->parent->size));				continue;			}            if ((use_Md5Opt) && (s_entry->whole_name != NULL))            {               /* calc the MD5 hash value */               memset(md5result,0,33);               if (s_entry->size && MD5File(md5result,s_entry->whole_name))               {                  // md5 calc ok,  make hash key                      struct directory_entry *hash_result;                  sprintf(tempbuf,"%d%s",s_entry->size,md5result);#define WR_SHOWF#ifdef WR_SHOWF                      if (showcount <=0)                         fprintf(stderr, "Scanning the Source files: (using MD5 Technology!)\n");                      showcount ++;                      fprintf(stderr, "\r[%05d]%.72s", showcount, s_entry->whole_name);                 //   printf("\r[%05d]%.73s", showcount, s_entry->whole_name);                      i = 1; j = 73 - strlen(s_entry->whole_name);
                      while (i < j)
                      {
                        fprintf (stderr," ");                 //     printf (" ");
                        i++;
                        }
#endif/* #define WR_DEBUG */#ifdef WR_DEBUG                  // debug enable, check detail if size is 377 or 7238
                  if ((s_entry->size != 377) || (s_entry->size == 7238))                    {
                      fprintf(stderr, "\nFile=%s \nSize=%d \nMd5s=", 
                              s_entry->whole_name,s_entry->size);                    
                      fprintf (stderr,"%s\n", md5result); 
                                               }                                                              #endif /* !WR_DEBUG */                                                    hash_result = (struct directory_entry *)htInTable(md5_hash,tempbuf);                  if (!hash_result)                  {                     htAddToTable(md5_hash,tempbuf,(void *) s_entry);                  }                   else                  {                     // found a matching md5 hash! using the duplicate file                     set_733((char *) s_entry->isorec.extent, hash_result->starting_block);                     set_733((char *) s_entry->isorec.size, hash_result->size);                       continue;                                   }                }             } 			/*			 * Some ordinary non-directory file.  Just schedule			 * the file to be written.  This is all quite			 * straightforward, just make a list and assign			 * extents as we go.  Once we get through writing all			 * of the directories, we should be ready write out			 * these files			 */			if (s_entry->size) {				dwpnt = (struct deferred_write *)					e_malloc(sizeof(struct deferred_write));				/* save this directory entry for later use */				dwpnt->s_entry = s_entry;				/* set the initial padding to zero */				dwpnt->pad = 0;#ifdef DVD_VIDEO				if (dvd_video && (title_set_info != 0)) {					dwpnt->pad = DVDGetFilePad(title_set_info, s_entry->name);#ifdef DEBUG					fprintf(stderr, "The pad was %d for file %s\n", dwpnt->pad, s_entry->name);#endif				}#endif /*DVD_VIDEO*/#ifdef APPLE_HYB				/*				 * maybe an offset to start of the real				 * file/fork				 */				dwpnt->off = s_entry->hfs_off;#else				dwpnt->off = (off_t)0;#endif	/* APPLE_HYB */				if (dw_tail) {					dw_tail->next = dwpnt;					dw_tail = dwpnt;				} else {					dw_head = dwpnt;					dw_tail = dwpnt;				}				if (s_entry->inode == TABLE_INODE) {					dwpnt->table = s_entry->table;					dwpnt->name = NULL;					sprintf(whole_path, "%s%s%s",						s_entry->filedir->whole_name,						SPATH_SEPARATOR, trans_tbl);				} else {					dwpnt->table = NULL;					strcpy(whole_path,							s_entry->whole_name);					dwpnt->name = strdup(whole_path);				}				dwpnt->next = NULL;				dwpnt->size = s_entry->size;				dwpnt->extent = last_extent;				set_733((char *) s_entry->isorec.extent,								last_extent);				s_entry->starting_block = last_extent;				add_hash(s_entry);				last_extent += ISO_BLOCKS(s_entry->size);#ifdef DVD_VIDEO				/* Shouldn't we always add the pad info? */				if (dvd_video) {					last_extent += dwpnt->pad;				}#endif /*DVD_VIDEO*/				if (verbose > 2) {					fprintf(stderr, "%d %d %s\n",						s_entry->starting_block,						last_extent - 1, whole_path);				}#ifdef DBG_ISO				if (ISO_BLOCKS(s_entry->size) > 500) {					fprintf(stderr,						"Warning: large file '%s'\n",						whole_path);					fprintf(stderr,						"Starting block is %d\n",						s_entry->starting_block);					fprintf(stderr,					"Reported file size is %d extents\n",						s_entry->size);				}#endif#ifdef	NOT_NEEDED	/* Never use this code if you like to create a DVD */				if (last_extent > (800000000 >> 11)) {					/* More than 800Mb? Punt */					fprintf(stderr,					"Extent overflow processing file '%s'\n",						 whole_path);					fprintf(stderr,						"Starting block is %d\n",						s_entry->starting_block);					fprintf(stderr,					"Reported file size is %d extents\n",								s_entry->size);					exit(1);				}#endif				continue;			}			/*			 * This is for zero-length files.  If we leave the			 * extent 0, then we get screwed, because many readers			 * simply drop files that have an extent of zero.			 * Thus we leave the size 0, and just assign the			 * extent number.			 */			set_733((char *) s_entry->isorec.extent, last_extent);		}		if (dpnt->subdir) {			assign_file_addresses(dpnt->subdir);		}		dpnt = dpnt->next;	}#ifdef DVD_VIDEO	if (title_set_info != NULL) {		DVDFreeFileSet(title_set_info);	}#endif /*DVD_VIDEO*/}/* assign_file_addresses(... */static voidfree_one_directory(dpnt)	struct directory	*dpnt;{	struct directory_entry *s_entry;	struct directory_entry *s_entry_d;	s_entry = dpnt->contents;	while (s_entry) {		s_entry_d = s_entry;		s_entry = s_entry->next;		if (s_entry_d->rr_attributes) {			free(s_entry_d->rr_attributes);			s_entry_d->rr_attributes = NULL;		}		if (s_entry_d->name != NULL) {			free(s_entry_d->name);			s_entry_d->name = NULL;		}		if (s_entry_d->whole_name != NULL) {			free(s_entry_d->whole_name);			s_entry_d->whole_name = NULL;		}#ifdef APPLE_HYB		if (apple_both && s_entry_d->hfs_ent && !s_entry_d->assoc)			free(s_entry_d->hfs_ent);#endif	/* APPLE_HYB */		free(s_entry_d);		s_entry_d = NULL;	}	dpnt->contents = NULL;}/* free_one_directory(... */static voidfree_directories(dpnt)	struct directory	*dpnt;{	while (dpnt) {		free_one_directory(dpnt);		if (dpnt->subdir)			free_directories(dpnt->subdir);		dpnt = dpnt->next;	}}voidgenerate_one_directory(dpnt, outfile)	struct directory	*dpnt;	FILE			*outfile;{	unsigned int	ce_address = 0;	char		*ce_buffer;	unsigned int	ce_index = 0;	unsigned int	ce_size;	unsigned int	dir_index;	char		*directory_buffer;	int		new_reclen;	struct directory_entry *s_entry;	struct directory_entry *s_entry_d;	unsigned int	total_size;	total_size = ISO_ROUND_UP(dpnt->size);	directory_buffer = (char *) e_malloc(total_size);	memset(directory_buffer, 0, total_size);	dir_index = 0;	ce_size = ISO_ROUND_UP(dpnt->ce_bytes);	ce_buffer = NULL;	if (ce_size > 0) {		ce_buffer = (char *) e_malloc(ce_size);		memset(ce_buffer, 0, ce_size);		ce_index = 0;		/* Absolute byte address of CE entries for this directory */		ce_address = last_extent_written + (total_size >> 11);		ce_address = ce_address << 11;	}	s_entry = dpnt->contents;	while (s_entry) {		/* skip if it's hidden */		if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) {			s_entry = s_entry->next;			continue;		}		/*		 * We do not allow directory entries to cross sector		 * boundaries. Simply pad, and then start the next entry at		 * the next sector		 */		new_reclen = s_entry->isorec.length[0];		if ((dir_index & (SECTOR_SIZE - 1)) + new_reclen >=								SECTOR_SIZE) {			dir_index = ISO_ROUND_UP(dir_index);		}		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	 */	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;		if (dpnt->parent->path_index > 0xffff) {#ifdef	USE_LIBSCHILY			comerrno(EX_BAD,			"Unable to generate sane path tables - too many directories (%d)\n",

⌨️ 快捷键说明

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