/*
*cp.c文件夹复制
*用法:cp [源目录] [目标目录]
*例如:cp /etc/apt /home,如果权限不够,加上sudo
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <dirent.h>
/*
**getname(),用于获取文件夹名字,如/home/sk/test 得到test
*/
char *getname(char *path)
{
char *name = path;
while(*path)
{
if(*(path++) == '/')
name = path;
}
return name;
}
/*
*do_cp(),若都是目录文件,将src里的所有文件复制到dst中,
*若都是普通文件,将src复制到dst
*/
void do_cp(char *src ,char *dst)
{
struct stat st;
DIR *dir;
struct dirent *direntp;
int des_size = strlen(dst);
int source_size = strlen(src);
if (stat(src,&st) == -1)
{
perror(src);
return ;
}
/*如果是目录文件*/
if (S_ISDIR(st.st_mode))
{
if (mkdir(dst, st.st_mode) == -1)
{
perror(dst);
return ;
}
/*打开目录*/
if((dir = opendir(src))==NULL)
{
perror(src);
return;
}
/*遍历目录*/
while((direntp = readdir(dir))!=NULL)
{
if((!strcmp( direntp->d_name,"."))||(!strcmp(direntp->d_name,"..")))
continue;
dst[des_size++] = '/';
src[source_size++] = '/';
strcpy(src+ source_size,direntp->d_name);
strcpy(dst + des_size,direntp->d_name);
do_cp(src,dst); //递归一下
}
dst[--des_size] = 0;
src[--source_size] = 0;
}
/*如果是普通文件*/
else
{
int fdsrc,fddst;
int ret;
/*打开源文件*/
if((fdsrc= open(src,O_RDONLY)) == -1)
{
perror(src);
return;
}
/*创建目标文件*/
if((fddst = creat(dst, O_CREAT|O_WRONLY|O_TRUNC))== -1)
{
perror(dst);
close(fddst);
return;
}
char buf[1024];
int size = 1024;
/*从原始文件read,再write到目标文件*/
while (((ret = read(fdsrc,buf,size)) != -1) && ret)
{
if (write(fddst, buf, ret) == -1)
{
perror("error");
break;
}
}
close(fdsrc);
close(fddst);
/*给予权限*/
chmod(dst, st.st_mode);
}
}
int main(int argc, char* argv[])
{
DIR *dirp;
struct stat st_info;
char dstpath[1024];
char src[512], dst[512];
if(argc != 3) //简单参数判断
{
printf("parameter wrong\n");
return -1;
}
strcpy(src, argv[1]); /*src为源目录*/
strcpy(dst, argv[2]); /*dst为目标目录*/
char* dname = getname(src);
strcpy(dstpath, dst);
strcat(dstpath, "/");
strcat(dstpath, dname);
if( (access(dst, 0 )) == 0 ) /*若dst存在,则将src复制到dst目录下
若不存在,新建dst目录,将src下的
文件复制到dst下*/
{
do_cp(src, dstpath);
}
else do_cp(src, dst);
}