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

📄 tree.c

📁 一款功能很强的光盘镜象制作工具
💻 C
📖 第 1 页 / 共 5 页
字号:
/* @(#)tree.c	1.68 02/11/22 joerg */#ifndef lintstatic	char sccsid[] =	"@(#)tree.c	1.68 02/11/22 joerg";#endif/* * File tree.c - scan directory  tree and build memory structures for iso9660 * filesystem   Written by Eric Youngdale (1993).   Copyright 1993 Yggdrasil Computing, Incorporated   Copyright (c) 1999,2000,2001 J. Schilling   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2, or (at your option)   any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  *//* ADD_FILES changes made by Ross Biro biro@yggdrasil.com 2/23/95 *//* APPLE_HYB James Pearson j.pearson@ge.ucl.ac.uk 23/2/2000 */#include <mconfig.h>#include "mkisofs.h"#include "match.h"#include "exclude.h"#include <timedefs.h>#include <errno.h>#include <fctldefs.h>#include <device.h>#include <schily.h>#ifdef UDF#include "udf.h"#endif#ifdef VMS#include <sys/file.h>#include <vms/fabdef.h>#include "vms.h"extern char	*strdup	__PR((const char *));#endif/* * Autoconf should be able to figure this one out for us and let us know * whether the system has memmove or not. */#ifndef HAVE_MEMMOVE#define memmove(d, s, n) bcopy ((s), (d), (n))#endif#ifdef __SVR4extern char	*strdup	__PR((const char *));#endifstatic unsigned char symlink_buff[PATH_MAX+1];static	char	*filetype		__PR((int t));static	char	*rstr			__PR((char *s1, char *s2));static	void	stat_fix		__PR((struct stat * st));	int	stat_filter		__PR((char *path, struct stat *st));	int	lstat_filter		__PR((char *path, struct stat *st));static	int	sort_n_finish		__PR((struct directory *this_dir));static	void	generate_reloc_directory __PR((void));static	void	attach_dot_entries	__PR((struct directory * dirnode,						struct stat * parent_stat));static	void	update_nlink		__PR((struct directory_entry *s_entry,						int value));static	void	increment_nlink		__PR((struct directory_entry *s_entry));	char	*find_rr_attribute	__PR((unsigned char *pnt, int len,						char *attr_type));	void	finish_cl_pl_entries	__PR((void));	int	scan_directory_tree	__PR((struct directory *this_dir,						char *path,						struct directory_entry *de));#ifdef APPLE_HYB	int	insert_file_entry	__PR((struct directory *this_dir,						char *whole_path,						char *short_name,						int have_rsrc));#else	int	insert_file_entry	__PR((struct directory *this_dir,						char *whole_path,						char *short_name));#endif	void	generate_iso9660_directories __PR((struct directory *node,						FILE *outfile));struct directory *find_or_create_directory __PR((struct directory *parent,						const char *path,						struct directory_entry *de,						int flag));static	void	delete_directory	__PR((struct directory * parent,						struct directory * child));	int	sort_tree		__PR((struct directory *node));	void	dump_tree		__PR((struct directory *node));	void	update_nlink_field	__PR((struct directory *node));struct directory_entry *search_tree_file __PR((struct directory *node,						char *filename));	void	init_fstatbuf		__PR((void));extern int	verbose;struct stat	fstatbuf;		/* We use this for the artificial						entries we create */struct stat	root_statbuf;		/* Stat buffer for root directory */struct directory *reloc_dir;static char *filetype(t)	int	t;{	static	char	unkn[32];	if (S_ISFIFO(t))		/* 1 */		return ("fifo");	if (S_ISCHR(t))			/* 2 */		return ("chr");	if (S_ISMPC(t))			/* 3 */		return ("multiplexed chr");	if (S_ISDIR(t))			/* 4 */		return ("dir");	if (S_ISNAM(t))			/* 5 */		return ("named file");	if (S_ISBLK(t))			/* 6 */		return ("blk");	if (S_ISMPB(t))			/* 7 */		return ("multiplexed blk");	if (S_ISREG(t))			/* 8 */		return ("regular file");	if (S_ISCNT(t))			/* 9 */		return ("contiguous file");	if (S_ISLNK(t))			/* 10 */		return ("symlink");	if (S_ISSHAD(t))		/* 11 */		return ("Solaris shadow inode");	if (S_ISSOCK(t))		/* 12 */		return ("socket");	if (S_ISDOOR(t))		/* 13 */		return ("door");	if (S_ISWHT(t))			/* 14 */		return ("whiteout");	if (S_ISEVC(t))			/* 15 */		return ("event count");	/*	 * Needs to be last in case somebody makes this	 * a supported file type.	 */	if ((t & S_IFMT) == 0)		/* 0 (unallocated) */		return ("unallocated");	sprintf(unkn, "octal '%o'", t & S_IFMT);	return (unkn);}/* * Check if s1 ends in strings s2 */static char *rstr(s1, s2)	char	*s1;	char	*s2;{	int	l1;	int	l2;	l1 = strlen(s1);	l2 = strlen(s2);	if (l2 > l1)		return ((char *) NULL);	if (strcmp(&s1[l1 - l2], s2) == 0)		return (&s1[l1 - l2]);	return ((char *) NULL);}static voidstat_fix(st)	struct stat	*st;{	int adjust_modes = 0;	if (S_ISREG(st->st_mode))		adjust_modes = rationalize_filemode;	else if (S_ISDIR(st->st_mode))		adjust_modes = rationalize_dirmode;	else		adjust_modes = (rationalize_filemode || rationalize_dirmode);	/*	 * If rationalizing, override the uid and gid, since the	 * originals will only be useful on the author's system.	 */	if (rationalize_uid)		st->st_uid = uid_to_use;	if (rationalize_gid)		st->st_gid = gid_to_use;	if (adjust_modes) {		if (S_ISREG(st->st_mode) && (filemode_to_use != 0)) {			st->st_mode = filemode_to_use | S_IFREG;		} else if (S_ISDIR(st->st_mode) && (dirmode_to_use != 0)) {			st->st_mode = dirmode_to_use | S_IFDIR;		} else {			/*			 * Make sure the file modes make sense.  Turn			 * on all read bits.  Turn on all exec/search			 * bits if any exec/search bit is set.  Turn			 * off all write bits, and all special mode			 * bits (on a r/o fs lock bits are useless,			 * and with uid+gid 0 don't want set-id bits,			 * either).			 */			st->st_mode |= 0444;#ifndef _WIN32	/* make all file "executable" */			if (st->st_mode & 0111)#endif	/* _WIN32 */				st->st_mode |= 0111;			st->st_mode &= ~07222;		}	}}intstat_filter(path, st)	char		*path;	struct stat	*st;{	int	result = stat(path, st);	if (result >= 0 && rationalize)		stat_fix(st);	return result;}intlstat_filter(path, st)	char		*path;	struct stat	*st;{	int	result = lstat(path, st);	if (result >= 0 && rationalize)		stat_fix(st);	return result;}static intsort_n_finish(this_dir)	struct directory	*this_dir;{	struct directory_entry *s_entry;	struct directory_entry *s_entry1;	struct directory_entry *table;	int		count;	int		d1;	int		d2;	int		d3;	int		new_reclen;	char		*c;	int		status = 0;	int		tablesize = 0;	char		newname[MAX_ISONAME+1];	char		rootname[MAX_ISONAME+1];	char		extname[MAX_ISONAME+1];	/*	 * Here we can take the opportunity to toss duplicate entries from the	 * directory.	 */	/* ignore if it's hidden */	if (this_dir->dir_flags & INHIBIT_ISO9660_ENTRY) {		return 0;	}	table = NULL;	init_fstatbuf();	/*	 * If we had artificially created this directory, then we might be	 * missing the required '.' entries.  Create these now if we need	 * them.	 */	if ((this_dir->dir_flags & (DIR_HAS_DOT | DIR_HAS_DOTDOT)) !=		(DIR_HAS_DOT | DIR_HAS_DOTDOT)) {		attach_dot_entries(this_dir, &fstatbuf);	}	flush_file_hash();	s_entry = this_dir->contents;	while (s_entry) {		/* ignore if it's hidden */		if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) {			s_entry = s_entry->next;			continue;		}		/* First assume no conflict, and handle this case */		if (!(s_entry1 = find_file_hash(s_entry->isorec.name))) {			add_file_hash(s_entry);			s_entry = s_entry->next;			continue;		}#ifdef APPLE_HYB		/*		 * if the pair are associated, then skip (as they have the		 * same name!)		 */		if (apple_both && s_entry1->assoc &&						s_entry1->assoc == s_entry) {			s_entry = s_entry->next;			continue;		}#endif	/* APPLE_HYB */		if (s_entry1 == s_entry) {#ifdef	USE_LIBSCHILY			comerrno(EX_BAD,			"Fatal goof, file '%s' already in hash table.\n",			s_entry->isorec.name);#else			fprintf(stderr,			"Fatal goof, file '%s' already in hash table.\n",			s_entry->isorec.name);			exit(1);#endif		}		/*		 * OK, handle the conflicts.  Try substitute names until we		 * come up with a winner		 */		strcpy(rootname, s_entry->isorec.name);		/*		 * Strip off the non-significant part of the name so that we		 * are left with a sensible root filename.  If we don't find		 * a '.', then try a ';'.		 */		c = strchr(rootname, '.');		/*		 * In case we ever allow more than on dot, only modify the		 * section past the last dot if the file name starts with a		 * dot.		 */		if (c != NULL && c == rootname && c != strrchr(rootname, '.')) {			c = strrchr(rootname, '.');		}		extname[0] = '\0';		/* In case we have no ext.   */		if (c) {			strcpy(extname, c);			*c = 0;			/* Cut off complete ext.     */		} else {			/*			 * Could not find any '.'.			 */			c = strchr(rootname, ';');			if (c) {				*c = 0;		/* Cut off version number    */			}		}		c = strchr(extname, ';');		if (c) {			*c = 0;			/* Cut off version number    */		}		d1 = strlen(rootname);		if (full_iso9660_filenames || iso9660_level > 1) {			d2 = strlen(extname);			/*			 * 31/37 chars minus the 3 characters we are			 * appending below to create unique filenames.			 */			if ((d1 + d2) > (iso9660_namelen - 3))				rootname[iso9660_namelen - 3 - d2] = 0;		} else {			if (d1 > 5)				rootname[5] = 0;		}		for (d1 = 0; d1 < 36; d1++) {			for (d2 = 0; d2 < 36; d2++) {				for (d3 = 0; d3 < 36; d3++) {					sprintf(newname, "%s%c%c%c%s%s",					rootname,					(d1 <= 9 ? '0' + d1 : 'A' + d1 - 10),					(d2 <= 9 ? '0' + d2 : 'A' + d2 - 10),					(d3 <= 9 ? '0' + d3 : 'A' + d3 - 10),					extname,					((s_entry->isorec.flags[0] & ISO_DIRECTORY) ||					omit_version_number ? "" : ";1"));#ifdef VMS				/* Sigh.  VAXCRTL seems to be broken here */					{						int	ijk = 0;						while (newname[ijk]) {							if (newname[ijk] == ' ')								newname[ijk] = '0';							ijk++;						}					}#endif					if (!find_file_hash(newname))						goto got_valid_name;				}			}		}		/* If we fell off the bottom here, we were in real trouble. */#ifdef	USE_LIBSCHILY		comerrno(EX_BAD,			"Unable to generate unique name for file %s\n",			s_entry->name);#else		fprintf(stderr,			"Unable to generate unique name for file %s\n",			s_entry->name);		exit(1);#endifgot_valid_name:		/*		 * OK, now we have a good replacement name.  Now decide which		 * one of these two beasts should get the name changed		 */		if (s_entry->priority < s_entry1->priority) {			if (verbose > 0) {				is_rrmoved++;				fprintf(stderr, "\nUsing %s for  %s%s%s (%s)",					newname,					this_dir->whole_name, SPATH_SEPARATOR,					s_entry->name, s_entry1->name);			}			s_entry->isorec.name_len[0] = strlen(newname);			new_reclen = offsetof(struct iso_directory_record,				name[0]) +				strlen(newname);			if (use_RockRidge) {				if (new_reclen & 1)					new_reclen++; /* Pad to an even byte */				new_reclen += s_entry->rr_attr_size;			}			if (new_reclen & 1)				new_reclen++;	/* Pad to an even byte */			s_entry->isorec.length[0] = new_reclen;			strcpy(s_entry->isorec.name, newname);#ifdef APPLE_HYB			/* has resource fork - needs new name */			if (apple_both && s_entry->assoc) {				struct directory_entry *s_entry2 =								s_entry->assoc;				/*				 * resource fork name *should* be the same as				 * the data fork				 */				s_entry2->isorec.name_len[0] =						s_entry->isorec.name_len[0];				strcpy(s_entry2->isorec.name,						s_entry->isorec.name);				s_entry2->isorec.length[0] = new_reclen;			}#endif	/* APPLE_HYB */		} else {			delete_file_hash(s_entry1);			if (verbose > 0) {				is_rrmoved++;				fprintf(stderr, "\nUsing %s for  %s%s%s (%s)",					newname,					this_dir->whole_name, SPATH_SEPARATOR,					s_entry1->name, s_entry->name);			}			s_entry1->isorec.name_len[0] = strlen(newname);			new_reclen = offsetof(struct iso_directory_record,					name[0]) +					strlen(newname);			if (use_RockRidge) {				if (new_reclen & 1)					new_reclen++; /* Pad to an even byte */				new_reclen += s_entry1->rr_attr_size;			}			if (new_reclen & 1)				new_reclen++;	/* Pad to an even byte */			s_entry1->isorec.length[0] = new_reclen;			strcpy(s_entry1->isorec.name, newname);			add_file_hash(s_entry1);#ifdef APPLE_HYB			/* has resource fork - needs new name */			if (apple_both && s_entry1->assoc) {				struct directory_entry *s_entry2 =							s_entry1->assoc;				/*				 * resource fork name *should* be the same as				 * the data fork				 */

⌨️ 快捷键说明

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