直接代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <utime.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#define N 4096
int cp(char dir_s[],char dir_d[])
{
int i,j,n;
DIR *dp;
char stmp[N],dtmp[N];
struct dirent *dir_list; //获得目录下文件列表信息
struct stat file_status; //获取文件信息
if ( (dp = opendir(dir_s)) == NULL){
printf("cp: cannot access %s: No such file or directory\n",dir_s);
return 1;
}
n=0;
while ( (dir_list = readdir(dp)) != NULL){
if(strcmp(dir_list->d_name, ".")==0 || strcmp(dir_list->d_name,"..")==0){
continue;
}
strcpy(stmp,dir_s);
strcat(stmp,dir_list->d_name);
if (lstat(stmp,&file_status) < 0){ //获取文件(目录)属性
printf("Cannot open the directory : %s\n",stmp);
break;
}
printf("%s\n",stmp);
strcpy(dtmp,dir_d);
strcat(dtmp,dir_list->d_name);
if (S_ISDIR(file_status.st_mode)) {
copydir(stmp,dtmp);
}
else if(S_ISLNK(file_status.st_mode)){
copylink(stmp,dtmp);
}
else {
copyfile(stmp,dtmp);
}
}
closedir(dp);
return 0;
}
//P210 复制文件
void copyfile(char dir_s[],char dir_d[]){
int s_file,d_file,j;
char buf[N];
struct stat file_status;
struct utimbuf file_time;
if(lstat(dir_s,&file_status)<0){
printf("Can't get file status\n");
return ;
}
s_file=open(dir_s,O_RDWR);
if (s_file== -1){
printf("open s file error\n");
return ;
}
d_file=creat(dir_d,file_status.st_mode);
if (d_file == -1) {
printf("open d file error\n");
return ;
}
while((j=read(s_file,buf,1024))>0){ //写入文件内容
write(d_file,buf,j);
}
chmod(dir_d,file_status.st_mode);
file_time.actime = file_status.st_atime; //更改时间
file_time.modtime = file_status.st_mtime;
remove()
remove()
utime(dir_d,&file_time);
close(s_file);
close(d_file);
return ;
}
//复制link
void copylink(char dir_s[],char dir_d[]){
char buf[N];
struct stat file_status;
struct utimbuf file_time;
readlink(dir_s,buf,1024); //读取链接文件本身信息 (P209)
symlink(buf,dir_d); //创建符号链接文件
lstat(dir_s,&file_status);
struct timespec filetime[2] = {file_status.st_atim,file_status.st_mtim};
utimensat(AT_FDCWD//当dir_d是绝对路径:忽略
,dir_d,filetime,
AT_SYMLINK_NOFOLLOW);//only itself
}
//复制目录
void copydir(char dir_s[],char dir_d[]){
struct stat file_status; //获取文件信息
struct utimbuf file_time;
if (dir_s[strlen(dir_s)-1] != '/'){
strcat(dir_s,"/");
}
lstat(dir_s,&file_status);
mkdir(dir_d,file_status.st_mode); //创建目录
if (dir_d[strlen(dir_d)-1] != '/'){
strcat(dir_d,"/");
}
cp(dir_s,dir_d);
file_time.actime = file_status.st_atime; //改变时间
file_time.modtime = file_status.st_mtime;
utime(dir_d,&file_time);
}
int main(int argc, char *argv[])
{
char dir_s[N],dir_d[N],temp[N],path[N];
struct stat file_status; //获取文件信息
struct utimbuf file_time;
char *file_name,*ch;
DIR *dp;
if (argc == 3)
{
strcpy(dir_d,argv[2]);
if (dir_d[strlen(dir_d)-1] != '/'){
strcat(dir_d,"/");
strcpy(temp,dir_d); //复制文件路径
}
strcpy(dir_s,argv[1]);
lstat(dir_s,&file_status);//获取文件相关信息
if((dp=opendir(dir_d))==NULL){
mkdir(dir_d,file_status.st_mode);//建立一个目录
}
if (S_ISDIR(file_status.st_mode)) {
if (dir_s[strlen(dir_s)-1] != '/'){
strcat(dir_s,"/");
}
printf("commnd cp %s %s \n",dir_s,dir_d);
cp(dir_s,dir_d); //参数应为绝对路径
}
else {
file_name = strrchr(dir_s,'/');
file_name++;
int i = 0;
for(ch = dir_s;ch<file_name;ch++){
path[i++] =*ch;
}
printf("%s\n",path);
strcat(dir_d,file_name); //改变目标路径
if(S_ISLNK(file_status.st_mode)){
copylink(dir_s,dir_d);
}
else {
copyfile(dir_s,dir_d);
}
lstat(path,&file_status);
}
file_time.actime = file_status.st_atime; //改变时间
file_time.modtime = file_status.st_mtime;
strcpy(dir_d,temp);
utime(dir_d,&file_time);
}
else {
printf("Argument error\n");
}
return 0;
}