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

📄 dirs.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1983, 1993 *	The Regents of the University of California.  All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * 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[] = "@(#)dirs.c	8.2 (Berkeley) 1/21/94";#endif /* not lint */#include <sys/param.h>#include <sys/file.h>#include <sys/stat.h>#include <sys/time.h>#include <ufs/ffs/fs.h>#include <ufs/ufs/dinode.h>#include <ufs/ufs/dir.h>#include <protocols/dumprestore.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include "pathnames.h"#include "restore.h"#include "extern.h"/* * Symbol table of directories read from tape. */#define HASHSIZE	1000#define INOHASH(val) (val % HASHSIZE)struct inotab {	struct	inotab *t_next;	ino_t	t_ino;	long	t_seekpt;	long	t_size;};static struct inotab *inotab[HASHSIZE];/* * Information retained about directories. */struct modeinfo {	ino_t ino;	struct timeval timep[2];	short mode;	short uid;	short gid;};/* * Definitions for library routines operating on directories. */#undef DIRBLKSIZ#define DIRBLKSIZ 1024struct rstdirdesc {	int	dd_fd;	long	dd_loc;	long	dd_size;	char	dd_buf[DIRBLKSIZ];};/* * Global variables for this file. */static long	seekpt;static FILE	*df, *mf;static RST_DIR	*dirp;static char	dirfile[32] = "#";	/* No file */static char	modefile[32] = "#";	/* No file */static char	dot[2] = ".";		/* So it can be modified *//* * Format of old style directories. */#define ODIRSIZ 14struct odirect {	u_short	d_ino;	char	d_name[ODIRSIZ];};static struct inotab	*allocinotab __P((ino_t, struct dinode *, long));static void		 dcvt __P((struct odirect *, struct direct *));static void		 flushent __P((void));static struct inotab	*inotablookup __P((ino_t));static RST_DIR		*opendirfile __P((const char *));static void		 putdir __P((char *, long));static void		 putent __P((struct direct *));static void		 rst_seekdir __P((RST_DIR *, long, long));static long		 rst_telldir __P((RST_DIR *));static struct direct	*searchdir __P((ino_t, char *));/* *	Extract directory contents, building up a directory structure *	on disk for extraction by name. *	If genmode is requested, save mode, owner, and times for all *	directories on the tape. */voidextractdirs(genmode)	int genmode;{	register int i;	register struct dinode *ip;	struct inotab *itp;	struct direct nulldir;	vprintf(stdout, "Extract directories from tape\n");	(void) sprintf(dirfile, "%s/rstdir%d", _PATH_TMP, dumpdate);	df = fopen(dirfile, "w");	if (df == NULL) {		fprintf(stderr,		    "restore: %s - cannot create directory temporary\n",		    dirfile);		fprintf(stderr, "fopen: %s\n", strerror(errno));		done(1);	}	if (genmode != 0) {		(void) sprintf(modefile, "%s/rstmode%d", _PATH_TMP, dumpdate);		mf = fopen(modefile, "w");		if (mf == NULL) {			fprintf(stderr,			    "restore: %s - cannot create modefile \n",			    modefile);			fprintf(stderr, "fopen: %s\n", strerror(errno));			done(1);		}	}	nulldir.d_ino = 0;	nulldir.d_type = DT_DIR;	nulldir.d_namlen = 1;	(void) strcpy(nulldir.d_name, "/");	nulldir.d_reclen = DIRSIZ(0, &nulldir);	for (;;) {		curfile.name = "<directory file - name unknown>";		curfile.action = USING;		ip = curfile.dip;		if (ip == NULL || (ip->di_mode & IFMT) != IFDIR) {			(void) fclose(df);			dirp = opendirfile(dirfile);			if (dirp == NULL)				fprintf(stderr, "opendirfile: %s\n",				    strerror(errno));			if (mf != NULL)				(void) fclose(mf);			i = dirlookup(dot);			if (i == 0)				panic("Root directory is not on tape\n");			return;		}		itp = allocinotab(curfile.ino, ip, seekpt);		getfile(putdir, xtrnull);		putent(&nulldir);		flushent();		itp->t_size = seekpt - itp->t_seekpt;	}}/* * skip over all the directories on the tape */voidskipdirs(){	while ((curfile.dip->di_mode & IFMT) == IFDIR) {		skipfile();	}}/* *	Recursively find names and inumbers of all files in subtree  *	pname and pass them off to be processed. */voidtreescan(pname, ino, todo)	char *pname;	ino_t ino;	long (*todo) __P((char *, ino_t, int));{	register struct inotab *itp;	register struct direct *dp;	int namelen;	long bpt;	char locname[MAXPATHLEN + 1];	itp = inotablookup(ino);	if (itp == NULL) {		/*		 * Pname is name of a simple file or an unchanged directory.		 */		(void) (*todo)(pname, ino, LEAF);		return;	}	/*	 * Pname is a dumped directory name.	 */	if ((*todo)(pname, ino, NODE) == FAIL)		return;	/*	 * begin search through the directory	 * skipping over "." and ".."	 */	(void) strncpy(locname, pname, MAXPATHLEN);	(void) strncat(locname, "/", MAXPATHLEN);	namelen = strlen(locname);	rst_seekdir(dirp, itp->t_seekpt, itp->t_seekpt);	dp = rst_readdir(dirp); /* "." */	if (dp != NULL && strcmp(dp->d_name, ".") == 0)		dp = rst_readdir(dirp); /* ".." */	else		fprintf(stderr, "Warning: `.' missing from directory %s\n",			pname);	if (dp != NULL && strcmp(dp->d_name, "..") == 0)		dp = rst_readdir(dirp); /* first real entry */	else		fprintf(stderr, "Warning: `..' missing from directory %s\n",			pname);	bpt = rst_telldir(dirp);	/*	 * a zero inode signals end of directory	 */	while (dp != NULL && dp->d_ino != 0) {		locname[namelen] = '\0';		if (namelen + dp->d_namlen >= MAXPATHLEN) {			fprintf(stderr, "%s%s: name exceeds %d char\n",				locname, dp->d_name, MAXPATHLEN);		} else {			(void) strncat(locname, dp->d_name, (int)dp->d_namlen);			treescan(locname, dp->d_ino, todo);			rst_seekdir(dirp, bpt, itp->t_seekpt);		}		dp = rst_readdir(dirp);		bpt = rst_telldir(dirp);	}	if (dp == NULL)		fprintf(stderr, "corrupted directory: %s.\n", locname);}/* * Lookup a pathname which is always assumed to start from the ROOTINO. */struct direct *pathsearch(pathname)	const char *pathname;{	ino_t ino;	struct direct *dp;	char *path, *name, buffer[MAXPATHLEN];	strcpy(buffer, pathname);	path = buffer;	ino = ROOTINO;	while (*path == '/')		path++;	dp = NULL;	while ((name = strsep(&path, "/")) != NULL && *name != NULL) {		if ((dp = searchdir(ino, name)) == NULL)			return (NULL);		ino = dp->d_ino;	}	return (dp);}/* * Lookup the requested name in directory inum. * Return its inode number if found, zero if it does not exist. */static struct direct *searchdir(inum, name)	ino_t	inum;	char	*name;{	register struct direct *dp;	register struct inotab *itp;	int len;	itp = inotablookup(inum);	if (itp == NULL)		return (NULL);	rst_seekdir(dirp, itp->t_seekpt, itp->t_seekpt);	len = strlen(name);	do {		dp = rst_readdir(dirp);		if (dp == NULL || dp->d_ino == 0)			return (NULL);	} while (dp->d_namlen != len || strncmp(dp->d_name, name, len) != 0);	return (dp);}/* * Put the directory entries in the directory file */static voidputdir(buf, size)	char *buf;	long size;{	struct direct cvtbuf;	register struct odirect *odp;	struct odirect *eodp;	register struct direct *dp;	long loc, i;	if (cvtflag) {		eodp = (struct odirect *)&buf[size];		for (odp = (struct odirect *)buf; odp < eodp; odp++)			if (odp->d_ino != 0) {				dcvt(odp, &cvtbuf);				putent(&cvtbuf);			}	} else {		for (loc = 0; loc < size; ) {			dp = (struct direct *)(buf + loc);			if (oldinofmt) {				if (Bcvt) {					swabst((u_char *)"l2s", (u_char *) dp);				}			} else {				if (Bcvt) {					swabst((u_char *)"ls", (u_char *) dp);				}			}			i = DIRBLKSIZ - (loc & (DIRBLKSIZ - 1));			if ((dp->d_reclen & 0x3) != 0 ||			    dp->d_reclen > i ||			    dp->d_reclen < DIRSIZ(0, dp) ||			    dp->d_namlen > NAME_MAX) {				vprintf(stdout, "Mangled directory: ");				if ((dp->d_reclen & 0x3) != 0)					vprintf(stdout,					   "reclen not multiple of 4 ");				if (dp->d_reclen < DIRSIZ(0, dp))					vprintf(stdout,					   "reclen less than DIRSIZ (%d < %d) ",					   dp->d_reclen, DIRSIZ(0, dp));				if (dp->d_namlen > NAME_MAX)					vprintf(stdout,

⌨️ 快捷键说明

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