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

📄 simple_dump.c

📁 网络数据管理协议的开发
💻 C
字号:
/*                               -*- Mode: C -*-  * simple_dump.c *  * Description     : Simple dump functions. *  * Copyright (c) 1996,1997 PDC, Network Appliance. All Rights Reserved. * * $Id: simple_dump.c,v 1.9 1998/05/26 03:52:22 tim Exp $ */#if !defined(lint) && !defined(SABER)static char rcsId[] __attribute__ ((unused)) = "@(#) $Id: simple_dump.c,v 1.9 1998/05/26 03:52:22 tim Exp $";#endif#include <sys/param.h>#include <sys/types.h>#include <sys/mman.h>#include <errno.h>#include <sys/stat.h>#include <dirent.h>#include <unistd.h>#include <string.h>#include "simple_private.h"#include "log.h"typedef struct DumpInfo{	SimpleParams		*params;	char*				path;	bool_t				fileHistory;} DumpInfo;static intdumpFile(DumpInfo*	dmpInfo,		 char*		path);static intdumpDirectory(DumpInfo*	dmpInfo,			  char*		path);static intwriteFile(DumpInfo*	dmpInfo,		  char*		path,		  off_t		size);static intwriteLink(DumpInfo*		dmpInfo,		  char*			path);/* * simpleDump *   Implements a simple dump. *   For each file, file status, the file name, and the file *   data (regular files only) is written to tape. *   File history data is generated for each file dumped. * * Parameters: *   params (input) - dump parameters. * * Returns: *   0 - success. *  -1 - failure. */intsimpleDump(SimpleParams*	params){	int		err;		DumpInfo			info;	char*				var_str;	NdmpdModuleParams*	modParams = params->modParams;	struct	stat		fileStat;	char				cwd[MAXPATHLEN+1];		info.params       = params;	info.path = (*modParams->getEnvFunc)(modParams->daemonCookie,										 "FILESYSTEM");	if (info.path == 0)	{		(*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0,							  "Dump: ERROR: Required environment variable:%s not specified.\n",							  "FILESYSTEM");		return(EINVAL);	}	if (info.path[0] != '/')	{		(*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0,							  "Dump: ERROR: relative dump path not allowed.\n");		return(EINVAL);	}		if (stat(info.path, &fileStat) < 0)	{		(*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0,							  "Dump: ERROR: stat %s: %s.\n",							  info.path, strerror(errno));		return(EINVAL);	}		if ((fileStat.st_mode & S_IFMT) != S_IFDIR)	{		(*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0,							  "Dump: ERROR: %s is not a directory.\n",							  info.path);		return(EINVAL);	}		(void)getcwd(cwd, sizeof(cwd));		if (chdir(info.path) < 0)	{		(*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0,							  "Dump: ERROR: can't chdir to %s.\n",							  info.path);		return(EINVAL);	}		var_str = (*modParams->getEnvFunc)(modParams->daemonCookie,									   "HIST");	if (var_str)	{		if (var_str[0] == 't' || var_str[0] == 'T' ||			var_str[0] == 'y' || var_str[0] == 'Y')			info.fileHistory = TRUE;		else			info.fileHistory = FALSE;	}	else		info.fileHistory = FALSE;	(*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0,						  "Dump: dumping %s.\n",						  info.path);	err = dumpFile(&info, ".");	if (err == 0)	{		/* Mark the end of the dump with a zerod file status structure. */		memset((void*)&fileStat, 0, sizeof(fileStat));		err = (*modParams->writeFunc)(modParams->daemonCookie,									  (char*)&fileStat,									  sizeof(fileStat));		if (err == 0)		{			modParams->stats->bytesProcessed += sizeof(fileStat);			/* Flush buffered data to tape. */			err = (modParams->writeFunc)(modParams->daemonCookie,										 0, 0);		}	}		if (err)		(*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0,							  "Dump: aborted.\n");	else		(*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0,							  "Dump: successfully completed.\n");	(void)chdir(cwd);	return(err);}static intdumpFile(DumpInfo*	dmpInfo,		 char*		path){	struct	stat		fileStat;	u_long				pathLen;	u_longlong_t		fh_info;	NdmpdModuleParams*	modParams = dmpInfo->params->modParams;		Debug(DBG_CAT_BACKUP|DBG_FOC_DETAIL,		  "dumpFile: dumping %s.\n",		  path);		if (lstat(path, &fileStat) < 0)	{		Error(LOG_ERR,			  "dumpFile: lstat error: %s.\n", strerror(errno));		(*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0,							  "Dump: ERROR: lstat(%s): %s.\n",							  path, strerror(errno));		return(0);	}		if ((fileStat.st_mode & S_IFMT) == S_IFREG)	{		/*		 * Catch access errors before writing the file meta data.		 * This eliminates the need to perform recovery if the meta		 * data is written and then the file data can not be written.		 */		if (access(path, R_OK) < 0)		{			(*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0,								  "Dump: ERROR: accessing %s: %s.\n",								  path, strerror(errno));			return(0);		}	}	/* Record the current data stream position for use in file history. */	fh_info = modParams->stats->bytesProcessed;		/*	 * Write the file status data to tape.	 */	if ((*modParams->writeFunc)(modParams->daemonCookie,								(char*)&fileStat,								sizeof(fileStat)) < 0)		return(-1);		modParams->stats->bytesProcessed += sizeof(fileStat);		/*	 * Write the file name length to tape. 	 */	pathLen = strlen(path);	if ((*modParams->writeFunc)(modParams->daemonCookie,								(char*)&pathLen,								sizeof(pathLen)) < 0)		return(-1);	modParams->stats->bytesProcessed += sizeof(pathLen);	/*	 * Write the file name to tape.	 */	if ((*modParams->writeFunc)(modParams->daemonCookie,								path,								pathLen) < 0)		return(-1);		modParams->stats->bytesProcessed += pathLen;	/*	 * Write the file data to tape.	 */	if ((fileStat.st_mode & S_IFMT) == S_IFREG)	{		if (writeFile(dmpInfo, path, fileStat.st_size) < 0)			return(-1);	}	else if ((fileStat.st_mode & S_IFMT) == S_IFLNK)	{		if (writeLink(dmpInfo, path) < 0)			return(-1);	}		if (dmpInfo->fileHistory)		(*modParams->fileHistoryFileFunc)(modParams->daemonCookie,										  path, &fileStat, fh_info);	if ((fileStat.st_mode & S_IFMT) == S_IFDIR)		return(dumpDirectory(dmpInfo, path));	return(0);}static intdumpDirectory(DumpInfo*	dmpInfo,			  char*		dirpath){	DIR*				dir;	struct dirent*		dirp;	int					err;	char				path[MAXPATHLEN];	u_long				dirpathlen;	NdmpdModuleParams*	modParams = dmpInfo->params->modParams;		Debug(DBG_CAT_BACKUP|DBG_FOC_DETAIL,		  "dumpDirectory: dumping %s.\n",		  dirpath);	/*	 * Give the daemon a chance to process any pending requests,	 * one of which may be an abort request.	 */	(*modParams->dispatchFunc)(modParams->daemonCookie, FALSE);	if (dmpInfo->params->abortFlag == TRUE)		return(EINTR);		if ((dir = opendir(dirpath)) == 0)	{		Error(LOG_ERR,			  "dumpDirectory: opendir(%s) error: %s.\n",			  dirpath, strerror(errno));		(*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0,							  "Dump: ERROR: opendir(%s): %s.\n",							  path, strerror(errno));		return(0);	}		strcpy(path, dirpath);	dirpathlen = strlen(dirpath);	path[dirpathlen++] = '/';		while ((dirp = readdir(dir)) != 0)	{		if (strcmp(dirp->d_name, ".") == 0 ||			strcmp(dirp->d_name, "..") == 0)			continue;		if (strlen(dirp->d_name) + dirpathlen > MAXPATHLEN)		{			Error(LOG_ERR,				  "dumpDirectory: MAXPATHLEN exceeded; %s/%s not dumped.\n",				  dirpath, dirp->d_name);			continue;		}		strcpy(&path[dirpathlen], dirp->d_name);				err = dumpFile(dmpInfo, path);		if (err != 0)		{			(void)closedir(dir);			return(err);		}	}	(void)closedir(dir);	return(0);}static intwriteFile(DumpInfo*	dmpInfo,		  char*		path,		  off_t		size){	int					fd;	caddr_t				addr;	int					err;	NdmpdModuleParams*	modParams = dmpInfo->params->modParams;		if (size == 0)		return(0);		fd = open(path, O_RDONLY);	if (fd < 0)	{		Error(LOG_ERR,			  "writeFile: error opening: %s: %s.\n",			  path, strerror(errno));		(*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0,							  "Dump: ERROR: opening %s: %s.\n",							  path, strerror(errno));		return(-1);	}		addr = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);	if (addr == MAP_FAILED)	{		Error(LOG_ERR,			  "writeFile: error mapping: %s: %s.\n",			  path, strerror(errno));		(*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0,							  "Dump: ERROR: mapping %s: %s.\n",							  path, strerror(errno));		close(fd);		return(-1);	}		err = (*modParams->writeFunc)(modParams->daemonCookie,								  (char*)addr,								  size);	if (err == 0)		modParams->stats->bytesProcessed += size;	close(fd);	munmap(addr, size);	return(err);}/* * writeLink *   Write symbolic link data to tape. The data consists of the *   link name. * * Parameters: *   dmpInfo (input) - info pointer. *   path    (input) - symbolic link path. * * Returns: *    0 - success. *   -1 - error */static intwriteLink(DumpInfo*		dmpInfo,		  char*			path){	char				buf[MAXPATHLEN];	int					n;	NdmpdModuleParams*	modParams = dmpInfo->params->modParams;	n = readlink(path, buf, sizeof(buf));	if (n < 0)	{		(*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0,							  "Dump: ERROR: reading link %s: %s.\n",							  path, strerror(errno));		return(-1);	}	/*	 * Write the link name to tape.	 */	if ((*modParams->writeFunc)(modParams->daemonCookie,								buf,								n) < 0)	{		(*modParams->logFunc)(modParams->daemonCookie, NDMP_LOG_NORMAL, 0,							  "Dump: ERROR: writing link name: %s: %s.\n",							  path, strerror(errno));		return(-1);	}		modParams->stats->bytesProcessed += n;	return(0);}

⌨️ 快捷键说明

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