#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#include<dirent.h>
#define ARGS_CHECK(argc,num){if(argc!=num){fprintf(stderr,"argc error!\n");return -1;}}
#define ERROR_CHECK(ret,errnum,msg){if(ret==errnum){perror(msg);return -1;}}
int cpFile(char *old_path,char *new_path){
int fd_read = open(old_path, O_RDONLY); //1、按正确的权限打开文件
ERROR_CHECK(fd_read, -1, "open");
int fd_write = open(new_path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
ERROR_CHECK(fd_write, -1, "open");
char buf[4096] = { '\0' }; //2、创建缓冲区buf
while (1) {
memset(buf, '\0', sizeof(buf)); //3、循环重置buf后read读取和write写入
int ret = read(fd_read, buf, sizeof(buf));
if (ret == 0) { //4、read返回值为0后结束循环
break;
}
write(fd_write, buf, sizeof(buf));
}
printf("Copied %s.\n",new_path); //test
close(fd_read);
close(fd_write);
return 0;
}
int createDir(char *old_path,char *new_path_back,char *dir_name){ //创建目录
printf("chdir is %s.\n",new_path_back); //test
printf("mkdir %s.\n",dir_name); //test
strcat(new_path_back,dir_name);
mkdir(new_path_back,0777);
}
int DFScp(char *old_path,char *new_path){
DIR *pd_old = opendir(old_path); //1、打开目录文件
ERROR_CHECK(pd_old,NULL,"opendir");
DIR *pd_new = opendir(new_path);
ERROR_CHECK(pd_new,NULL,"opendir");
struct dirent *pdirent; //2、用dirent作循环的容器,存储目录节点的信息
while((pdirent = readdir(pd_old))){
if(!strcmp(pdirent->d_name,".") || !strcmp(pdirent->d_name,"..")){ //3、跳过.和.. ,输出目录文件名
continue;
}
char p_new[512] = { 0 };
char p_new_back[512] = { 0 };
strcat(p_new,new_path); //拼接复制到的路径
strcat(p_new,"/");
strcpy(p_new_back,p_new);
strcat(p_new,pdirent->d_name);
char p_old[512] = { 0 }; //拼接被复制的路径
strcat(p_old,old_path);
strcat(p_old,"/");
strcat(p_old,pdirent->d_name);
if(pdirent->d_type == DT_REG){ //是文件,则复制文件
cpFile(p_old,p_new);
}
else if(pdirent->d_type == DT_DIR){ //是空目录,则创建缺少的目录,再传入新的路径,递归调用cp -r
createDir(p_old,p_new_back,pdirent->d_name);
printf("Into Next:%s\n",p_new); //test
DFScp(p_old,p_new);
}
}
return 0;
}
int main(int argc,char *argv[]){
ARGS_CHECK(argc,3);
DFScp(argv[1],argv[2]);
return 0;
}