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

📄 multi.c

📁 创建一个符合iso-9660标准的iso文件系统
💻 C
📖 第 1 页 / 共 3 页
字号:
		pnt[i]->next = this_dir->contents;		pnt[i]->filedir = this_dir;		this_dir->contents = pnt[i];		pnt[i] = NULL;	}	/*	 * If we don't have an entry for the translation table, then don't	 * bother trying to copy the starting extent over. Note that it is	 * possible that if we are copying the entire directory, the entry for	 * the translation table will have already been inserted into the	 * linked list and removed from the old entries list, in which case we	 * want to leave the extent number as it was before.	 */	if (ttbl_extent == 0) {		return;	}	/*	 * Finally, check the directory we are creating to see whether there	 * are any new entries in it.  If there are not, we can reuse the same	 * translation table.	 */	for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) {		/*		 * Don't care about '.' or '..'.  They are never in the table		 * anyways.		 */		if (s_entry->name != NULL && strcmp(s_entry->name, ".") == 0) {			continue;		}		if (s_entry->name != NULL && strcmp(s_entry->name, "..") == 0) {			continue;		}/*		if( strcmp(s_entry->name, "<translation table>") == 0)*/		if (strcmp(s_entry->name, trans_tbl) == 0) {			continue;		}		if ((s_entry->de_flags & SAFE_TO_REUSE_TABLE_ENTRY) == 0) {			return;		}	}	/*	 * Locate the translation table, and re-use the same extent. It isn't	 * clear that there should ever be one in there already so for now we	 * try and muddle through the best we can.	 */	for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) {/*      	if( strcmp(s_entry->name, "<translation table>") == 0)*/		if (strcmp(s_entry->name, trans_tbl) == 0) {			fprintf(stderr, "Should never get here\n");			set_733(s_entry->isorec.extent, ttbl_extent);			return;		}	}	pnt[ttbl_index]->next = this_dir->contents;	pnt[ttbl_index]->filedir = this_dir;	this_dir->contents = pnt[ttbl_index];	pnt[ttbl_index] = NULL;}/* * Here we have a case of a directory that has completely disappeared from * the face of the earth on the tree we are mastering from.  Go through and * merge it into the tree, as well as everything beneath it. * * Note that if a directory has been moved for some reason, this will * incorrectly pick it up and attempt to merge it back into the old * location.  FIXME(eric). */static intmerge_old_directory_into_tree(dpnt, parent)	struct directory_entry	*dpnt;	struct directory *parent;{	struct directory_entry **contents = NULL;	int		i;	int		n_orig;	struct directory *this_dir,			*next_brother;	char		whole_path[1024];	this_dir = (struct directory *) e_malloc(sizeof(struct directory));	memset(this_dir, 0, sizeof(struct directory));	this_dir->next = NULL;	this_dir->subdir = NULL;	this_dir->self = dpnt;	this_dir->contents = NULL;	this_dir->size = 0;	this_dir->extent = 0;	this_dir->depth = parent->depth + 1;	this_dir->parent = parent;	if (!parent->subdir)		parent->subdir = this_dir;	else {		next_brother = parent->subdir;		while (next_brother->next)			next_brother = next_brother->next;		next_brother->next = this_dir;	}	/* Set the name for this directory. */	strcpy(whole_path, parent->de_name);	strcat(whole_path, SPATH_SEPARATOR);	strcat(whole_path, dpnt->name);	this_dir->de_name = strdup(whole_path);	this_dir->whole_name = strdup(whole_path);	/*	 * Now fill this directory using information from the previous session.	 */	contents = read_merging_directory(&dpnt->isorec, &n_orig);	/*	 * Start by simply copying the '.', '..' and non-directory entries to	 * this directory.  Technically we could let merge_remaining_entries	 * handle this, but it gets rather confused by the '.' and '..' entries	 */	for (i = 0; i < n_orig; i++) {		/*		 * We can always reuse the TRANS.TBL in this particular case.		 */		contents[i]->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY;		if (((contents[i]->isorec.flags[0] & ISO_DIRECTORY) != 0)			&& (i >= 2)) {			continue;		}		/* If we have a directory, don't reuse the extent number. */		if ((contents[i]->isorec.flags[0] & ISO_DIRECTORY) != 0) {			memset(contents[i]->isorec.extent, 0, 8);			if (strcmp(contents[i]->name, ".") == 0)				this_dir->dir_flags |= DIR_HAS_DOT;			if (strcmp(contents[i]->name, "..") == 0)				this_dir->dir_flags |= DIR_HAS_DOTDOT;		}		/*		 * for regilar files, we do it here.		 * If it has CL or RE attributes, remember its extent		 */		check_rr_relocation(contents[i]); 		/*		 * Set the whole name for this file.		 */		strcpy(whole_path, this_dir->whole_name);		strcat(whole_path, SPATH_SEPARATOR);		strcat(whole_path, contents[i]->name);		contents[i]->whole_name = strdup(whole_path);		contents[i]->next = this_dir->contents;		contents[i]->filedir = this_dir;		this_dir->contents = contents[i];		contents[i] = NULL;	}	/*	 * and for directories, we do it here.	 * If it has CL or RE attributes, remember its extent	 */	check_rr_relocation(dpnt);	/*	 * Zero the extent number for ourselves.	 */	memset(dpnt->isorec.extent, 0, 8);	/*	 * Anything that is left are other subdirectories that need to be	 * merged.	 */	merge_remaining_entries(this_dir, contents, n_orig);	free_mdinfo(contents, n_orig);#if 0	/*	 * This is no longer required.  The post-scan sort will handle all of	 * this for us.	 */	sort_n_finish(this_dir);#endif	return 0;}char           *cdrecord_data = NULL;intget_session_start(file_addr)	int		*file_addr;{	char		*pnt;#ifdef CDRECORD_DETERMINES_FIRST_WRITABLE_ADDRESS	/*	 * FIXME(eric).  We need to coordinate with cdrecord to obtain the	 * parameters.  For now, we assume we are writing the 2nd session, so	 * we start from the session that starts at 0.	 */	*file_addr = (16 << 11);	/*	 * We need to coordinate with cdrecord to get the next writable address	 * from the device.  Here is where we use it.	 */	session_start = last_extent = last_extent_written = cdrecord_result();#else	if (cdrecord_data == NULL) {#ifdef	USE_LIBSCHILY		comerrno(EX_BAD,		    "Special parameters for cdrecord not specified with -C\n");#else		fprintf(stderr,		    "Special parameters for cdrecord not specified with -C\n");		exit(1);#endif	}	/*	 * Next try and find the ',' in there which delimits the two numbers.	 */	pnt = strchr(cdrecord_data, ',');	if (pnt == NULL) {#ifdef	USE_LIBSCHILY		comerrno(EX_BAD, "Malformed cdrecord parameters\n");#else		fprintf(stderr, "Malformed cdrecord parameters\n");		exit(1);#endif	}	*pnt = '\0';	if (file_addr != NULL) {		*file_addr = atol(cdrecord_data) * SECTOR_SIZE;	}	pnt++;	session_start = last_extent = last_extent_written = atol(pnt);	pnt--;	*pnt = ',';#endif	return 0;}/* * This function scans the directory tree, looking for files, and it makes * note of everything that is found.  We also begin to construct the ISO9660 * directory entries, so that we can determine how large each directory is. */intmerge_previous_session(this_dir, mrootp)	struct directory *this_dir;	struct iso_directory_record *mrootp;{	struct directory_entry **orig_contents = NULL;	struct directory_entry *odpnt = NULL;	int		n_orig;	struct directory_entry *s_entry;	int		status;	int		lstatus;	struct stat     statbuf,			lstatbuf;	int		retcode;	/*	 * Parse the same directory in the image that we are merging for	 * multisession stuff.	 */	orig_contents = read_merging_directory(mrootp, &n_orig);	if (orig_contents == NULL) {		return (0);	}	/*	 * Now we scan the directory itself, and look at what is inside of it.	 */	for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) {		status = stat_filter(s_entry->whole_name, &statbuf);		lstatus = lstat_filter(s_entry->whole_name, &lstatbuf);		/*		 * We always should create an entirely new directory tree		 * whenever we generate a new session, unless there were		 * *no* changes whatsoever to any of the directories, in which		 * case it would be kind of pointless to generate a new		 * session.		 * I believe it is possible to rigorously prove that any change		 * anywhere in the filesystem will force the entire tree to be		 * regenerated because the modified directory will get a new		 * extent number.  Since each subdirectory of the changed		 * directory has a '..' entry, all of them will need to be		 * rewritten too, and since the parent directory of the		 * modified directory will have an extent pointer to the	   	 * directory it too will need to be rewritten.  Thus we will		 * never be able to reuse any directory information when		 * writing new sessions.		 *		 * We still check the previous session so we can mark off the		 * equivalent entry in the list we got from the original disc,		 * however.		 */		/*		 * The check_prev_session function looks for an identical		 * entry in the previous session.  If we see it, then we copy		 * the extent number to s_entry, and cross it off the list.		 * It returns 2 if it's a directory		 */		retcode = check_prev_session(orig_contents, n_orig, s_entry,			&statbuf, &lstatbuf, &odpnt);		if (retcode == -1)			return (-1);		if (retcode == 2 && odpnt != NULL) {			int             dflag;			if (strcmp(s_entry->name, ".") != 0 &&					strcmp(s_entry->name, "..") != 0) {				struct directory *child;				/*				 * XXX It seems that the tree that has been				 * XXX read from the previous session does not				 * XXX carry whole_name entries. We provide a				 * XXX hack in				 * XXX multi.c:find_or_create_directory()				 * XXX that should be removed when a				 * XXX reasonable method could be found.				 */				child = find_or_create_directory(this_dir,					s_entry->whole_name,					s_entry, 1);				dflag = merge_previous_session(child,					&odpnt->isorec);				if (dflag == -1) {					return (-1);				}				free(odpnt);				odpnt = NULL;			}		}	}	/*	 * Whatever is left over, are things which are no longer in the tree on	 * disk. We need to also merge these into the tree.	 */	merge_remaining_entries(this_dir, orig_contents, n_orig);	free_mdinfo(orig_contents, n_orig);	return (1);}/* * This code deals with relocated directories which may exist  * in the previous session.  */struct dir_extent_link  {	unsigned int		extent;	struct directory_entry	*de;	struct dir_extent_link	*next;};static struct dir_extent_link	*cl_dirs = NULL;static struct dir_extent_link	*re_dirs = NULL;static voidcheck_rr_relocation(de)	struct directory_entry *de;{	unsigned char   sector[SECTOR_SIZE];	unsigned char  *pnt = de->rr_attributes;		 int    len = de->rr_attr_size;	int             cont_extent = 0,	                cont_offset = 0,	                cont_size = 0;	pnt = parse_xa(pnt, &len, /*dpnt*/ 0);	while (len >= 4) {		if (pnt[3] != 1 && pnt[3] != 2) {#ifdef USE_LIBSCHILY			errmsgno(EX_BAD, "**BAD RRVERSION (%d) for %c%c\n", pnt[3], pnt[0], pnt[1]);#else			fprintf(stderr, "**BAD RRVERSION (%d) for %c%c\n", pnt[3], pnt[0], pnt[1]);#endif		}		if (strncmp((char *) pnt, "CL", 2) == 0) {			struct dir_extent_link *dlink = e_malloc(sizeof(*dlink));			dlink->extent = isonum_733(pnt + 4);			dlink->de = de;			dlink->next = cl_dirs;			cl_dirs = dlink;		} else if (strncmp((char *) pnt, "RE", 2) == 0) {			struct dir_extent_link *dlink = e_malloc(sizeof(*dlink));			dlink->extent = de->starting_block;			dlink->de = de;			dlink->next = re_dirs;			re_dirs = dlink;		} else if (strncmp((char *) pnt, "CE", 2) == 0) {			cont_extent = isonum_733(pnt + 4);			cont_offset = isonum_733(pnt + 12);			cont_size = isonum_733(pnt + 20);		} else if (strncmp((char *) pnt, "ST", 2) == 0) {			len = pnt[2];		}		len -= pnt[2];		pnt += pnt[2];		if (len <= 3 && cont_extent) {			/* ??? What if cont_offset+cont_size > SECTOR_SIZE */			readsecs(cont_extent, sector, 1);			pnt = sector + cont_offset;			len = cont_size;			cont_extent = cont_offset = cont_size = 0;		}	}}voidmatch_cl_re_entries(){	struct dir_extent_link *re = re_dirs;	/* for each relocated directory */	for (; re; re = re->next) {		struct dir_extent_link *cl = cl_dirs;		for (; cl; cl = cl->next) {			/* find a place where it was relocated from */			if (cl->extent == re->extent) {				/* set link to that place */				re->de->parent_rec = cl->de;				re->de->filedir = cl->de->filedir;				/*				 * see if it is in rr_moved				 */				if (reloc_dir != NULL) {					struct directory_entry *rr_moved_e = reloc_dir->contents;					for (; rr_moved_e; rr_moved_e = rr_moved_e->next) {						/* yes it is */						if (re->de == rr_moved_e) {							/* forget it */							re->de = NULL;						}					}				}				break;			}		}	}}voidfinish_cl_pl_for_prev_session(){	struct dir_extent_link *re = re_dirs;	/* for those that were relocated, but NOT to rr_moved */	re = re_dirs;	for (; re; re = re->next) {		if (re->de != NULL) {			/*			 * here we have hypothetical case when previous session			 * was not created by mkisofs and contains relocations			 */			struct directory_entry *s_entry = re->de;			struct directory_entry *s_entry1;			struct directory *d_entry = reloc_dir->subdir;			/* do the same as finish_cl_pl_entries */			if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) {				continue;			}			while (d_entry) {				if (d_entry->self == s_entry)					break;				d_entry = d_entry->next;			};			if (!d_entry) {#ifdef USE_LIBSCHILY				comerrno(EX_BAD, "Unable to locate directory parent\n");#else				fprintf(stderr, "Unable to locate directory parent\n");				exit(1);#endif			};			if (s_entry->filedir != NULL && s_entry->parent_rec != NULL) {				char           *rr_attr;				/*				 * First fix the PL pointer in the directory in the				 * rr_reloc dir				 */				s_entry1 = d_entry->contents->next;				rr_attr = find_rr_attribute(s_entry1->rr_attributes,					s_entry1->total_rr_attr_size, "PL");				if (rr_attr != NULL)					set_733(rr_attr + 4, s_entry->filedir->extent);				/* Now fix the CL pointer */				s_entry1 = s_entry->parent_rec;				rr_attr = find_rr_attribute(s_entry1->rr_attributes,					s_entry1->total_rr_attr_size, "CL");				if (rr_attr != NULL)					set_733(rr_attr + 4, d_entry->extent);			}		}	}	/* free memory */	re = re_dirs;	while (re) {		struct dir_extent_link *next = re->next;		free(re);		re = next;	}	re = cl_dirs;	while (re) {		struct dir_extent_link *next = re->next;		free(re);		re = next;	}}

⌨️ 快捷键说明

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