micro-utils/coreutils/shred.c

111 lines
2.0 KiB
C
Raw Normal View History

2023-10-15 11:29:56 +03:00
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
2023-10-15 11:58:12 +03:00
#include <sys/mman.h>
2023-10-15 11:29:56 +03:00
#include <sys/stat.h>
#define RAND_SOURCE "/dev/urandom"
unsigned int f_flag;
unsigned int u_flag;
unsigned int z_flag;
unsigned int n_loops;
2023-10-15 11:58:12 +03:00
int shred(int rand_fd, int fd) {
/* Get size */
2023-10-15 11:29:56 +03:00
off_t size = lseek(fd, 0, SEEK_END);
2023-10-15 11:58:12 +03:00
if (size <= 0)
2023-10-15 11:29:56 +03:00
return 1;
2023-10-15 11:58:12 +03:00
void *buf = mmap(NULL, size, PROT_WRITE, MAP_SHARED, fd, 0);
if (buf == MAP_FAILED) {
fprintf(stderr, "shred: mmap: %s\n", strerror(errno));
return 1;
}
2023-10-15 11:29:56 +03:00
2023-10-15 11:58:12 +03:00
for (unsigned int n = 0; n < n_loops; n++) {
read(rand_fd, buf, size);
fsync(fd);
}
2023-10-15 11:29:56 +03:00
2023-10-15 11:58:12 +03:00
if (z_flag)
memset(buf, 0, size);
2023-10-15 11:29:56 +03:00
2023-10-15 11:58:12 +03:00
if (munmap(buf, size)) {
fprintf(stderr, "shred: munmap: %s\n", strerror(errno));
return 1;
2023-10-15 11:29:56 +03:00
}
return 0;
}
2023-11-07 16:56:14 +03:00
int main(int argc, char **argv) {
2023-10-15 11:29:56 +03:00
n_loops = 3;
2023-11-07 16:56:14 +03:00
int opt;
while ((opt = getopt(argc, argv, "fuzn:")) != -1) {
switch (opt) {
case 'f':
f_flag = 1;
break;
2023-10-15 11:29:56 +03:00
2023-11-07 16:56:14 +03:00
case 'u':
u_flag = 1;
break;
2023-10-15 11:29:56 +03:00
2023-11-07 16:56:14 +03:00
case 'z':
z_flag = 1;
break;
2023-10-15 11:29:56 +03:00
2023-11-07 16:56:14 +03:00
case 'n':
n_loops = atoi(optarg);
break;
2023-10-15 11:29:56 +03:00
2023-11-07 16:56:14 +03:00
default:
printf("shred [file1 file2...]\n\t[-n N Overwrite N times, default 3]\n\t[-z Final overwrite with zeros]\n\t[-u Remove file] [-f Chmod to ensure writability]\n");
return 0;
2023-10-15 11:29:56 +03:00
}
}
2023-11-07 16:56:14 +03:00
argv += optind;
argc -= optind;
if (argc == 0) {
fprintf(stderr, "shred: missing operand\n");
return 1;
}
2023-10-15 11:29:56 +03:00
int rand_fd = open(RAND_SOURCE, O_RDONLY);
if (rand_fd < 0) {
2023-11-07 16:56:14 +03:00
fprintf(stderr, "shred: %s: %s\n", RAND_SOURCE, strerror(errno));
2023-10-15 11:29:56 +03:00
return 1;
}
2023-11-07 16:56:14 +03:00
for (int i = 0; i < argc; i++) {
2023-10-15 11:58:12 +03:00
int fd = open(argv[i], O_RDWR);
2023-10-15 11:29:56 +03:00
if (fd < 0) {
fprintf(stderr, "shred: %s is %s\n", argv[i], strerror(errno));
continue;
2023-10-15 11:29:56 +03:00
}
2023-10-15 11:58:12 +03:00
shred(rand_fd, fd);
2023-11-06 13:41:52 +03:00
fsync(fd);
2023-10-15 11:29:56 +03:00
close(fd);
2023-11-07 16:56:14 +03:00
if (f_flag) {
if (chmod(argv[i], 0) < 0)
2023-10-15 11:29:56 +03:00
fprintf(stderr, "shred: %s is %s\n", argv[i], strerror(errno));
2023-11-07 16:56:14 +03:00
}
2023-10-15 11:29:56 +03:00
2023-11-07 16:56:14 +03:00
if (u_flag) {
if (unlink(argv[i]) < 0)
2023-10-15 11:29:56 +03:00
fprintf(stderr, "shred: %s is %s\n", argv[i], strerror(errno));
2023-11-07 16:56:14 +03:00
}
2023-10-15 11:29:56 +03:00
}
close(rand_fd);
return 0;
}