CP命令的较完整的实现

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

void cp_file(const char *src,const char *dest,mode_t mode)
{
	char buf[1024] = {0};
	int n;
	
	int fd1 = open(src,O_RDONLY);
	int fd2 = open(dest,mode);
	while(n = read(fd1,buf,sizeof(buf)))
		write(fd2,buf,n);
}
void cp_dir(const char *src,const char *dest)
{
	DIR *dfd = NULL;
	if((dfd = opendir(src)) == NULL)
	{
		perror("Open dir");
		exit(EXIT_FAILURE);
	}
	struct dirent *dp = NULL;
	while((dp = readdir(dfd))!= NULL)
	{
		if(!strcmp(dp->d_name,".") || !strcmp(dp->d_name,".."))
			continue;
		char *name_src = malloc(strlen(src) +1 + strlen(dp->d_name) + 1);
		sprintf(name_src,"%s/%s\0",src,dp->d_name);
		char *name_dest = malloc(strlen(dest) +1 + strlen(dp->d_name) + 1);
		sprintf(name_dest,"%s/%s\0",dest,dp->d_name);
		struct stat stat_src;
		if(lstat(name_src,&stat_src) == -1)
		{
			perror("name_src");
			exit(EXIT_FAILURE);
		}
		if(S_ISREG(stat_src.st_mode))
		{
			cp_file(name_src,name_dest,stat_src.st_mode);
			free(name_src);
			free(name_dest);
		}
		if(S_ISDIR(stat_src.st_mode))
		{
			if(mkdir(name_dest,stat_src.st_mode) == -1)
			{
				perror("mkdir name_dest");
				exit(EXIT_FAILURE);
			}
			cp_dir(name_src,name_dest);
			free(name_src);
			free(name_dest);
		}
	}
}

int main(int argc,char *argv[])
{
	if(argc != 3)
	{
		fprintf(stderr,"Usage: %s src dest\n",argv[1]);
		exit(EXIT_FAILURE);
	}
	struct stat stat_src;
	if(lstat(argv[1],&stat_src) == -1)
	{
		fprintf(stderr,"can't access\n");
		exit(EXIT_FAILURE);
	}
	if(S_ISREG(stat_src.st_mode))
	{
		struct stat stat_dest;
		if(lstat(argv[2],&stat_dest) == -1)
		{
			if(errno == ENOENT)
			{
				cp_file(argv[1],argv[2],stat_src.st_mode);
			}
			else
			{
				perror("file:stat_dest");
				exit(EXIT_FAILURE);
			}
		}
		if(S_ISREG(stat_dest.st_mode))
		{
			printf("The file has already exist,do you want to overwrite it ?(y/n)\n");
			char c = getchar();
			if(c == 'y' || c== 'Y')
			{
				unlink(argv[2]);
				cp_file(argv[1],argv[2],stat_src.st_mode);
			}
            else if(c == 'n' || c== 'N')
            {
                printf("The dest do not overwrite!\n");
                return 0;
			}
			else
			{
				printf("Enter error!\n");
				exit(EXIT_FAILURE);
			}
		}
        if(S_ISDIR(stat_dest.st_mode))
		{
			char *ptr = malloc(strlen(argv[2]) + 1 + strlen(argv[1]) + 1);
			sprintf(ptr,"%s/%s\0",argv[2],argv[1]);
			cp_file(argv[1],ptr,stat_src.st_mode);
			free(ptr);
		}
        if(S_ISDIR(stat_src.st_mode))
		{
			char *ptr = malloc(strlen(argv[2]) + 1 + strlen(argv[1]) + 1);
            sprintf(ptr,"%s/%s\0",argv[2],argv[1]);
            cp_file(argv[1],ptr,stat_src.st_mode);
			free(ptr);
		}
	}
	else if(S_ISDIR(stat_src.st_mode))
	{
		struct stat stat_dest;
		if(lstat(argv[2],&stat_dest) == -1)
        {
			if(errno == ENOENT)
			{
				if(mkdir(argv[2],stat_src.st_mode) == -1)
				{
					perror("mkdir stat_dest");
                    exit(EXIT_FAILURE);
				}
				cp_file(argv[1],argv[2],stat_src.st_mode);
            }
			else
			{
				perror("dir:stat_dest");
                exit(EXIT_FAILURE);
			}
		}
		if(S_ISREG(stat_dest.st_mode))
        {
            printf("can't copy a file to a directory!\n");
			exit(EXIT_FAILURE);
		}
		if(S_ISDIR(stat_dest.st_mode))
		{
			char *ptr = malloc(strlen(argv[1]) + 1 + strlen(argv[2]) + 1);
			sprintf(ptr,"%s/%s\0",argv[2],argv[1]);
            printf("ptr = %s\n",ptr);
			if(mkdir(ptr,stat_src.st_mode) == -1)
            {
                perror("mkdir ptr");
				exit(EXIT_FAILURE);
			}
            cp_dir(argv[1],ptr);
			free(ptr);
		}
	}
	return 0;
 }
 

你可能感兴趣的:(Linux(ubuntu))