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

📄 tree.c

📁 创建一个符合iso-9660标准的iso文件系统
💻 C
📖 第 1 页 / 共 5 页
字号:
		/*		 * if the rsrc size is zero, then we don't need the entry, so		 * we might as well delete it - this will only happen if we		 * didn't know the rsrc size from the rsrc file size		 */		if (s_entry->assoc && s_entry->assoc->size == 0)			delete_rsrc_ent(s_entry);	}	if (apple_ext && s_entry->assoc) {		/* need Apple extensions for the resource fork as well */		generate_rock_ridge_attributes(whole_path,			short_name, s_entry->assoc,			&statbuf, &lstatbuf, deep_flag);	}	/* leave out resource fork for the time being */	if (use_RockRidge && !have_rsrc) {#else	if (use_RockRidge) {#endif	/* APPLE_HYB */		generate_rock_ridge_attributes(whole_path,			short_name, s_entry,			&statbuf, &lstatbuf, deep_flag);	}	return 1;}voidgenerate_iso9660_directories(node, outfile)	struct directory	*node;	FILE			*outfile;{	struct directory *dpnt;	dpnt = node;	while (dpnt) {		if (dpnt->extent > session_start) {			generate_one_directory(dpnt, outfile);		}		if (dpnt->subdir)			generate_iso9660_directories(dpnt->subdir, outfile);		dpnt = dpnt->next;	}}/* * Function:	find_or_create_directory * * Purpose:	Locate a directory entry in the tree, create if needed. * * Arguments:	parent & de are never NULL at the same time. */struct directory *find_or_create_directory(parent, path, de, flag)	struct directory	*parent;	const char		*path;	struct directory_entry	*de;	int			flag;{	struct directory *dpnt;	struct directory_entry *orig_de;	struct directory *next_brother;	const char	*cpnt;	const char	*pnt;	orig_de = de;	/*	 * XXX It seems that the tree that has been read from the	 * XXX previous session does not carry whole_name entries.	 * XXX We provide a hack in multi.c:find_or_create_directory()	 * XXX that should be removed when a reasonable method could	 * XXX be found.	 */	if (path == NULL) {		error("Warning: missing whole name for: '%s'\n", de->name);		path = de->name;	}	pnt = strrchr(path, PATH_SEPARATOR);	if (pnt == NULL) {		pnt = path;	} else {		pnt++;	}	if (parent != NULL) {		dpnt = parent->subdir;		while (dpnt) {			/*			 * Weird hack time - if there are two directories by			 * the same name in the reloc_dir, they are not			 * treated as the same thing unless the entire path			 * matches completely.			 */			if (flag && strcmp(dpnt->de_name, pnt) == 0) {				return dpnt;			}			dpnt = dpnt->next;		}	}	/*	 * We don't know if we have a valid directory entry for this one yet.	 * If not, we need to create one.	 */	if (de == NULL) {		de = (struct directory_entry *)			e_malloc(sizeof(struct directory_entry));		memset(de, 0, sizeof(struct directory_entry));		de->next = parent->contents;		parent->contents = de;		de->name = strdup(pnt);		de->whole_name = strdup(path);		de->filedir = parent;		de->isorec.flags[0] = ISO_DIRECTORY;		de->priority = 32768;		de->inode = UNCACHED_INODE;		de->dev = (dev_t) UNCACHED_DEVICE;		set_723(de->isorec.volume_sequence_number,						volume_sequence_number);		iso9660_file_length(pnt, de, 1);		init_fstatbuf();		/*		 * It doesn't exist for real, so we cannot add any Rock Ridge.		 */		if (use_RockRidge) {			fstatbuf.st_mode = 0555 | S_IFDIR;			fstatbuf.st_nlink = 2;			generate_rock_ridge_attributes("",				(char *) pnt, de,				&fstatbuf,				&fstatbuf, 0);		}		iso9660_date(de->isorec.date, fstatbuf.st_mtime);#ifdef APPLE_HYB		if (apple_both) {			/* give the directory an HFS entry */			hfsdirent	*hfs_ent;			hfs_ent = (hfsdirent *) e_malloc(sizeof(hfsdirent));			/* fill in the defaults */			memset(hfs_ent, 0, sizeof(hfsdirent));			hfs_ent->crdate = fstatbuf.st_ctime;			hfs_ent->mddate = fstatbuf.st_mtime;			de->hfs_ent = hfs_ent;			/* get the Mac directory name */			get_hfs_dir((char *) path, (char *) pnt, de);		}#endif	/* APPLE_HYB */	}	/*	 * If we don't have a directory for this one yet, then allocate it now,	 * and patch it into the tree in the appropriate place.	 */	dpnt = (struct directory *) e_malloc(sizeof(struct directory));	memset(dpnt, 0, sizeof(struct directory));	dpnt->next = NULL;	dpnt->subdir = NULL;	dpnt->self = de;	dpnt->contents = NULL;	dpnt->whole_name = strdup(path);	cpnt = strrchr(path, PATH_SEPARATOR);	if (cpnt)		cpnt++;	else		cpnt = path;	dpnt->de_name = strdup(cpnt);	dpnt->size = 0;	dpnt->extent = 0;	dpnt->jextent = 0;	dpnt->jsize = 0;#ifdef APPLE_HYB	dpnt->hfs_ent = de->hfs_ent;#endif	/* APPLE_HYB */	if (orig_de == NULL) {		struct stat	xstatbuf;		int		sts;		/*		 * Now add a . and .. entry in the directory itself. This is a		 * little tricky - if the real directory exists, we need to		 * stat it first. Otherwise, we use the fictitious fstatbuf		 * which points to the time at which mkisofs was started.		 */		sts = stat_filter(parent->whole_name, &xstatbuf);		if (sts == 0) {			attach_dot_entries(dpnt, &xstatbuf);		} else {			attach_dot_entries(dpnt, &fstatbuf);		}	}	if (!parent || parent == root) {		if (!root) {			root = dpnt;	/* First time through for root					   directory only */			root->depth = 0;			root->parent = root;		} else {			dpnt->depth = 1;			if (!root->subdir) {				root->subdir = dpnt;			} else {				next_brother = root->subdir;				while (next_brother->next)					next_brother = next_brother->next;				next_brother->next = dpnt;			}			dpnt->parent = parent;		}	} else {		/* Come through here for  normal traversal of  tree */#ifdef DEBUG		fprintf(stderr, "%s(%d) ", path, dpnt->depth);#endif		if (parent->depth > RR_relocation_depth) {#ifdef	USE_LIBSCHILY			comerrno(EX_BAD,			"Directories too deep for '%s' (%d) max is %d.\n",				path, parent->depth, RR_relocation_depth);#else			fprintf(stderr,			"Directories too deep for '%s' (%d) max is %d.\n",				path, parent->depth, RR_relocation_depth);			exit(1);#endif		}		dpnt->parent = parent;		dpnt->depth = parent->depth + 1;		if (!parent->subdir) {			parent->subdir = dpnt;		} else {			next_brother = parent->subdir;			while (next_brother->next)				next_brother = next_brother->next;			next_brother->next = dpnt;		}	}	return dpnt;}/* * Function:	delete_directory * * Purpose:	Locate a directory entry in the tree, create if needed. * * Arguments: */static voiddelete_directory(parent, child)	struct directory	*parent;	struct directory	*child;{	struct directory *tdir;	if (child->contents != NULL) {#ifdef	USE_LIBSCHILY		comerrno(EX_BAD, "Unable to delete non-empty directory\n");#else		fprintf(stderr, "Unable to delete non-empty directory\n");		exit(1);#endif	}	free(child->whole_name);	child->whole_name = NULL;	free(child->de_name);	child->de_name = NULL;#ifdef APPLE_HYB	if (apple_both && child->hfs_ent)		free(child->hfs_ent);#endif	/* APPLE_HYB */	if (parent->subdir == child) {		parent->subdir = child->next;	} else {		for (tdir = parent->subdir; tdir->next != NULL;							tdir = tdir->next) {			if (tdir->next == child) {				tdir->next = child->next;				break;			}		}		if (tdir == NULL) {#ifdef	USE_LIBSCHILY			comerrno(EX_BAD,			"Unable to locate child directory in parent list\n");#else			fprintf(stderr,			"Unable to locate child directory in parent list\n");			exit(1);#endif		}	}	free(child);	return;}intsort_tree(node)	struct directory	*node;{	struct directory *dpnt;	int		ret = 0;	dpnt = node;	while (dpnt) {		ret = sort_n_finish(dpnt);		if (ret) {			break;		}		if (dpnt->subdir)			sort_tree(dpnt->subdir);		dpnt = dpnt->next;	}	return ret;}voiddump_tree(node)	struct directory *node;{	struct directory *dpnt;	dpnt = node;	while (dpnt) {		fprintf(stderr, "%4d %5d %s\n",				dpnt->extent, dpnt->size, dpnt->de_name);		if (dpnt->subdir)			dump_tree(dpnt->subdir);		dpnt = dpnt->next;	}}voidupdate_nlink_field(node)	struct directory *node;{	struct directory *dpnt;	struct directory *xpnt;	struct directory_entry *s_entry;	int		i;	dpnt = node;	while (dpnt) {		if (dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) {			dpnt = dpnt->next;			continue;		}		/*		 * First, count up the number of subdirectories this guy has.		 */		for (i = 0, xpnt = dpnt->subdir; xpnt; xpnt = xpnt->next)			if ((xpnt->dir_flags & INHIBIT_ISO9660_ENTRY) == 0)				i++;		/*		 * Next check to see if we have any relocated directories in		 * this directory. The nlink field will include these as		 * real directories when they are properly relocated.			 * In the non-rockridge disk, the relocated entries appear as		 * zero length files.		 */		for (s_entry = dpnt->contents; s_entry;						s_entry = s_entry->next) {			if ((s_entry->de_flags & RELOCATED_DIRECTORY) != 0 &&				(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) ==									 0) {				i++;			}		}		/* Now update the field in the Rock Ridge entry. */		update_nlink(dpnt->self, i + 2);		/* Update the '.' entry for this directory. */		update_nlink(dpnt->contents, i + 2);		/* Update all of the '..' entries that point to this guy. */		for (xpnt = dpnt->subdir; xpnt; xpnt = xpnt->next)			update_nlink(xpnt->contents->next, i + 2);		if (dpnt->subdir)			update_nlink_field(dpnt->subdir);		dpnt = dpnt->next;	}}/* * something quick and dirty to locate a file given a path * recursively walks down path in filename until it finds the * directory entry for the desired file */struct directory_entry *search_tree_file(node, filename)	struct directory *node;	char		*filename;{	struct directory_entry *depnt;	struct directory *dpnt;	char		*p1;	char		*rest;	char		*subdir;	/* strip off next directory name from filename */	subdir = strdup(filename);	if ((p1 = strchr(subdir, '/')) == subdir) {		fprintf(stderr,		"call to search_tree_file with an absolute path, stripping\n");		fprintf(stderr,		"initial path separator. Hope this was intended...\n");		memmove(subdir, subdir + 1, strlen(subdir) - 1);		p1 = strchr(subdir, '/');	}	/* do we need to find a subdirectory */	if (p1) {		*p1 = '\0';#ifdef DEBUG_TORITO		fprintf(stderr, "Looking for subdir called %s\n", p1);#endif		rest = p1 + 1;#ifdef DEBUG_TORITO		fprintf(stderr, "Remainder of path name is now %s\n", rest);#endif		dpnt = node->subdir;		while (dpnt) {#ifdef DEBUG_TORITO			fprintf(stderr,				"%4d %5d %s\n", dpnt->extent, dpnt->size,				dpnt->de_name);#endif			if (!strcmp(subdir, dpnt->de_name)) {#ifdef DEBUG_TORITO				fprintf(stderr,				"Calling next level with filename = %s", rest);#endif				return (search_tree_file(dpnt, rest));			}			dpnt = dpnt->next;		}		/* if we got here means we couldnt find the subdir */		return (NULL);	} else {		/* look for a normal file now */		depnt = node->contents;		while (depnt) {#ifdef DEBUG_TORITO			fprintf(stderr, "%4d %5d %s\n", depnt->isorec.extent,				depnt->size, depnt->name);#endif			if (!strcmp(filename, depnt->name)) {#ifdef DEBUG_TORITO				fprintf(stderr, "Found our file %s", filename);#endif				return (depnt);			}			depnt = depnt->next;		}		/* if we got here means we couldnt find the subdir */		return (NULL);	}#ifdef	ERIC_FUN	fprintf(stderr, "We cant get here in search_tree_file :-/ \n");#endif}voidinit_fstatbuf(){	time_t	current_time;	if (fstatbuf.st_ctime == 0) {		time(&current_time);		if (rationalize) {			fstatbuf.st_uid = 0;			fstatbuf.st_gid = 0;		} else {			fstatbuf.st_uid = getuid();			fstatbuf.st_gid = getgid();		}		fstatbuf.st_ctime = current_time;		fstatbuf.st_mtime = current_time;		fstatbuf.st_atime = current_time;	}}

⌨️ 快捷键说明

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