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

📄 dir.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1980, 1986, 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[] = "@(#)dir.c	8.1 (Berkeley) 6/5/93";#endif /* not lint */#include <sys/param.h>#include <sys/time.h>#include <ufs/ufs/dinode.h>#include <ufs/ufs/dir.h>#include <ufs/ffs/fs.h>#include <stdlib.h>#include <string.h>#include "fsck.h"char	*lfname = "lost+found";int	lfmode = 01777;struct	dirtemplate emptydir = { 0, DIRBLKSIZ };struct	dirtemplate dirhead = {	0, 12, DT_DIR, 1, ".",	0, DIRBLKSIZ - 12, DT_DIR, 2, ".."};struct	odirtemplate odirhead = {	0, 12, 1, ".",	0, DIRBLKSIZ - 12, 2, ".."};struct direct	*fsck_readdir();struct bufarea	*getdirblk();/* * Propagate connected state through the tree. */propagate(){	register struct inoinfo **inpp, *inp;	struct inoinfo **inpend;	long change;	inpend = &inpsort[inplast];	do {		change = 0;		for (inpp = inpsort; inpp < inpend; inpp++) {			inp = *inpp;			if (inp->i_parent == 0)				continue;			if (statemap[inp->i_parent] == DFOUND &&			    statemap[inp->i_number] == DSTATE) {				statemap[inp->i_number] = DFOUND;				change++;			}		}	} while (change > 0);}/* * Scan each entry in a directory block. */dirscan(idesc)	register struct inodesc *idesc;{	register struct direct *dp;	register struct bufarea *bp;	int dsize, n;	long blksiz;	char dbuf[DIRBLKSIZ];	if (idesc->id_type != DATA)		errexit("wrong type to dirscan %d\n", idesc->id_type);	if (idesc->id_entryno == 0 &&	    (idesc->id_filesize & (DIRBLKSIZ - 1)) != 0)		idesc->id_filesize = roundup(idesc->id_filesize, DIRBLKSIZ);	blksiz = idesc->id_numfrags * sblock.fs_fsize;	if (chkrange(idesc->id_blkno, idesc->id_numfrags)) {		idesc->id_filesize -= blksiz;		return (SKIP);	}	idesc->id_loc = 0;	for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) {		dsize = dp->d_reclen;		bcopy((char *)dp, dbuf, (size_t)dsize);#		if (BYTE_ORDER == LITTLE_ENDIAN)			if (!newinofmt) {				struct direct *tdp = (struct direct *)dbuf;				u_char tmp;				tmp = tdp->d_namlen;				tdp->d_namlen = tdp->d_type;				tdp->d_type = tmp;			}#		endif		idesc->id_dirp = (struct direct *)dbuf;		if ((n = (*idesc->id_func)(idesc)) & ALTERED) {#			if (BYTE_ORDER == LITTLE_ENDIAN)				if (!newinofmt && !doinglevel2) {					struct direct *tdp;					u_char tmp;					tdp = (struct direct *)dbuf;					tmp = tdp->d_namlen;					tdp->d_namlen = tdp->d_type;					tdp->d_type = tmp;				}#			endif			bp = getdirblk(idesc->id_blkno, blksiz);			bcopy(dbuf, bp->b_un.b_buf + idesc->id_loc - dsize,			    (size_t)dsize);			dirty(bp);			sbdirty();		}		if (n & STOP) 			return (n);	}	return (idesc->id_filesize > 0 ? KEEPON : STOP);}/* * get next entry in a directory. */struct direct *fsck_readdir(idesc)	register struct inodesc *idesc;{	register struct direct *dp, *ndp;	register struct bufarea *bp;	long size, blksiz, fix, dploc;	blksiz = idesc->id_numfrags * sblock.fs_fsize;	bp = getdirblk(idesc->id_blkno, blksiz);	if (idesc->id_loc % DIRBLKSIZ == 0 && idesc->id_filesize > 0 &&	    idesc->id_loc < blksiz) {		dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);		if (dircheck(idesc, dp))			goto dpok;		fix = dofix(idesc, "DIRECTORY CORRUPTED");		bp = getdirblk(idesc->id_blkno, blksiz);		dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);		dp->d_reclen = DIRBLKSIZ;		dp->d_ino = 0;		dp->d_type = 0;		dp->d_namlen = 0;		dp->d_name[0] = '\0';		if (fix)			dirty(bp);		idesc->id_loc += DIRBLKSIZ;		idesc->id_filesize -= DIRBLKSIZ;		return (dp);	}dpok:	if (idesc->id_filesize <= 0 || idesc->id_loc >= blksiz)		return NULL;	dploc = idesc->id_loc;	dp = (struct direct *)(bp->b_un.b_buf + dploc);	idesc->id_loc += dp->d_reclen;	idesc->id_filesize -= dp->d_reclen;	if ((idesc->id_loc % DIRBLKSIZ) == 0)		return (dp);	ndp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);	if (idesc->id_loc < blksiz && idesc->id_filesize > 0 &&	    dircheck(idesc, ndp) == 0) {		size = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);		idesc->id_loc += size;		idesc->id_filesize -= size;		fix = dofix(idesc, "DIRECTORY CORRUPTED");		bp = getdirblk(idesc->id_blkno, blksiz);		dp = (struct direct *)(bp->b_un.b_buf + dploc);		dp->d_reclen += size;		if (fix)			dirty(bp);	}	return (dp);}/* * Verify that a directory entry is valid. * This is a superset of the checks made in the kernel. */dircheck(idesc, dp)	struct inodesc *idesc;	register struct direct *dp;{	register int size;	register char *cp;	u_char namlen, type;	int spaceleft;	size = DIRSIZ(!newinofmt, dp);	spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);#	if (BYTE_ORDER == LITTLE_ENDIAN)		if (!newinofmt) {			type = dp->d_namlen;			namlen = dp->d_type;		} else {			namlen = dp->d_namlen;			type = dp->d_type;		}#	else		namlen = dp->d_namlen;		type = dp->d_type;#	endif	if (dp->d_ino < maxino &&	    dp->d_reclen != 0 &&	    dp->d_reclen <= spaceleft &&	    (dp->d_reclen & 0x3) == 0 &&	    dp->d_reclen >= size &&	    idesc->id_filesize >= size &&	    namlen <= MAXNAMLEN &&	    type <= 15) {		if (dp->d_ino == 0)			return (1);		for (cp = dp->d_name, size = 0; size < namlen; size++)			if (*cp == 0 || (*cp++ == '/'))				return (0);		if (*cp == 0)			return (1);	}	return (0);}direrror(ino, errmesg)	ino_t ino;	char *errmesg;{	fileerror(ino, ino, errmesg);}fileerror(cwd, ino, errmesg)	ino_t cwd, ino;	char *errmesg;{	register struct dinode *dp;	char pathbuf[MAXPATHLEN + 1];	pwarn("%s ", errmesg);	pinode(ino);	printf("\n");	getpathname(pathbuf, cwd, ino);	if (ino < ROOTINO || ino > maxino) {		pfatal("NAME=%s\n", pathbuf);		return;	}	dp = ginode(ino);	if (ftypeok(dp))		pfatal("%s=%s\n",		    (dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE", pathbuf);	else		pfatal("NAME=%s\n", pathbuf);}adjust(idesc, lcnt)	register struct inodesc *idesc;	short lcnt;{	register struct dinode *dp;	dp = ginode(idesc->id_number);	if (dp->di_nlink == lcnt) {		if (linkup(idesc->id_number, (ino_t)0) == 0)			clri(idesc, "UNREF", 0);	} else {		pwarn("LINK COUNT %s", (lfdir == idesc->id_number) ? lfname :			((dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE"));		pinode(idesc->id_number);		printf(" COUNT %d SHOULD BE %d",			dp->di_nlink, dp->di_nlink - lcnt);		if (preen) {			if (lcnt < 0) {				printf("\n");				pfatal("LINK COUNT INCREASING");			}			printf(" (ADJUSTED)\n");		}		if (preen || reply("ADJUST") == 1) {			dp->di_nlink -= lcnt;			inodirty();		}	}}mkentry(idesc)	struct inodesc *idesc;{	register struct direct *dirp = idesc->id_dirp;	struct direct newent;	int newlen, oldlen;	newent.d_namlen = strlen(idesc->id_name);	newlen = DIRSIZ(0, &newent);	if (dirp->d_ino != 0)		oldlen = DIRSIZ(0, dirp);	else		oldlen = 0;	if (dirp->d_reclen - oldlen < newlen)		return (KEEPON);	newent.d_reclen = dirp->d_reclen - oldlen;	dirp->d_reclen = oldlen;	dirp = (struct direct *)(((char *)dirp) + oldlen);	dirp->d_ino = idesc->id_parent;	/* ino to be entered is in id_parent */	if (newinofmt)		dirp->d_type = typemap[idesc->id_parent];	else		dirp->d_type = 0;	dirp->d_reclen = newent.d_reclen;	dirp->d_namlen = newent.d_namlen;	bcopy(idesc->id_name, dirp->d_name, (size_t)dirp->d_namlen + 1);	return (ALTERED|STOP);}chgino(idesc)

⌨️ 快捷键说明

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