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

📄 symtab.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1983, 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[] = "@(#)symtab.c	8.1 (Berkeley) 6/5/93";#endif /* not lint *//* * These routines maintain the symbol table which tracks the state * of the file system being restored. They provide lookup by either * name or inode number. They also provide for creation, deletion, * and renaming of entries. Because of the dynamic nature of pathnames, * names should not be saved, but always constructed just before they * are needed, by calling "myname". */#include <sys/param.h>#include <sys/stat.h>#include <ufs/ufs/dinode.h>#include <errno.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include "restore.h"#include "extern.h"/* * The following variables define the inode symbol table. * The primary hash table is dynamically allocated based on * the number of inodes in the file system (maxino), scaled by * HASHFACTOR. The variable "entry" points to the hash table; * the variable "entrytblsize" indicates its size (in entries). */#define HASHFACTOR 5static struct entry **entry;static long entrytblsize;static void		 addino __P((ino_t, struct entry *));static struct entry	*lookupparent __P((char *));static void		 removeentry __P((struct entry *));/* * Look up an entry by inode number */struct entry *lookupino(inum)	ino_t inum;{	register struct entry *ep;	if (inum < ROOTINO || inum >= maxino)		return (NULL);	for (ep = entry[inum % entrytblsize]; ep != NULL; ep = ep->e_next)		if (ep->e_ino == inum)			return (ep);	return (NULL);}/* * Add an entry into the entry table */static voidaddino(inum, np)	ino_t inum;	struct entry *np;{	struct entry **epp;	if (inum < ROOTINO || inum >= maxino)		panic("addino: out of range %d\n", inum);	epp = &entry[inum % entrytblsize];	np->e_ino = inum;	np->e_next = *epp;	*epp = np;	if (dflag)		for (np = np->e_next; np != NULL; np = np->e_next)			if (np->e_ino == inum)				badentry(np, "duplicate inum");}/* * Delete an entry from the entry table */voiddeleteino(inum)	ino_t inum;{	register struct entry *next;	struct entry **prev;	if (inum < ROOTINO || inum >= maxino)		panic("deleteino: out of range %d\n", inum);	prev = &entry[inum % entrytblsize];	for (next = *prev; next != NULL; next = next->e_next) {		if (next->e_ino == inum) {			next->e_ino = 0;			*prev = next->e_next;			return;		}		prev = &next->e_next;	}	panic("deleteino: %d not found\n", inum);}/* * Look up an entry by name */struct entry *lookupname(name)	char *name;{	register struct entry *ep;	register char *np, *cp;	char buf[MAXPATHLEN];	cp = name;	for (ep = lookupino(ROOTINO); ep != NULL; ep = ep->e_entries) {		for (np = buf; *cp != '/' && *cp != '\0'; )			*np++ = *cp++;		*np = '\0';		for ( ; ep != NULL; ep = ep->e_sibling)			if (strcmp(ep->e_name, buf) == 0)				break;		if (ep == NULL)			break;		if (*cp++ == '\0')			return (ep);	}	return (NULL);}/* * Look up the parent of a pathname */static struct entry *lookupparent(name)	char *name;{	struct entry *ep;	char *tailindex;	tailindex = rindex(name, '/');	if (tailindex == NULL)		return (NULL);	*tailindex = '\0';	ep = lookupname(name);	*tailindex = '/';	if (ep == NULL)		return (NULL);	if (ep->e_type != NODE)		panic("%s is not a directory\n", name);	return (ep);}/* * Determine the current pathname of a node or leaf */char *myname(ep)	register struct entry *ep;{	register char *cp;	static char namebuf[MAXPATHLEN];	for (cp = &namebuf[MAXPATHLEN - 2]; cp > &namebuf[ep->e_namlen]; ) {		cp -= ep->e_namlen;		bcopy(ep->e_name, cp, (long)ep->e_namlen);		if (ep == lookupino(ROOTINO))			return (cp);		*(--cp) = '/';		ep = ep->e_parent;	}	panic("%s: pathname too long\n", cp);	return(cp);}/* * Unused symbol table entries are linked together on a freelist * headed by the following pointer. */static struct entry *freelist = NULL;/* * add an entry to the symbol table */struct entry *addentry(name, inum, type)	char *name;	ino_t inum;	int type;{	register struct entry *np, *ep;	if (freelist != NULL) {		np = freelist;		freelist = np->e_next;		bzero((char *)np, (long)sizeof(struct entry));	} else {		np = (struct entry *)calloc(1, sizeof(struct entry));		if (np == NULL)			panic("no memory to extend symbol table\n");	}	np->e_type = type & ~LINK;	ep = lookupparent(name);	if (ep == NULL) {		if (inum != ROOTINO || lookupino(ROOTINO) != NULL)			panic("bad name to addentry %s\n", name);		np->e_name = savename(name);		np->e_namlen = strlen(name);		np->e_parent = np;		addino(ROOTINO, np);		return (np);	}	np->e_name = savename(rindex(name, '/') + 1);	np->e_namlen = strlen(np->e_name);	np->e_parent = ep;	np->e_sibling = ep->e_entries;	ep->e_entries = np;	if (type & LINK) {		ep = lookupino(inum);		if (ep == NULL)			panic("link to non-existant name\n");		np->e_ino = inum;		np->e_links = ep->e_links;		ep->e_links = np;	} else if (inum != 0) {		if (lookupino(inum) != NULL)			panic("duplicate entry\n");		addino(inum, np);	}	return (np);}/* * delete an entry from the symbol table */voidfreeentry(ep)	register struct entry *ep;{	register struct entry *np;	ino_t inum;	if (ep->e_flags != REMOVED)		badentry(ep, "not marked REMOVED");	if (ep->e_type == NODE) {		if (ep->e_links != NULL)			badentry(ep, "freeing referenced directory");		if (ep->e_entries != NULL)			badentry(ep, "freeing non-empty directory");	}	if (ep->e_ino != 0) {		np = lookupino(ep->e_ino);		if (np == NULL)			badentry(ep, "lookupino failed");		if (np == ep) {			inum = ep->e_ino;			deleteino(inum);			if (ep->e_links != NULL)				addino(inum, ep->e_links);		} else {			for (; np != NULL; np = np->e_links) {				if (np->e_links == ep) {					np->e_links = ep->e_links;					break;				}			}			if (np == NULL)				badentry(ep, "link not found");		}	}	removeentry(ep);	freename(ep->e_name);	ep->e_next = freelist;	freelist = ep;}/* * Relocate an entry in the tree structure */

⌨️ 快捷键说明

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