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

📄 tree.c

📁 一款功能很强的光盘镜象制作工具
💻 C
📖 第 1 页 / 共 5 页
字号:
			nchar = -1;#endif			symlink_buff[nchar < 0 ? 0 : nchar] = 0;			sprintf(buffer, "L\t%s\t%s\n",				s_entry->name, symlink_buff);			break;#endif#ifdef S_IFSOCK		case S_IFSOCK:			sprintf(buffer, "S\t%s\n",				s_entry->name);			break;#endif		case S_IFREG:		default:			sprintf(buffer, "F\t%s\n",				s_entry->name);			break;		};		s_entry->table = strdup(buffer);	}	if (S_ISDIR(statbuf.st_mode)) {		int	dflag;		if (strcmp(short_name, ".") != 0 && strcmp(short_name, "..")									!= 0) {			struct directory *child;			child = find_or_create_directory(this_dir, whole_path,				s_entry, 1);			if (no_scandir)				dflag = 1;			else				dflag = scan_directory_tree(child, whole_path,								s_entry);			if (!dflag) {				lstatbuf.st_mode =					(lstatbuf.st_mode & ~S_IFMT) | S_IFREG;				if (child->contents == NULL) {					delete_directory(this_dir, child);				}			}		}		/* If unable to scan directory, mark this as a non-directory */	}	if (use_RockRidge && this_dir == root && strcmp(s_entry->name, ".")									== 0) {		deep_flag |= NEED_CE | NEED_SP;	/* For extension record */	}	/* Now figure out how much room this file will take in the directory */#ifdef APPLE_HYB	/* if the file is HFS excluded, then we don't have an hfs_ent */	if (apple_both && !have_rsrc && s_entry->hfs_ent) {		if (S_ISREG(lstatbuf.st_mode)) { /* it's a regular file */			/* fill in the rest of the HFS entry */			get_hfs_info(whole_path, short_name, s_entry);			/* if required, set ISO directory name from HFS name */			if (use_mac_name)				iso9660_file_length(s_entry->hfs_ent->name,								s_entry, 0);			/* print details about the HFS file */			if (verbose > 2)				print_hfs_info(s_entry);			/*			 * copy the new ISO9660 name to the rsrc fork			 * - if it exists			 */			if (s_entry->assoc)				strcpy(s_entry->assoc->isorec.name,							s_entry->isorec.name);			/*			 * we can't handle hard links in the hybrid case, so we			 * "uncache" the file. The downside to this is that			 * hard linked files are added to the output image			 * more than once (we've already done this for rsrc			 * files)			 */			if (apple_hyb) {				s_entry->inode = UNCACHED_INODE;				s_entry->dev = (dev_t) UNCACHED_DEVICE;			}		} else if (!(s_entry->isorec.flags[0] & ISO_DIRECTORY)) {			/* not a directory .. */			/*			 * no mac equivalent, so ignore - have to be careful			 * here, the hfs_ent may be also be for a relocated			 * directory			 */			if (s_entry->hfs_ent &&				!(s_entry->de_flags & RELOCATED_DIRECTORY))				free(s_entry->hfs_ent);			s_entry->hfs_ent = NULL;		}		/*		 * 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 = new_dir_mode | 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.		 */		if (parent == NULL || parent->whole_name[0] == '\0')			sts = -1;		else			sts = stat_filter(parent->whole_name, &xstatbuf);		if (debug && parent) {			error("stat parent->whole_name: '%s' -> %d.\n",				parent->whole_name, sts);		}		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) {			/*			 * XXX to prevent this, we would need to add			 * XXX support for RR directory relocation			 * XXX to find_or_create_directory()			 */#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)			u

⌨️ 快捷键说明

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