#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <string.h> #include <dirent.h>
char *create_new_name_str(char *src_path, char *dst_path, char *buf) { if(src_path == NULL || dst_path == NULL || buf == NULL) { printf("Error: empty pointer detected!\n"); exit(1); }
strcpy(buf, dst_path); int dst_len = strlen(buf); if(buf[dst_len-1] != '/') { buf[dst_len] = '/'; buf[dst_len+1] = '\0'; }
int src_len = strlen(src_path); char *src = src_path + src_len;
while(*src != '/' && src > src_path) { src--; }
strcat(buf, src + 1); return buf; }
int copy_dir(char *src_path, char *dst_path) { DIR *dir = NULL; if((dir = opendir(src_path)) == NULL) { printf("Error: %s\n", strerror(errno)); return -1; } struct dirent *dir_attr = NULL; struct stat dir_stat = {0}; char new_src_path[256] = {0}; char new_dst_path[256] = {0}; strcpy(new_src_path, src_path); strcpy(new_dst_path, dst_path);
int src_len = strlen(src_path); int dst_len = strlen(dst_path); if(new_src_path[src_len-1] != '/') { strcat(new_src_path, "/"); } if(new_dst_path[dst_len-1] != '/') { strcat(new_dst_path, "/"); }
char src_tmp[256] = {0}; char dst_tmp[256] = {0}; strcpy(src_tmp, new_src_path); strcpy(dst_tmp, new_dst_path); while((dir_attr = readdir(dir)) != NULL) { strcpy(new_src_path, src_tmp); strcat(new_src_path, dir_attr->d_name); strcpy(new_dst_path, dst_tmp); strcat(new_dst_path, dir_attr->d_name);
if(stat(new_src_path, &dir_stat) !=0) { printf("Error: %s\n", strerror(errno)); return -1; } if(S_ISDIR(dir_stat.st_mode)) { if(strcmp(dir_attr->d_name, ".") != 0 && strcmp(dir_attr->d_name, "..") != 0) { if(mkdir(new_dst_path, 0755) != 0) { printf("mkdir error: %s\n", strerror(errno)); return -1; } copy_dir(new_src_path, new_dst_path); printf("new_dst_path = %s\n", new_dst_path); } continue; } else if(S_ISREG(dir_stat.st_mode)) { printf("new_dst_path1 = %s\n", new_dst_path); if(copy_signal_file(new_src_path, new_dst_path) == -1) { return -1; } } else { printf("unregernized file type!\n"); return -1; } } }
int copy_signal_file(char *src_path, char *dst_path) { printf("src = %s\ndst = %s\n", src_path, dst_path); int fd_src, fd_dst; if((fd_src = open(src_path, O_RDONLY)) == -1) { printf("%s: %s\n", src_path, strerror(errno)); return -1; } if((fd_dst = open(dst_path, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) { printf("%s: %s\n", dst_path, strerror(errno)); return -1; }
ssize_t rd_bytes, wr_bytes; char buf[1024] = { 0 }; while((rd_bytes = read(fd_src, buf, 1024)) != 0) { if((wr_bytes = write(fd_dst, buf, rd_bytes)) != rd_bytes) { printf("in func copy: write error\n"); close(fd_src); close(fd_dst); return -1; } } close(fd_src); close(fd_dst); return 0;
}
int copy(char *src_path, char *dst_path) { if(src_path == NULL || dst_path == NULL) { printf("in func copy: empty pointer detected!\n"); return -1; }
int src_exist, dst_exist; struct stat src_stat = {0}; struct stat dst_stat = {0}; char *src_name = NULL; char *dst_name = NULL;
src_exist = access(src_path, F_OK); dst_exist = access(dst_path, F_OK); if(src_exist == -1) { printf("Error: %s: %s\n", src_path, strerror(errno)); return -1; } if(stat(src_path, &src_stat) == -1) { printf("Error: %s\n", strerror(errno)); return -1; }
if(dst_exist == 0) { if(stat(dst_path, &dst_stat) == -1) { printf("Error: %s\n", strerror(errno)); return -1; }
/*src and dst are both exist,and they are all reg*/ if(S_ISREG(src_stat.st_mode) && S_ISREG(dst_stat.st_mode)) { src_name = src_path; dst_name = dst_path; printf("file %s already exist! repalce it?(y/n)\n"); char c = getchar(); int u = 0; while(c != 'y' && c != 'n') { printf("type 'y' or 'n'! %d\n", ++u); c = getchar(); } if(c == 'n') { return -1; } if(copy_signal_file(src_name, dst_name) == -1) { return -1; } }
/*both src and dst exist, src is reg while dst is dir*/ if(S_ISREG(src_stat.st_mode) && S_ISDIR(dst_stat.st_mode)) { src_name = src_path; char buf[256] = {0}; create_new_name_str(src_path, dst_path, buf); dst_name = buf; if(copy_signal_file(src_name, dst_name) == -1) { return -1; } } /*both src and dst exist, src is dir while dst is reg*/ if(S_ISDIR(src_stat.st_mode) && S_ISREG(dst_stat.st_mode)) { printf("Error: src is dir while dst is reg!\n"); return -1; } /*both src and dst exist, they both are dir*/ if(S_ISDIR(src_stat.st_mode) && S_ISDIR(dst_stat.st_mode)) { if(copy_dir(src_path, dst_path) == -1) { return -1; } } } else { /*dst does not exist*/ int dst_len = strlen(dst_path); /*dst does not exist, but it`s a reg*/ if(dst_path[dst_len-1] != '/') { int off_set = 0; char *tmp = dst_path + dst_len; while(*(tmp--) != '/' && off_set <= dst_len) { off_set++; } if(off_set > dst_len) { src_name = src_path; dst_name = dst_path; if(copy_signal_file(src_name, dst_name) == -1) { return -1; } } else { char new_buf[256] = { 0 }; strncpy(new_buf, dst_path, dst_len-off_set); printf("new_buf = %s\n", new_buf); if(access(new_buf, F_OK) != 0) { printf("Error: %s: No such file or directory\n", src_path); return -1; } else { src_name = src_path; dst_name = dst_path; if(copy_signal_file(src_name, dst_name) == -1) { return -1; } } } } /*dst does not exist,and it`s a dir*/ else { printf("Error: %s: No such file or directory\n", src_path); } } return 0; }
int main(int argc, char **argv) { copy(argv[1], argv[2]); return 0; }
|