采用系统调用cp命令
This commit is contained in:
parent
95c86c087f
commit
90bc173c8c
2
Makefile
2
Makefile
@ -5,7 +5,7 @@ CFLAGS += -g -O2 -Wall
|
|||||||
LIBS = -static
|
LIBS = -static
|
||||||
OBJ := rm_
|
OBJ := rm_
|
||||||
|
|
||||||
all: rm_.o cp.o
|
all: rm_.o
|
||||||
$(CC) $(CFLAGS) -o $(OBJ) $^ $(LIBS)
|
$(CC) $(CFLAGS) -o $(OBJ) $^ $(LIBS)
|
||||||
$(STRIP) $(OBJ)
|
$(STRIP) $(OBJ)
|
||||||
-chmod a+x $(OBJ)
|
-chmod a+x $(OBJ)
|
||||||
|
115
cp.c
115
cp.c
@ -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);
|
|
||||||
}
|
|
30
cp.h
30
cp.h
@ -1,30 +0,0 @@
|
|||||||
#ifndef CP_H
|
|
||||||
#define CP_H
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <linux/limits.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#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
|
|
184
rm_.c
184
rm_.c
@ -26,57 +26,189 @@ int copyfile(char *old_file, char *new_file)
|
|||||||
return 0;
|
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)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
char buffer[1024];
|
||||||
char new_file[CACHE_SIZE];
|
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) {
|
if ((getuid()) != 0) {
|
||||||
printf("Root用户运行?\n");
|
printf("Root用户运行?\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc == 1) {
|
// 创建目录
|
||||||
printf("%s file1 file2 file3 ...\n", argv[0]);
|
if (!access(buffer, 0)) {
|
||||||
return -1;
|
//printf("%s 垃圾桶目录存在\n", buffer);
|
||||||
}
|
;
|
||||||
|
|
||||||
if (!access(DELETE, 0)) {
|
|
||||||
printf("%s 垃圾桶目录存在\n", DELETE);
|
|
||||||
} else {
|
} else {
|
||||||
printf("%s 创建垃圾桶目录\n", DELETE);
|
printf("%s 创建垃圾桶目录\n", buffer);
|
||||||
if ((mkdir(DELETE, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) ==
|
mkdir_r(buffer);
|
||||||
0) {
|
|
||||||
printf("%s 创建垃圾桶成功\n", DELETE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 1; i < argc; i++) {
|
// 备份文件
|
||||||
bzero(new_file, 0);
|
for (i = optind; i < argc; i++) {
|
||||||
strcpy(new_file, DELETE);
|
strcpy(new_file, buffer);
|
||||||
|
|
||||||
char *p; // 去除./ ../ ../../ ...
|
// 假如 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], '/');
|
p = strrchr(argv[i], '/');
|
||||||
if (p != NULL)
|
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;
|
p = p + 1;
|
||||||
else {
|
} else
|
||||||
|
p = tmp;
|
||||||
|
} else {
|
||||||
|
p = p + 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
p = argv[i];
|
p = argv[i];
|
||||||
}
|
}
|
||||||
strcat(new_file, p);
|
|
||||||
|
|
||||||
|
strcat(new_file, p);
|
||||||
printf("移动到 %s\n", new_file);
|
printf("移动到 %s\n", new_file);
|
||||||
|
|
||||||
cp(argv[i], new_file);
|
if(fork() == 0) {
|
||||||
|
if (execlp("cp", "cp", "-rf", argv[i], new_file, (char *)0) == -1)
|
||||||
|
printf("execlp pwd error");
|
||||||
|
}
|
||||||
|
wait(NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 1; i < argc; i++) {
|
// 删除文件
|
||||||
if (remove(argv[i]) == 0) {
|
for (i = optind; i < argc; i++) {
|
||||||
printf("%s 删除成功\n", argv[i]);
|
if(fork() == 0) {
|
||||||
} else {
|
if (execlp("rm", "rm", "-rf", argv[i], (char *)0) == -1)
|
||||||
printf("%s 删除失败\n", argv[i]);
|
printf("execlp pwd error");
|
||||||
}
|
}
|
||||||
|
wait(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
rm_.h
6
rm_.h
@ -3,13 +3,13 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#define DELETE "/delete/"
|
|
||||||
#define CACHE_SIZE 270
|
#define CACHE_SIZE 270
|
||||||
|
|
||||||
#include "cp.h"
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user