📄 mycp.c
字号:
#include<sys/stat.h>
#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h>
#include<dirent.h>
#include<stdio.h>
#include<string.h>
// to judge if a file is a directory or regular files
// return 1, a dir; 0, regular file; -1, error
int isdir(const char * path)
{
struct stat bf;
// read status of the file
if(stat(path, &bf) == -1){
printf("isdir(%s), stat(%s) error!\n",path, path);
return -1;
}
if((S_IFMT & bf.st_mode) == S_IFDIR) {
return 1;
}
else
return 0;
}
// copy a file using open,creat,read and write
// from and to are both absolute path
// return 1, success; 0, error
int cpfile(const char * from, const char * to)
{
int f1, f2, n;
char buf[BUFSIZ];
struct stat old_mode;
// read status of the old file
if(stat(from, &old_mode) == -1){
printf("cpfile(%s, %s), stat(%s) error!\n", from, to, from);
return 0;
}
// open the old file
if( (f1 = open(from, O_RDONLY)) == -1){
printf("cpfile(%s, %s), can't open %s.\n", from, to, from);
return 0;
}
// create new file
if( (f2 = creat(to, old_mode.st_mode)) == -1){
printf("cpfile(%s, %s), can't create %s.\n", from, to, to);
close(f1);
return 0;
}
// int fchmod(int fd, mode_t mode)
if(fchmod(f2, old_mode.st_mode) == -1){
printf("cpfile(%s, %s), fchmod(%s) error!\n", from, to, to);
return 0;
}
// read and write
while((n = read(f1, buf, BUFSIZ)) > 0){
if(write(f2, buf, n) != n){
printf("cpfile(%s, %s), write(%s) error!\n", from, to, to);
close(f1);
close(f2);
return 0;
}
}
close(f1);
close(f2);
return 1;
}
// get file name or directory name
// NAME is stored in name
void getfilename(char * bf, char * name)
{
int i, n, j;
n = strlen(bf);
for(i = n - 1; i >=0 ; i--){
if(bf[i]=='/'){
break;
}
}
for(i++, j = 0; i < n; i++, j++)
name[j] = bf[i];
name[j] = '\0';
}
// copy a directory, including the files and sub-directories, into a directory that exists
void cpdir(const char * from, const char * to)
{
char bffrom[BUFSIZ], bfto[BUFSIZ]; // use to store filepath of the source and destination
char name[BUFSIZ];
int flag;
flag = isdir(from);
strcpy(bffrom, from);
strcpy(bfto, to);
if(flag == 0) // regular file
{
getfilename(bffrom, name); // get file name
strcat(bfto, "/");
strcat(bfto, name);
cpfile(bffrom, bfto);
return;
}
else
if(flag == 1) // directory
{
// make the same dir
getfilename(bffrom, name); // get dir name
strcat(bfto, "/");
strcat(bfto, name);
if(strcmp(name, ".")==0 || strcmp(name, "..")==0 ){ return ; // current and parent! }
struct stat old_mode; // get the old_mode
if(stat(from, &old_mode) == -1){
printf("mkdir(%s), stat(%s) error!\n", bfto, bffrom);
return;
}
mkdir(bfto, old_mode.st_mode); // make dir bfto
chmod(bfto, old_mode.st_mode); // change mode of bfto
// copy the files and subdir in the dir
DIR * pdir;
struct dirent * pdirent;
pdir = opendir(bffrom);
while(1) {
pdirent = readdir(pdir) ;
if(pdirent == NULL)
break;
else{
strcpy(bffrom, from);//key
strcat(bffrom, "/");
strcat(bffrom, pdirent->d_name); // subfile or subdir path
cpdir(bffrom, bfto) ; // nested
}
}
closedir(pdir); return ;
}
else
return ;
}/**some bugs: *the source filepath does not exist;*the destination filepath does not exist, or exists with the same source(care about overwrite);*the commandline with space and without quotation(the same as the two above);*/
int main(int argc, char * argv[])
{
// commandline
if(argc != 3) {
printf("usage: %s from to\nwe should use quotation marks if from or to has a space.\n", argv[0]);
return -1;
}
// call
cpdir(argv[1], argv[2]); //printf("1: %s\n2: %s\n", argv[1] ,argv[2]);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -