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

📄 copy_dir_rec.c

📁 pwdutils是一套密码管理工具
💻 C
字号:
/* Copyright (C) 2003, 2005 Thorsten Kukuk   Author: Thorsten Kukuk <kukuk@suse.de>   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License version 2 as   published by the Free Software Foundation.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software Foundation,   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */#ifdef HAVE_CONFIG_H#include "config.h"#endif#define _GNU_SOURCE#include <errno.h>#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <string.h>#include <dirent.h>#include <sys/stat.h>#include "i18n.h"#include "public.h"/* Recursive copy of a directory. Return values:   -1: Error occured, remove the tree.    0: No error.    1: There was on error in a deeper level, this is only informative.*/intcopy_dir_rec (const char *src, const char *dst, int preserve_id,	      uid_t uid, gid_t gid){  struct dirent *entry;  DIR *dir = opendir (src);  int retval = 0;  if (dir == NULL)    return -1;  while ((entry = readdir (dir)) != NULL)    {      /* Skip "." and ".." directory entries.  */      if (strcmp (entry->d_name, ".") == 0 ||	  strcmp (entry->d_name, "..") == 0)	continue;      else	{	  char srcfile[strlen (src) + strlen (entry->d_name) + 2];	  char dstfile[strlen (dst) + strlen (entry->d_name) + 2];	  struct stat st;	  char *cp;	  /* create source and destination filename with full path.  */	  cp = stpcpy (srcfile, src);	  *cp++ = '/';	  strcpy (cp, entry->d_name);	  cp = stpcpy (dstfile, dst);	  *cp++ = '/';	  strcpy (cp, entry->d_name);	  if (lstat (srcfile, &st) != 0)	    continue;	  if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))	    {	      if (mknod (dstfile, st.st_mode & ~07777, st.st_rdev) != 0)		{		  fprintf (stderr, _("Can't create `%s': %m\n"),			   dstfile);		  retval = 1;		}	      else if (chown (dstfile,			      preserve_id ? st.st_uid : uid,			      preserve_id ? st.st_gid : gid) != 0 ||		       chmod (dstfile, st.st_mode & 07777) != 0)		{		  unlink (dstfile);		  retval = 1;		}	      else if (copy_xattr (srcfile, dstfile) != 0)		{		  unlink (dstfile);		  retval = 1;		}	    }	  else if (S_ISDIR(st.st_mode))	    {	      if (mkdir (dstfile, 0) != 0)		{		  fprintf (stderr, _("Cannot create directory `%s': %s\n"),			   dstfile, strerror (errno));		  retval = 1;		}	      else		{		  retval = copy_dir_rec (srcfile, dstfile,					 preserve_id, uid, gid);		  if (retval < 0 ||		      chown (dstfile,			     preserve_id ? st.st_uid : uid,			     preserve_id ? st.st_gid : gid) != 0 ||		      chmod (dstfile, st.st_mode & 07777) != 0)		    {		      fprintf (stderr, _("Cannot change permissions for `%s': %s\n"),			       dstfile, strerror (errno));		      /* An error occured, remove the new subtree.  */		      remove_dir_rec (dstfile);		      retval = 1;		    }		  else if (copy_xattr (srcfile, dstfile) != 0)		    {		      remove_dir_rec (dstfile);		      retval = 1;		    }		}	    }	  else if (S_ISLNK(st.st_mode))	    {	      char buffer[4096];	      int len = readlink (srcfile, buffer, sizeof (buffer));	      if (len < 0)		retval = 1;	      else		{		  buffer[len] = '\0';		  if (symlink (buffer, dstfile) != 0)		    {		      fprintf (stderr, _("Cannot create symlink `%s': %s\n"),			       dstfile, strerror (errno));		      retval = 1;		    }		  else if (lchown (dstfile,				   preserve_id ? st.st_uid : uid,				   preserve_id ? st.st_gid : gid) != 0)		    {		      fprintf (stderr,                               _("Cannot change owner/group for `%s': %s\n"),			       dstfile, strerror (errno));		      unlink (dstfile);		      retval = 1;		    }		  else if (copy_xattr (srcfile, dstfile) != 0)		    {		      unlink (dstfile);		      retval = 1;		    }		}	    }	  else  /* Here we should have only regular files.  */	    {	      int src_fd, dst_fd;	      src_fd = open (srcfile, O_RDONLY);	      if (src_fd < 0)		{		  retval = 1;		  continue;		}	      dst_fd = open (dstfile, O_WRONLY|O_CREAT|O_TRUNC, 0);	      if (dst_fd < 0)		{		  close (src_fd);		  retval = 1;		}	      else		{		  char buffer[4096];		  int cnt;		  while ((cnt = read (src_fd, buffer, sizeof (buffer))) > 0)		    {		      if (write (dst_fd, buffer, cnt) != cnt)			{			  fprintf (stderr, _("Cannot copy `%s': %s\n"),				   srcfile, strerror (errno));			  cnt = -1;			  break;			}		    }		  close (src_fd);		  close (dst_fd);		  if (cnt < 0 /* Remove file if copy failed. */ ||		      chown (dstfile,			     preserve_id ? st.st_uid : uid,			     preserve_id ? st.st_gid : gid) != 0 ||		      chmod (dstfile, st.st_mode & 07777))		    {		      fprintf (stderr, _("Cannot change permissions for `%s': %s\n"),			       dstfile, strerror (errno));		      unlink (dstfile);		      retval = 1;		    }		  else if (copy_xattr (srcfile, dstfile) != 0)		    {		      unlink (dstfile);		      retval = 1;		    }		}	    }	}   }  closedir (dir);  return retval;}

⌨️ 快捷键说明

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