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

📄 traverse.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * Copyright (c) 1980, 1988, 1991, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)traverse.c	8.2 (Berkeley) 9/23/93";#endif /* not lint */#include <sys/param.h>#include <sys/time.h>#include <sys/stat.h>#ifdef sunos#include <sys/vnode.h>#include <ufs/fs.h>#include <ufs/fsdir.h>#include <ufs/inode.h>#else#include <ufs/ffs/fs.h>#include <ufs/ufs/dir.h>#include <ufs/ufs/dinode.h>#endif#include <protocols/dumprestore.h>#include <ctype.h>#include <stdio.h>#ifdef __STDC__#include <string.h>#include <unistd.h>#endif#include "dump.h"#define	HASDUMPEDFILE	0x1#define	HASSUBDIRS	0x2#ifdef	FS_44INODEFMTtypedef	quad_t fsizeT;#elsetypedef	long fsizeT;#endifstatic	int dirindir __P((ino_t ino, daddr_t blkno, int level, long *size));static	void dmpindir __P((ino_t ino, daddr_t blk, int level, fsizeT *size));static	int searchdir __P((ino_t ino, daddr_t blkno, long size, long filesize));/* * This is an estimation of the number of TP_BSIZE blocks in the file. * It estimates the number of blocks in files with holes by assuming * that all of the blocks accounted for by di_blocks are data blocks * (when some of the blocks are usually used for indirect pointers); * hence the estimate may be high. */longblockest(dp)	register struct dinode *dp;{	long blkest, sizeest;	/*	 * dp->di_size is the size of the file in bytes.	 * dp->di_blocks stores the number of sectors actually in the file.	 * If there are more sectors than the size would indicate, this just	 *	means that there are indirect blocks in the file or unused	 *	sectors in the last file block; we can safely ignore these	 *	(blkest = sizeest below).	 * If the file is bigger than the number of sectors would indicate,	 *	then the file has holes in it.	In this case we must use the	 *	block count to estimate the number of data blocks used, but	 *	we use the actual size for estimating the number of indirect	 *	dump blocks (sizeest vs. blkest in the indirect block	 *	calculation).	 */	blkest = howmany(dbtob(dp->di_blocks), TP_BSIZE);	sizeest = howmany(dp->di_size, TP_BSIZE);	if (blkest > sizeest)		blkest = sizeest;	if (dp->di_size > sblock->fs_bsize * NDADDR) {		/* calculate the number of indirect blocks on the dump tape */		blkest +=			howmany(sizeest - NDADDR * sblock->fs_bsize / TP_BSIZE,			TP_NINDIR);	}	return (blkest + 1);}/* Auxiliary macro to pick up files changed since previous dump. */#ifdef FS_44INODEFMT#define	CHANGEDSINCE(dp, t) \	((dp)->di_mtime.ts_sec >= (t) || (dp)->di_ctime.ts_sec >= (t))#else#define	CHANGEDSINCE(dp, t) \	((dp)->di_mtime >= (t) || (dp)->di_ctime >= (t))#endif/* The WANTTODUMP macro decides whether a file should be dumped. */#ifdef UF_NODUMP#define	WANTTODUMP(dp) \	(CHANGEDSINCE(dp, spcl.c_ddate) && \	 (nonodump || ((dp)->di_flags & UF_NODUMP) != UF_NODUMP))#else#define	WANTTODUMP(dp) CHANGEDSINCE(dp, spcl.c_ddate)#endif/* * Dump pass 1. * * Walk the inode list for a filesystem to find all allocated inodes * that have been modified since the previous dump time. Also, find all * the directories in the filesystem. */intmapfiles(maxino, tapesize)	ino_t maxino;	long *tapesize;{	register int mode;	register ino_t ino;	register struct dinode *dp;	int anydirskipped = 0;	for (ino = ROOTINO; ino < maxino; ino++) {		dp = getino(ino);		if ((mode = (dp->di_mode & IFMT)) == 0)			continue;		SETINO(ino, usedinomap);		if (mode == IFDIR)			SETINO(ino, dumpdirmap);		if (WANTTODUMP(dp)) {			SETINO(ino, dumpinomap);			if (mode != IFREG && mode != IFDIR && mode != IFLNK)				*tapesize += 1;			else				*tapesize += blockest(dp);			continue;		}		if (mode == IFDIR)			anydirskipped = 1;	}	/*	 * Restore gets very upset if the root is not dumped,	 * so ensure that it always is dumped.	 */	SETINO(ROOTINO, dumpinomap);	return (anydirskipped);}/* * Dump pass 2. * * Scan each directory on the filesystem to see if it has any modified * files in it. If it does, and has not already been added to the dump * list (because it was itself modified), then add it. If a directory * has not been modified itself, contains no modified files and has no * subdirectories, then it can be deleted from the dump list and from * the list of directories. By deleting it from the list of directories, * its parent may now qualify for the same treatment on this or a later * pass using this algorithm. */intmapdirs(maxino, tapesize)	ino_t maxino;	long *tapesize;{	register struct	dinode *dp;	register int i, isdir;	register char *map;	register ino_t ino;	long filesize;	int ret, change = 0;	isdir = 0;		/* XXX just to get gcc to shut up */	for (map = dumpdirmap, ino = 1; ino < maxino; ino++) {		if (((ino - 1) % NBBY) == 0)	/* map is offset by 1 */			isdir = *map++;		else			isdir >>= 1;		if ((isdir & 1) == 0 || TSTINO(ino, dumpinomap))			continue;		dp = getino(ino);		filesize = dp->di_size;		for (ret = 0, i = 0; filesize > 0 && i < NDADDR; i++) {			if (dp->di_db[i] != 0)				ret |= searchdir(ino, dp->di_db[i],					(long)dblksize(sblock, dp, i),					filesize);			if (ret & HASDUMPEDFILE)				filesize = 0;			else				filesize -= sblock->fs_bsize;		}		for (i = 0; filesize > 0 && i < NIADDR; i++) {			if (dp->di_ib[i] == 0)				continue;			ret |= dirindir(ino, dp->di_ib[i], i, &filesize);		}		if (ret & HASDUMPEDFILE) {			SETINO(ino, dumpinomap);			*tapesize += blockest(dp);			change = 1;			continue;		}		if ((ret & HASSUBDIRS) == 0) {			if (!TSTINO(ino, dumpinomap)) {				CLRINO(ino, dumpdirmap);				change = 1;			}		}	}	return (change);}/* * Read indirect blocks, and pass the data blocks to be searched * as directories. Quit as soon as any entry is found that will * require the directory to be dumped. */static intdirindir(ino, blkno, ind_level, filesize)	ino_t ino;	daddr_t blkno;	int ind_level;	long *filesize;{	int ret = 0;	register int i;	daddr_t	idblk[MAXNINDIR];	bread(fsbtodb(sblock, blkno), (char *)idblk, (int)sblock->fs_bsize);	if (ind_level <= 0) {		for (i = 0; *filesize > 0 && i < NINDIR(sblock); i++) {			blkno = idblk[i];			if (blkno != 0)				ret |= searchdir(ino, blkno, sblock->fs_bsize,					*filesize);			if (ret & HASDUMPEDFILE)				*filesize = 0;			else				*filesize -= sblock->fs_bsize;		}		return (ret);	}	ind_level--;	for (i = 0; *filesize > 0 && i < NINDIR(sblock); i++) {		blkno = idblk[i];		if (blkno != 0)			ret |= dirindir(ino, blkno, ind_level, filesize);	}	return (ret);}/* * Scan a disk block containing directory information looking to see if * any of the entries are on the dump list and to see if the directory * contains any subdirectories. */static intsearchdir(ino, blkno, size, filesize)	ino_t ino;	daddr_t blkno;	register long size;	long filesize;{	register struct direct *dp;	register long loc, ret = 0;	char dblk[MAXBSIZE];	bread(fsbtodb(sblock, blkno), dblk, (int)size);	if (filesize < size)		size = filesize;	for (loc = 0; loc < size; ) {		dp = (struct direct *)(dblk + loc);		if (dp->d_reclen == 0) {			msg("corrupted directory, inumber %d\n", ino);			break;		}		loc += dp->d_reclen;

⌨️ 快捷键说明

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