From 90bc173c8c80c4bb3a2932d7e67de73a4b5894b7 Mon Sep 17 00:00:00 2001 From: aixiao Date: Thu, 21 May 2020 19:15:37 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=87=E7=94=A8=E7=B3=BB=E7=BB=9F=E8=B0=83?= =?UTF-8?q?=E7=94=A8cp=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 2 +- cp.c | 115 ------------------------------- cp.h | 30 -------- rm_.c | 204 +++++++++++++++++++++++++++++++++++++++++++++---------- rm_.conf | 1 + rm_.h | 6 +- 6 files changed, 173 insertions(+), 185 deletions(-) delete mode 100644 cp.c delete mode 100644 cp.h create mode 100644 rm_.conf diff --git a/Makefile b/Makefile index 28542e6..b467761 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ CFLAGS += -g -O2 -Wall LIBS = -static OBJ := rm_ -all: rm_.o cp.o +all: rm_.o $(CC) $(CFLAGS) -o $(OBJ) $^ $(LIBS) $(STRIP) $(OBJ) -chmod a+x $(OBJ) diff --git a/cp.c b/cp.c deleted file mode 100644 index 3075546..0000000 --- a/cp.c +++ /dev/null @@ -1,115 +0,0 @@ -#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 deleted file mode 100644 index f95aa28..0000000 --- a/cp.h +++ /dev/null @@ -1,30 +0,0 @@ -#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 index 52f42b6..cd1e543 100644 --- a/rm_.c +++ b/rm_.c @@ -26,57 +26,189 @@ int copyfile(char *old_file, char *new_file) return 0; } +int mkdir_r(const char *path) +{ + if (path == NULL) { + return -1; + } + char *temp = strdup(path); + char *pos = temp; + + /* 去掉开头的 './' 或 '/' */ + if (strncmp(temp, "/", 1) == 0) { + pos += 1; + } else if (strncmp(temp, "./", 2) == 0) { + pos += 2; + } + + /* 循环创建目录 */ + for (; *pos != '\0'; ++pos) { + if (*pos == '/') { + *pos = '\0'; + mkdir(temp, 0755); + //printf("for %s\n", temp); + *pos = '/'; + } + } + + /* 如果最后一级目录不是以'/'结尾, + 遇到'\0'就中止循环, + 不会创建最后一级目录 */ + if (*(pos - 1) != '/') { + //printf("if %s\n", temp); + mkdir(temp, 0755); + } + free(temp); + return 0; +} + +void help_information(void) +{ + puts("\ + RM_\n\ +Secure deletion of files and directories\n\ +Author: aixiao@aixiao.me\n\ +\n\ +Usage: rm_ [optinos] [File] [File]...\n\ + Options:\n\ + -h,-? : print help\n\ + -c file : config file (default: /etc/rm_.conf)\n\ + -t directory : Trash can directory\n\ + \ + "); +} + int main(int argc, char **argv) { + char buffer[1024]; char new_file[CACHE_SIZE]; - bzero(new_file, 0); + char tmp[CACHE_SIZE]; + char config[CACHE_SIZE]; + char directory[CACHE_SIZE]; + int opt, i; + char *p, *p1; + FILE *fp; + memset(directory, 0, CACHE_SIZE); + memset(config, 0, CACHE_SIZE); + strcpy(config, "/etc/rm_.conf"); + char optstring[] = "c:t:h?"; + while (-1 != (opt = getopt(argc, argv, optstring))) { + switch (opt) { + case 'c': + strcpy(config, optarg); + break; + case 't': + strcpy(directory, optarg); + break; + case 'h': + case '?': + help_information(); + exit(0); + break; + } + + } + + // 配置文件读取 + memset(buffer, 0, CACHE_SIZE); + memset(new_file, 0, CACHE_SIZE); + memset(tmp, 0, CACHE_SIZE); + fp = fopen(config, "r"); + if (fp == NULL) { + printf("读取配置文件错误!\n"); + exit(1); + } + fread(buffer, sizeof(buffer), 1, fp); + fclose(fp); + p = strchr(buffer, '\n'); + if (p) { + buffer[strlen(buffer) - 1] = 0; + } else { + printf("配置文件读取错误!\n"); + exit(1); + } + if ((p = strchr(buffer, '\n'))) { + printf("配置文件读取错误!\n"); + exit(1); + } + if (directory != NULL) { + if (strlen(directory) == 0) { + ; + } else { + memset(buffer, 0, strlen(buffer)); + strcpy(buffer, directory); + } + } + + if (buffer[strlen(buffer)-1] != '/') { + printf("垃圾桶目录格式错误!\n"); + exit(1); + } + + // 检测root用户 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); + + // 创建目录 + if (!access(buffer, 0)) { + //printf("%s 垃圾桶目录存在\n", buffer); + ; } else { - printf("%s 创建垃圾桶目录\n", DELETE); - if ((mkdir(DELETE, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) == - 0) { - printf("%s 创建垃圾桶成功\n", DELETE); - } + printf("%s 创建垃圾桶目录\n", buffer); + mkdir_r(buffer); } - 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 (i = optind; i < argc; i++) { + strcpy(new_file, buffer); - } - - for (int i = 1; i < argc; i++) { - if (remove(argv[i]) == 0) { - printf("%s 删除成功\n", argv[i]); + // 假如 argv[i] 为 "../a/" 就取 a + // 假如 argv[i] 为 "../a" 就取 a + // 假如 argv[i] 为 "../a/b" 就取 b + // 假如 argv[i] 为 "../a/b/" 就取 b + // 假如 argv[i] 为 "a" 就取 a + // 假如 argv[i] 为 "a/" 就取 a + p = strrchr(argv[i], '/'); + if (p != NULL) { + if (argv[i][strlen(argv[i]) - 1] == '/') { + memcpy(tmp, argv[i], strlen(argv[i]) - 1); + p = strrchr(tmp, '/'); + p1 = strchr(tmp, '/'); + if (p1 != NULL) { + p = strrchr(tmp, '/'); + p = p + 1; + } else + p = tmp; + } else { + p = p + 1; + } } else { - printf("%s 删除失败\n", argv[i]); + p = argv[i]; } + + strcat(new_file, p); + printf("移动到 %s\n", new_file); + + if(fork() == 0) { + if (execlp("cp", "cp", "-rf", argv[i], new_file, (char *)0) == -1) + printf("execlp pwd error"); + } + wait(NULL); + + } + + // 删除文件 + for (i = optind; i < argc; i++) { + if(fork() == 0) { + if (execlp("rm", "rm", "-rf", argv[i], (char *)0) == -1) + printf("execlp pwd error"); + } + wait(NULL); } return 0; } + diff --git a/rm_.conf b/rm_.conf new file mode 100644 index 0000000..1c50dd5 --- /dev/null +++ b/rm_.conf @@ -0,0 +1 @@ +/data/delete/ diff --git a/rm_.h b/rm_.h index 114df30..32e0d2a 100644 --- a/rm_.h +++ b/rm_.h @@ -3,13 +3,13 @@ #include #include +#include #include #include #include +#include +#include -#define DELETE "/delete/" #define CACHE_SIZE 270 -#include "cp.h" - #endif