commit 95c86c087f947bc48de804ae8b6103428666fdcb Author: aixiao Date: Fri Dec 6 23:48:38 2019 +0800 初次提交 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..28542e6 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +CROSS_COMPILE ?= +CC := $(CROSS_COMPILE)gcc +STRIP := $(CROSS_COMPILE)strip +CFLAGS += -g -O2 -Wall +LIBS = -static +OBJ := rm_ + +all: rm_.o cp.o + $(CC) $(CFLAGS) -o $(OBJ) $^ $(LIBS) + $(STRIP) $(OBJ) + -chmod a+x $(OBJ) +.c.o: + $(CC) $(CFLAGS) -c $< $(LIBS) + +clean: + rm -rf *.o + rm $(OBJ) diff --git a/README.md b/README.md new file mode 100644 index 0000000..cb01c6a --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# rm_ + Linux代替rm命令防止错误删除文件 + +# Build + git clone https://github.com/niuyuling/rm_.git + cd rm_ + make clean; make + +# Help Information + root@niuyuling:/mnt/c/Users/niuyuling/Desktop/rm# touch a.txt b.txt ../c.txt + root@niuyuling:/mnt/c/Users/niuyuling/Desktop/rm# ./rm_ a.txt b.txt ../c.txt + /delete/ 垃圾桶目录存在 + 移动到 /delete/a.txt + 移动到 /delete/b.txt + 移动到 /delete/c.txt + a.txt 删除成功 + b.txt 删除成功 + ../c.txt 删除成功 + root@niuyuling:/mnt/c/Users/niuyuling/Desktop/rm# \ No newline at end of file diff --git a/cp.c b/cp.c new file mode 100644 index 0000000..3075546 --- /dev/null +++ b/cp.c @@ -0,0 +1,115 @@ +#include "cp.h" + +uint32_t dst_mode = O_RDWR | O_CREAT; +uint32_t arg = 0; + +void cp_real(int fd, const char *src, const char *dst) +{ + if ((arg & PARAM_L)) { + if (arg & PARAM_V) + printf("link %s -> %s\n", src, dst); + link(src, dst); + } else if ((arg & PARAM_S)) { + if (arg & PARAM_V) + printf("symlink %s -> %s\n", src, dst); + symlink(src, dst); + } else { + if (arg & PARAM_V) + printf("copydata %s -> %s\n", src, dst); + struct stat src_statbuf; + fstat(fd, &src_statbuf); + int dstfd = open(dst, dst_mode, 0644); + struct stat dst_statbuf; + fstat(dstfd, &dst_statbuf); + if (!dst_statbuf.st_size) + ftruncate(dstfd, src_statbuf.st_size); + char buf[100]; + int size; + while ((size = read(fd, buf, sizeof(buf))) > 0) + write(dstfd, buf, size); + } +} + +char buf1[512]; +char buf2[512]; + +void cp(const char *src, const char *dst) +{ + arg |= PARAM_R; + dst_mode |= O_TRUNC; + arg |= PARAM_F; + int srcfd = open(src, O_RDONLY); + if (srcfd < 0) { + MY_ERR("source file not exist"); + return; + } + struct stat src_statbuf; + fstat(srcfd, &src_statbuf); + int dstfd = open(dst, O_RDONLY); + struct stat dst_statbuf; + if (dstfd > 0) + fstat(dstfd, &dst_statbuf); + if (dstfd > 0 && !S_ISDIR(dst_statbuf.st_mode) && !(arg & PARAM_F)) { + MY_ERR("dest file is exist"); + goto exit; + } + if (S_ISDIR(src_statbuf.st_mode)) { + if (arg & PARAM_V) + printf("process directory %s\n", src); + if (!(arg & PARAM_R)) { + MY_ERR("source file is directory"); + goto exit; + } + mkdir(dst, 0775); + + DIR *pDir; + struct dirent *ent; + pDir = opendir(src); + while ((ent = readdir(pDir)) != NULL) { + if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) + continue; + strcpy(buf1, src); + strcat(buf1, "/"); + strcat(buf1, ent->d_name); + strcpy(buf2, dst); + strcat(buf2, "/"); + strcat(buf2, ent->d_name); + cp(buf1, buf2); + } + } else { + if (dstfd > 0 && S_ISDIR(dst_statbuf.st_mode)) { + if (arg & PARAM_V) + printf("process directory %s\n", dst); + strcpy(buf1, dst); + strcat(buf1, "/"); + get_name(buf2, src); + strcat(buf1, buf2); + cp(src, buf1); + } else { + cp_real(srcfd, src, dst); + } + } +exit: + close(srcfd); + close(dstfd); +} + +void get_name(char *name, const char *pathname) +{ + if (pathname == NULL) + return; + size_t i = strlen(pathname); + int j; + for (j = i - 1; j >= 0; --j) + if (pathname[j] == '/') + break; + strcpy(name, pathname + j + 1); + name[i - j - 1] = '\0'; +} + +void my_err(const char *err_string, int line) +{ + //fprintf(stderr, "line: %d ", line); + perror(err_string); + exit(1); +} diff --git a/cp.h b/cp.h new file mode 100644 index 0000000..f95aa28 --- /dev/null +++ b/cp.h @@ -0,0 +1,30 @@ +#ifndef CP_H +#define CP_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PARAM_NONE 0 +#define PARAM_F 1 +#define PARAM_R 2 +#define PARAM_L 4 +#define PARAM_S 8 +#define PARAM_V 16 + +#define MY_ERR(x) my_err(x,__LINE__) + +void my_err(const char *err_string, int line); +void cp(const char *src, const char *dst); +void get_name(char *name, const char *pathname); +void cp_real(int fd, const char *src, const char *dst); + +#endif diff --git a/rm_.c b/rm_.c new file mode 100644 index 0000000..52f42b6 --- /dev/null +++ b/rm_.c @@ -0,0 +1,82 @@ +#include "rm_.h" + +int copyfile(char *old_file, char *new_file) +{ + FILE *fp1 = NULL; //指向源文件 + FILE *fp2 = NULL; //指向目的文件 + char buffer[1024] = { 0 }; //缓存 + int n = 0; //文件大小 + + if ((old_file == NULL) || (new_file == NULL)) { + return -1; + } + + if ((fp1 = fopen(old_file, "r")) != NULL) { + if ((fp2 = fopen(new_file, "w")) != NULL) { + while ((n = fread(buffer, 1, sizeof(buffer), fp1)) > 0) { + fwrite(buffer, n, 1, fp2); + memset(buffer, 0, sizeof(buffer)); + } + fclose(fp1); + fclose(fp2); + return 1; + } + } + + return 0; +} + +int main(int argc, char **argv) +{ + char new_file[CACHE_SIZE]; + bzero(new_file, 0); + + if ((getuid()) != 0) { + printf("Root用户运行?\n"); + return -1; + } + + if (argc == 1) { + printf("%s file1 file2 file3 ...\n", argv[0]); + return -1; + } + + if (!access(DELETE, 0)) { + printf("%s 垃圾桶目录存在\n", DELETE); + } else { + printf("%s 创建垃圾桶目录\n", DELETE); + if ((mkdir(DELETE, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) == + 0) { + printf("%s 创建垃圾桶成功\n", DELETE); + } + } + + for (int i = 1; i < argc; i++) { + bzero(new_file, 0); + strcpy(new_file, DELETE); + + char *p; // 去除./ ../ ../../ ... + p=strrchr(argv[i],'/'); + if (p != NULL) + p=p+1; + else { + p=argv[i]; + } + strcat(new_file, p); + + printf("移动到 %s\n", new_file); + + cp(argv[i], new_file); + + } + + for (int i = 1; i < argc; i++) { + if (remove(argv[i]) == 0) { + printf("%s 删除成功\n", argv[i]); + } else { + printf("%s 删除失败\n", argv[i]); + } + } + + return 0; +} diff --git a/rm_.h b/rm_.h new file mode 100644 index 0000000..114df30 --- /dev/null +++ b/rm_.h @@ -0,0 +1,15 @@ +#ifndef RM_H +#define RM_H + +#include +#include +#include +#include +#include + +#define DELETE "/delete/" +#define CACHE_SIZE 270 + +#include "cp.h" + +#endif