cp用于复制文件之类的操作
用法:cp [参数] file newfile (把file复制到newfile)
或:cp [参数] file1 file2 file3 ... dirname(把文件file1 file2 file ...复制到dirname目录下)
参数:
-a :相当于 -pdr 。
-d :若来源文件为连结文件的属性(link file),则复制该链接文件,而不是该链接文件所链接的文件。
-f :为强制 (force) 的意思,若有重复或其它疑问时,不会询问,直接复制。(一般alias cp='cp -i'时,使用)
-i :若目的文件已经存在时,在覆盖时会先询问。(覆盖不复制文件权限,只复制内容)
-l :复制硬链接文件,而不是硬链接文件所链接的内容(这个有点意思,大概就是,复制一个强连接文件,而不是把强连接文件的内容复制一遍,如果软链接是指针的话,强连接就是引用,-d 就是复制一个指针,-l 就是复制一个别名引用,不加的话,就是复制它们所指向的内容。可以百度linux文件系统,inode)
-p :连同文件的属性一起复制过去,而非使用预设属性。(这里的属性单指0744权限属性,还有atime最后读时间 ctime最后状态改变时间 mtime最后写时间 之类的一些属性 man cp原话是:-p same as --preserve=mode,ownership,timestamps)
-r :递归持续复制,用于目录的复制行为;
-s :复制成为软链接文件(symbolic link)。
-u:源文件比目的文件更新时,拷贝执行。
---------------------------------------------------------------------------------------------------------------------------------------------------------------
目前要实现的:
基本用法 -i ;
---------------------------------------------------------------------------------------------------------------------------------------------------------------
思路:
最基本思路无非就是读源文件,写目的文件。
实现读写需要read() write()之类的函数
实现同等权限需要stat(),fstat(),lstat()之类的函数
大概就是,通过main(int ac,char *av[]) 中的ac与*av获得源文件地址,然后打开该文件,读取该文件权限,通过读取到的目的文件的地址,建立目的文件,写入,关闭文件,完成。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
附上代码:
/*2015.5.9
*cp01.c
*
*/
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
#define BUFFERSIZE 4096
#define MODE 00744
static int flag_i;
int main(int ac ,char *av[])
{
int i=0,j=0,k=0,fnum=0;
fnum=flag(ac,av);
if(fnum<2) {
fprintf(stderr,"miss file operand\n");
return -1;
}
char avv[fnum][128];
for(i=1;i<ac;i++)
{
if(av[i][0] != '-'){
strcpy(avv[k++],av[i]);
if(avv[k-1][strlen(avv[k-1])-1]=='/') avv[k-1][strlen(avv[k-1])-1]='\0';
if(k<fnum&&(f_exist(avv[k-1])!=1)) {
fprintf(stderr,"%s is not filename\n",av[i]);
return -2;
}
/* else if(k>2&&(f_exist(avv[k-1]))!=2){
fprintf(stderr,"%s is not dirname\n");
return -3;
}*/
}
}
int tp=f_exist(avv[fnum-1]);
if(tp == 0){
if(fnum>2) {
fprintf(stderr,"%s is not dirname\n",avv[fnum-1]);
return -4;
}
file_create(avv[0],avv[1]);
file_to_file(avv[0],avv[1]);
}
else if(tp == 1){
if(fnum>2){
fprintf(stderr,"%s is not dirname\n",avv[fnum-1]);
return -4;
}
if(flag_i){
file_to_file(avv[0],avv[1]);
}
else {} //do nothing
}
else if(tp == 2){
for(i=0;i<fnum-1;i++)
{
char *filename=avv[i],j=0,nfile[128];
int len=strlen(avv[i]);
/*--------------------*/
while(j<len) // qu chu '/'
if(avv[i][j++]=='/') filename = &avv[i][j-1];
strcpy(nfile,avv[fnum-1]);
len =strlen(nfile);
nfile[len]='/';
nfile[len+1]='\0';
strcat(nfile,filename);
/*create legal path*/
if(f_exist(nfile)==0){
file_create(avv[i],nfile);
file_to_file(avv[i],nfile);
}
else if(f_exist(nfile)==1){ if(flag_i) file_to_file(avv[i],nfile);
}
}
}
return 0;
}
int file_create(char *patha,char *pathb)//创建新文件pathb,权限为patha的权限信息
{
struct stat sta;
int fdb;
if(stat(patha,&sta) == -1 ){
open(pathb,O_CREAT,MODE);
return -1;
}
if(open(pathb,O_CREAT,sta.st_mode) == -1)
{
fprintf(stderr,"cp error\n");
return -1;
}
return 0;
}
int flag(int ac,char *av[])//记录输入的选项-[]
{
int flag_i=0,fnum=0;
while(--ac){
if(av[ac][0] == '-')
{
int i;
for(i=1;i<strlen(av[ac]);i++)
if(av[ac][i] == 'i') flag_i=1;
}
else fnum++;
}
return fnum;
}
int f_exist(char *path)//判断文件类型
{
struct stat st;
int re;
re = stat(path,&st);
if(re == -1) {
return 0; //not exist
}
if((st.st_mode&S_IFDIR) == S_IFDIR)
return 2; //dir_file
return 1; //regular_file
}
int file_to_file(char *patha,char *pathb) //patha exist && pathb exist
{
int fda,fdb;
char BUF[BUFFERSIZE];
fda=open(patha,O_RDONLY);
if(fda == -1){
perror(patha);
return -1;
}
fdb=open(pathb,O_WRONLY);
if(fdb == -1){
perror(pathb);
return -2;
}
ssize_t r_len,w_len;
while((r_len=read(fda,BUF,BUFFERSIZE))!=0)
{
if(r_len == -1){
perror(patha);
return -3;
}
w_len=write(fdb,BUF,strlen(BUF));
if(w_len != strlen(BUF)){
perror(pathb);
return -4;
}
}
close(fda);
close(fdb);
return 1;
}