#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;
}